Key名称
- Key名称的使用规范如下:
使用统一的命名规范。
一般使用业务名(或数据库名)为前缀,用冒号分隔,例如,业务名:表名:id。
控制key名称的长度。
在保证语义清晰的情况下,尽量减少Key的长度。有些常用单词可使用缩写,例如,user缩写为u,messages缩写为msg。
名称中不要包含特殊字符。
Value值
- Value值的使用规范如下:
要避免大Key。
大Key会带来网卡流量风暴和慢查询,一般string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000。
选择合适的数据类型。
比如存储用户的信息,可用使用多个key,使用set u:1:name "X"、set u:1:age 20这样存储,也可以使用hash数据结构,存储成1个key,设置用户属性时使用hmset一次设置多个,同时这样存储也能节省内存。
设置合理的过期时间。
最好是过期时间打散,不要集中在某个时间点过期。
Redis命令
- Redis命令的常用规范如下:
时间复杂度为O(N)的命令,需要特别注意N的值。
例如:hgetall、lrange、smembers、zrange、sinter这些命令都是做全集操作,如果元素很多,是很耗性能的。可使用hscan、sscan、zscan这些分批扫描的命令替代。
命令禁用,使用前,请参考Redis命令兼容性和WebCli命令兼容性。
慎重使用select。
Redis多数据库支持较弱,多业务用多数据库实际还是单线程处理,会有干扰。最好是拆分使用多个Redis。天翼云集群实例不支持多DB。
如果有批量操作,可使用mget、mset或pipeline,提高效率,但要注意控制一次批量操作的元素个数。
- mget、mset和pipeline的区别如下:
mget和mset是原子操作,pipeline是非原子操作。
pipeline可以打包不同的命令,mget和mset做不到。
使用pipeline,需要客户端和服务端同时支持。
lua脚本的执行超时时间为5秒钟,建议不要在lua脚本中使用比较耗时的代码,比如长时间的sleep、大的循环等语句。
调用lua脚本时,建议不要使用随机函数去指定key,否则在主备节点上执行结果不一致,从而导致主备节点数据不一致。
- 集群实例使用lua有如下限制:
使用EVAL和EVALSHA命令时,命令参数中必须带有至少1个key,否则客户端会提示“ERR eval/evalsha numkeys must be bigger than zero in redis cluster mode”的错误。
使用EVAL和EVALSHA命令时,DCS Redis集群实例使用第一个key来计算slot,用户代码需要保证操作的key是在同一个slot。
其他
建议使用连接池+长连接,可以有效控制连接,同时提高效率。
合理设置maxmemory-policy(最大内存淘汰策略)。
noeviction:在这种策略下,如果缓存达到了配置的上限,实例将不再处理客户端任何增加缓存数据的请求,比如写命令,实例直接返回错误给客户端。缓存达到上限后,实例只处理删除和少数几个例外请求。
allkeys-lru:根据LRU(Least recently used,最近最少使用)算法尝试回收最少使用的键,使得新添加的数据有空间存放。
volatile-lru:根据LRU(Least recently used,最近最少使用)算法尝试回收最少使用的键,但仅限于在过期集合的键,使得新添加的数据有空间存放。
allkeys-random:回收随机的键使得新添加的数据有空间存放。
volatile-random:回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
volatile-ttl:回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。
allkeys-lfu:从所有键中驱逐最不常用的键。
volatile-lfu:从具有“expire”字段集的所有键中驱逐最不常用的键。
删除大Key时,不要直接使用del命令。
如果是Hash类型的大Key,推荐使用hscan + hdel
如果是List类型的大Key,推荐使用ltrim
如果是Set类型的大Key,推荐使用sscan + srem
如果是SortedSet类型的大Key,推荐使用zscan + zrem
使用Pipeline时,建议不要一次太多命令,集群最大1024。