实现一个 redis 命令 --nonzerodecr
上篇文章介绍了命令的执行流程,对redis如何执行命令也有了初步的了解,通过实现一个redis命令来再次加深印象。
笔者平时主要语言是PHP,有些功能PHP无法满足就会用到PHP的扩展,比如swoole。因此,就想到redis可不可以以做扩展?为了满足一些特殊的需求,可不可以为redis开发一个命令?
前期准备
因为redis是用C开发的,为了能开发redis命令,首先也是必须的是,你要懂一点C语言基础,另一个就是,需要了解一下redis命令是如何执行的,知道redis执行命令大概的流程,最简单的一个流程描述就是:
读取命令->解析命令->调用命令函数->返回执行结果
或者再读一次上篇文章。
我们要做的就是,确保redis能解析到新增的命令,能根据输入的命令找到对应的方法并执行。
函数需求
要实现一个命令,说明当前redis的命令无法满足开发的需求。考虑这样的一个需求,在秒杀的情景下,达到了这样的case:商品剩下最后一件,两个用户同时抢购,使用业务代码:
这样做有个问题就是活动结束后,key的值可能为-1,这样对于最终查询库存时会出现负值,不利于数据对账及统计。那么,能不能新增一个命令,让redis在计算时判断key的值,如果是0就不进行扣减呢?
将函数命名为nonzerodecr,开始实现。
添加函数名到命令表
把函数名称添加到命令表,参照decr命令的命令表:
增加nonzerodecrCommand:
声明nonzerodecr,因为新增的命令nonzerodecr只是内部增加一个非0的判断,其余操作没有变化,因此只需要跟decrCommand一样的声明即可:
实现函数
在实现新的函数之前,先看看decrComamnd命令的实现:
函数调用了incrDecrCommand实现自增和自减,实现如下:
函数的流程图如下:
如图所示,要实现函数nonzerodecrCommand,只需要在进行增/减操作前增加一个大于等于0 的判断即可,其余的逻辑不变,实现如下:
编译测试
编写完代码后,对代码进行编译测试:
结果符合最初的需求,在值等于0之后,再进行扣减,值不会变为负数。
总结与思考
通过介绍实现nonzerodecr命令的过程,对如何实现一个命令有了一个初步的认识,之后如果有新的需求也可以根据这个步骤去实现一个新的命令。
上面介绍的命令实现方式比较粗暴,可能会有隐藏的bug,但对于入门实现一个命令这个目的来说,这个代码时可以的,另外,一开始提到的秒杀场景除了可以使用新命令来解决,也可以使用redis-lua脚本的形式来实现,实现方法是多样的,具体的技术选型需要根据业务的场景来选择,如果你有更好的方案,欢迎评论留下你的方案。
原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
如果本文对你有帮助,请点个赞吧,谢谢^_^
版权声明: 本文为 InfoQ 作者【老胡爱分享】的原创文章。
原文链接:【http://xie.infoq.cn/article/e79b8ff3782fefc03c844274e】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论