Windowsの下でredisが頻繁にgetとsetの同じ値で発生する問題について

4066 ワード

最近は用事が多く、「redis読み書き分離下の高可用性設計と実現」の実現部分を更新していない.これまでの実現が高可用性に達していなかった理由のほかに、もう一つの重要な原因がある.私が引き継いだ別のプロジェクトでredisが頻繁にgetとsetが同じ値になったとき、一致しない状況が発生した.これは相手の頭のプログラムに長い間疑われていた.1月中旬から今まで、約1人の友达の时間、このwindowsの下のredisに振り回されて、以下は問題と方法をみんなと分かち合って、参考にします.
まずシーンを言いますと、プログラムの機能はジョブのスケジューリングセンターで、リアルタイムで新しいジョブ処理モジュールのオンライン状況を監視する必要があります.そこでredisを利用してデータの記憶をして、新しく増加したノードごとに、自分のidをredisに追加して、タイムアウト時間は1.5秒で、毎秒心拍数を報告します.プログラムの実行時間は短くて数分、長くて数時間で、ノードの紛失問題が発生します.問題を探す方法は以下の通りです.
第一に、すべてのredisアクセスロックは、使用するクラスライブラリがスレッドセキュリティの問題を処理していないことを防止します.
第二に、ロックをかけた後もノードが失われている問題が発見され、APIの説明ドキュメントを参照すると、問題がパブリケーションとサブスクリプションに現れる可能性があり、サブスクリプション機能のパブリッシュを停止することを決定します. 
第三に、この時は依然としてだめで、自分のプログラムのマルチスレッドが処理されていない可能性があると推測して、プログラムを単一スレッドに変更して実行して、単一スレッドの実行は問題がありません.
第四に、単一スレッドに問題がない以上、複数の単一スレッドのプログラムを同時に実行して、各プログラムに1つのノードをシミュレートして自分のデータを報告させることを試みて、各プログラムの中ですべてのノードのトポロジー情報を得ることができるはずだが、実行してしばらくすると紛失の問題も発生するが、同じ秒以内に、あるプログラムではノードの損失を報告して、あるプログラムでは報告していない、初歩的な判断はsetとgetの間の時間差の問題による可能性がある.
第五に、linuxの下のredisを交換して第四ステップの同じプログラムで実行した結果、問題は発見されなかった.
結論:windowsの下のredisはlinuxの下の性能がよくなくて、開発する時できるだけlinuxバージョンのredisを使って、結局オンラインになる時linuxで、redisの公式もlinuxのバージョンだけを提供して、プラットフォームの招くredisの違いのためにあまり時間を使う必要はありません!
いずれかのノードの実装は、以下のファイルを8部コピーし、node 1をnode 2、node 3に変更するだけである.Node 8は、同時に実行すると、上記の紛失の問題が観察されます.
 
 
#!/usr/bin/env python
#coding=utf-8
import redis
import time
import random

if __name__ == "__main__":
    rc = redis.Redis(host='127.0.0.1',port=6379,db=1,password='')
    node1 = "node:m1"
    node2 = "node:m2"
    node3 = "node:m3"
    node4 = "node:m4"
    node5 = "node:m5"
    node6 = "node:m6"
    node7 = "node:m7"
    node8 = "node:m8"
    TAG_NODE = "node:m*"
    print "start...", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
    time.sleep(2)
    while True:
        try:
            rc.set(node1, 1, 0, 1500)
            rcds = rc.keys(TAG_NODE)
            if len(rcds) != 8:
                tmp_time = time.time()
                print 'error rcds len =' ,len(rcds), rcds ,tmp_time ,time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(tmp_time))
                ext_node = rc.exists(node1)
                if not ext_node:
                    print "cannot find node1 ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
                ext_node = rc.exists(node2)
                if not ext_node:
                    print "cannot find node2 ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
                ext_node = rc.exists(node3)
                if not ext_node:
                    print "cannot find node3 ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
                ext_node = rc.exists(node4)
                if not ext_node:
                    print "cannot find node4 ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
                ext_node = rc.exists(node6)
                if not ext_node:
                    print "cannot find node6 ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
                ext_node = rc.exists(node6)
                if not ext_node:
                    print "cannot find node6 ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
                ext_node = rc.exists(node7)
                if not ext_node:
                    print "cannot find node7 ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
                ext_node = rc.exists(node8)
                if not ext_node:
                    print "cannot find node8 ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
            time.sleep(1)
            #time.sleep(random.random())
        except Exception , e:
            print 'Exception===',e