我们项目使用了openresty(lua-resty-redis)+redis改进API性能吞吐量,效果非常好。用ab压测api benchmark可以达到15w TPS(3 redis instances+ single openresty, 24 core cpu). 但是随着redis存量越来越大,用sentinel+master/slave模式很难水平扩展,所以我们准备替换成redis cluster.
目前openresty尚没有official的redis cluster client, 比较github上其它几个版本,https://github.com/cuiweixie/lua-resty-redis-cluster看下来是最接近我们requirement的。其中ffi slot cache,pipeline的思路都非常好。不过,这个版本距离我们真正使用还是有一些问题:
1) redis-cluster 在resharding slot迁移的时候,smart client需要支持 Move redirection和ASK redirection. (可以看https://redis.io/topics/cluster-spec 关于Redirection and resharding部分)
2) 相应的Pipeline也需要支持 Move redirection和ASK redirection.
3) slotcache需要缓存16384个slot以及对应的负责节点,所以体量不小。在并发较高时,因为cosocket会suspend 当前的coroutine切换其它进来,coroutine stack仍然保留了对这个slotcache的reference不会释放空间, 同时有多个suspend的coroutine就会造成 Lua VM crashed, reason: not enough memory. 所以需要在请求cosocket前把对slotcache的引用清除。
4) 在一些如节点fail/cluster down的状态下,需要额外的error handling. 节点fail需要refresh slot cache.
在这些基础上,我们做了一个新的改进版client, 思路上大体一致(比如slot cache部分已经很好了直接使用),Fix了以上的问题,并且引进一些新的feature, 如:
1) read from slave. redis cluster的slave节点需要enable readonly才可读,因为异步复制。但是对一致性要求不高的场景, 完全可以利用slave来分担一部分读压力。
2) hashtag support(可以看https://redis.io/topics/cluster-spec keys hash tag部分)
由于时间比较紧精力也有限, 所以像mget, mset这一版还没有support。自己使用lua的经验也很短,希望大家多指正。
项目地址: https://github.com/steve0511/resty-redis-cluster