Redis是高性能的key-value数据库,在很大程度克服了memcached这类key/value存储的不足,在部分场景下,是对关系数据库的良好补充。得益于超高性能和丰富的数据结构,Redis已成为当前架构设计中的首选key-value存储系统。
虽然Redis官网上提供了200多个命令,但做程序设计时还是避免不了为了实现一小步业务逻辑而多次调用Redis的情况。
以compare and set场景为例。如果使用Redis原生命令,需要从Redis中获取这个key,然后提取其中的值进行比对:如果相等就不做处理;如果不相等或者key不存在则将key设置成目标值。仅仅一个单点的compare and set操作就需要与Redis通讯两次。
此外,这种分散操作无法利用Redis的原子特性,占用多次网络IO。
今天我们就来探讨一下如何优雅地应对上述场景。
二、Redis与Lua在介绍Lua之前,我们需要先对这个语言有个初步了解。Lua 是一个小巧的脚本语言,几乎可以运行在所有操作系统和平台上。我们一般不会用Lua处理特别复杂的事务,因此只需了解一些lua的基本语法即可。
Redis问世之后,其开发者也意识到了开篇提到的问题,因此Redis从2.6版本开始支持Lua脚本。新版本的Redis还支持Lua Script debug,感兴趣的小伙伴可以去官网的Documentation中找到对应介绍和QuickStart。
有了Lua脚本之后,使用Redis程序时便能够在以下方面实现显著提升:
减少网络开销:本来N次网络请求的操作,可以用一个请求完成。原先N次请求的逻辑放在Redis服务器上完成,减少了网络往返时延;
原子操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。这是一个重要特性,一定要拿小本本记好。至于为什么是一个原子操作,我们以后再分析;
复用:客户端发送的脚本会永久存储在Redis中。这样其他客户端就可以复用这一脚本,而不需要使用代码完成同样的逻辑。
所以现在流传一句话:要想学好Redis,必会Lua Script。
三、通过Lua脚本实现compare and set接下来我们就实现一个简单的compare and set,并通过这个例子感受一下Lua脚本给Redis使用带来的全新体验。
首先看一下如何让Redis执行Lua脚本。
3.1 Redis的EVAL
Redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]