前言:

    我们知道使用redis计数可以使用incrby, hincrby 等计数指令,因为redis的工作线程只有一个,所以保证了并发原子的控制。  由于我们的业务的特殊性,有增有减,有各类状态值的判断,尤其在异常情况下,计数会减到0以下,负数是不能忍的。 所以,我们需要尽量保证各个计数器值是正整数。 


该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新。  http://xiaorui.cc/?p=4737

我先前的做法是这样, 先判断各种业务在redis中的各种标志位,然后尝试去操作计数,如果拿到的计数值小于0,那么我们给他摆正。 逻辑还是稍显复杂,来回的状态判断就有十几回.

redis command

先前的代码片段如下 (实际逻辑代码过多,就简单举个例子说明):

上面的代码没问题,可以跑… 但是首先不够原子,比如并发都拿到了 -1 值,接着都去 set 1, 这样显而损失了不少精度.  另外一个大点就是性能…  


pipeline批量 ? 是可以解决…  但我们知道pipeline可以减少网络来回的RTT,你也可以在一个管道中混入读写,但问题是,你还是需要做判断… 你的判断比如又要来回…


后面,我们改用redis lua来实现这一块逻辑.   下面的例子是代码片段,其实线上的逻辑要比这复杂的多。 简单说,如果每次判断值都要io来往,那么时间的消耗是必然的。 所以,我们可以把相关的逻辑注册到redis eval方法里,这样只需一次io访问就完成了该逻辑链。  

如果没有使用redis lua的朋友,可以看看我以前写过的redis lua eval的文章。  http://xiaorui.cc/?p=3052

性能测试

性能方面,针对这一块逻辑测试,redis lua要比单条redis性能高很好。如果redis lua方法只是单条指令,那么他的速度要比redis慢…. 原因你懂得…  

中间遇到一些问题,mac上的redis-server是3.2,测试主机2.4 … 对的,相当古老的 2.4 .   也不知道哪位大哥这么仇恨我,居然给我转了个2.4… 导致我忙活了好长时间…   因为先前确认这逻辑没问题,就没有在判断 err 的状态… 

你虽然传入的是int, 但是 redis的lua解释器不认,所以需要用toNumber去转换到 数字对象.  不然会出现下面的问题.  

redis注册lua脚本的时候,会根据内容hash一个code,通过这个code是可以映射相关的lua自定义函数.

END.



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!

详解python调用redis lua内嵌脚本的高级用法

Lua 脚本功能是 Reids 2.6 版本开始提供的高级功能, 我们可以通过redis内嵌的 Lua 环境的进行搞复杂的需求。 使用内置的lua脚本环境可以解决Redis长久以来...

阅读全文

评论已关闭。