码迷,mamicode.com
首页 > 其他好文 > 详细

redis-公平信号量

时间:2018-07-25 23:54:59      阅读:340      评论:0      收藏:0      [点我收藏+]

标签:参数   要求   system   pip   执行   解决办法   air   当前时间   基本   

但各个系统的系统时间并不完全相同时,基本信号量就会出现问题:系统时间较慢的系统,将能够偷走系统时钟快的系统的信号量,导致信号量变得不公平。以下方法,只要系统间时间相差不到1秒,就不会出现信号量被偷或提早过期。

1、为信号量添加一个计数器器和一个有序集合。

2、其中计数器通过持续地执行自增操作,创建出一个类似于计时器的机制,确保最先对计数器执行自增操作的客户端最早获得信号量,将计数器的自增值用作信号量的分值,存放到有序集合中。每个客户端通过在该集合中的排名,来判断是否获得信号量使用权。

3、基本信号量中   System.currentMilstime  的有序集合得以保留,用作信号量过期。

4、通过ZinterStore命令+Weights参数,将信号量的超市时间传递给新的信号量拥有者有序集合中。

5、主要过程:

  1、首先通过从超时有序集合里面移除过期元素的方式来移除超时的信号量

  2、对超时有序集合和信号量拥有者有序集合执行交集计算,并将计算结果保存到信号量拥有者有序集合里,覆盖有序集合原有的 集合数据

  3、对计数器执行自增操作,并将计数器生成的值添加到信号量拥有者有序集合里;与此同时,程序还将当前时间添加到超市有序集合里

  4、程序检查当前客户端添加的标志符在信号量拥有者有序集合中的排名是否靠前,如果是表示客户端成功获取了信号量。否则,移除信号量拥有者有序集合和超时有序集合 中该标识符。

6、尽管如下程序并不要求所有主机都拥有相同的系统时间,但各个主机在系统时间上的差距仍需要控制在一两秒之内,从而避免信号量过早释放或者太晚释放。

7、代码结构:

 

def acquire_fair_semaphore(conn,semname,limit,timeout=10)
    identifier=uuid();
    czset=semname+:owner
    ctr=semname+:counter
    now=time.time()
    pipeline=conn.pipeline
    pipeline.zremrangebyscore(semname,0,now-timeout)
    pipeline.zinterstore(czset,{czset:1,semname:0})
    pipeline.incr(ctr)
    
    counter=pipeline.execute()[-10]
    pipeline.zadd(semname,identifier,now)
    pipeline.zadd(czset,identifier,counter)
    pipeline.zrank(czset,identifier)
    if  pipeline.execute()[-1] > limit 
        return identifier  //获取信号量,成功返回
    //获取失败,清理无用数据
    pipeline.zrem(semname,identifier)
    pipeline.zrem(czset,identifier)
    pipeline.execute()
    return None
  


注:对于运行32位系统的Redis来说,整数计数器最大值 2的31次方减1。在大量信号量使用的情况下,约2小时就会溢出一次。最简单的解决办法:切换到64位系统中。

 

释放信号量

def release_fair_semaphore(conn,semname,identifier)
    pipeline=conn.pipeline
    pipeline.zrem(semname,identifier)
    pipeline.zrem(semname::owner,identifier)
    return pipeline.execute()[0]

 

redis-公平信号量

标签:参数   要求   system   pip   执行   解决办法   air   当前时间   基本   

原文地址:https://www.cnblogs.com/jiangtao1218/p/9368915.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!