这周遇到的一个小需求是通过Go实现对Redis的hash field实时上限检查,而因为是线上的服务,所以这个上限检查不能对redis pod造成负担,跟组内导师交流学习后了解到可以通过redis的HScan命令来实现这个需求
redis的具体实现中,使用了一种叫做**渐进式哈希(rehashing)**的机制来提高dict的缩放效率SCAN命令是基于游标(cursor)迭代的,SCAN命令并不单纯指代SCAN命令,还包含SSCAN、HSCAN、ZSCAN,每种命令操作对象是有区别的,但用法及功能基本相同
当Redis中的数据量很大时,因为Redis是单线程服务,所以一些数据操作会导致Redis服务卡顿,甚至宕机。当某一指令耗时很长时(比如经典的keys *),就会阻塞后续的指令执行。当被积压的指令越来越多时,Redis服务占用CPU将不断升高,最终导致Redis pod崩溃
相比于keys命令,scan命令有两个比较明显的优势:
通用参数:
命令 | 功能 | 参数 | 返回值 |
|---|---|---|---|
SCAN | 基于游标迭代DB | cursor [MATCH pattern] [COUNT count] | 返回数组,第一个值是下一次迭代的游标(uint64),第2个值是元素列表(key列表) |
SSCAN | 基于游标迭代Sets | key cursor [MATCH pattern] [COUNT count] | 返回数组,第一个值是下一次迭代的游标(uint64),第2个值是元素列表 |
HSCAN | 基于游标迭代Hashes | key cursor [MATCH pattern] [COUNT count] | 返回数组,第2个值是field-value列表 |
ZSCAN | 基于游标迭代ZSets | key cursor [MATCH pattern] [COUNT count] | 返回数组,第2个值是member-score列表 |

redis Scan命令是在生产环境中操作redis大key最合适的命令,但相应地,使用起来也是有很多坑点需要开发者注意的(我一开始也觉得这个需求几行加个定时任务就结束了,没想到一搞就是两天)