关于windows下redis频繁get 和set相同值遇到的问题

    最近一段时间事情比较多,没有更新《redis读写分离下的高可用设计与实现》的实现部分,除了之前的实现没有达到高可用的原因外,还有一个重要的原因,我接手的另一个项目中redis频繁get和set相同的值时,出现了不一致的情况,这让我对手头上的程序怀疑了很长一段时间,从1月中旬,到现在,大约一个多朋的时间,被这个windows下的redis折腾得不轻,下面把处理问题和方法和大家分享下,仅供参考。

    先说一下场景,程序的功能是作业的调度中心,需要实时监控新的作业处理模块的在线情况,于是利用redis做数据的存储,每个新增加的结点,把自己的id添加到redis中,超时时间为1.5秒,每一秒钟上报一次心跳。程序运行一段时间,短则几分钟,长则几个小时,会出现结点的丢失问题,查找问题的方法如下:

   第一,所有的redis访问加锁,防止由于使用的类库没有处理好线程安全的问题。

   第二,加锁后仍然发现结点丢失的问题,查阅API说明文档,问题可能出现在发布和订阅上,决定停止发布订阅功能。  

   第三,此时仍然不行,猜测可能是自己程序多线程没有处理好,把程序改为单线程运行,单个线程运行没有问题。

   第四,既然单线程没有问题,那尝试多个单线程的程序同时运行,让每个程序模拟一个结点上报自己的数据,每个程序中应该都能得到所有结点的拓扑信息,但运行一段时间后也会出现丢失的问题,但在同一秒内,有的程序中报了结点的丢失,有的没有报,初步判断可能是由于set 和get之间时间差的问题。

   第五,换linux下的redis用第四步中的相同程序运行,结果没有发现问题。


结论:windows下的redis并没有linux下的性能好,开发的时候尽可能使用linux版本的redis,毕竟上线的时候是linux,redis官方也只给出了linux的版本,没必要为平台导致的redis差异花太多时间!



其中一个结点的实现如下,复制8份下面的文件,只需要修改node1为node2,node3....node8,同时运行,则可以观察到上面说到的丢失的问题。



#!/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


    

关于windows下redis频繁get 和set相同值遇到的问题

上一篇:Windows Server 2012 OEM key


下一篇:Illustrator临摹时尚潮流霸气的英文手写艺术字教程