Redis使用规范指导

Redis使用规范指导

一. 键值设计

1.key名设计:

  • 可读性和可管理性: 以业务名:表名:id 来避免冲突;
1
user:book:1
  • 简洁性: 不要过长, 会导致内存占用过高; 最好不要超过20字节;
1
若过长: 就把常用的单词缩写: 如: u:bok:1
  • 不要包含特殊字符(强制)
1
如 空格, 换行, 单双引号以及其他的转义字符

2.value设计

  • 避免bigkey, 大数据(慢查询根源)(强制)
1
2
string类型控制在10kb以内, hash, list, set, zset等元素不要超过5000
非字符串的bigkey, 不要使用del删除, 使用hscan, sscan, zscan方式渐进式删除, 同时要注意防止bigkey过期时间自动删除问题(例如一个200万的zset设置1小时过期, 会触发del操作, 造成阻塞, 而且慢查询不可查(查latency可发现))
  • 选择适合的数据类型
1
2
3
4
5
6
7
8
使用实体类型时(合理控制和使用数据结构内存编码优化配置, 例如ziplist, 注意节省内存和性能之间的平衡)
反例:
set user:1:name tom
set user:1:age 19
set user:1:favor football

正例:
hmset user:1 name tom age 19 favor football
  • 控制key的生命周期, 不要随随便便就设置永久, redis不是垃圾桶(强制)
1
基本上所有key都需要设置生命周期, 永久生命周期的需要上报且备注;

二.命令的使用

  • O(N)命令关注N的数量级后再使用;
1
如hgetall, lrange, smemebers, zrange, sinter等并非不能使用, 但是要明确N的值后再用, 遍历请使用hscan, sscan, zscan代替;
  • 禁止使用的命令
1
keys, flushall, flushdb等
  • 合理使用select
1
其实大部分情况下没必要分库使用, 因为还是单线程处理; 使用分库时请认真想清楚再使用;
  • 使用批量操作提高效率
1
2
3
4
5
6
7
8
1) 使用原生命令时, 可以用: mget, mset等
2) 编程时, 可以使用pipeline提高效率(但注意量级)
注意控制好一次批量操作的元素个数(例如500以内, 也跟字节数有关)

注意不同点:
1.pipeline 需要客户端和服务端同时支持(现在一般支持)
2.pipeline可以打包不同的命令, 原生做不到;
3.原生命令为原子操作, pipeline为非原子操作;
  • 不太建议过多使用Redis的事务功能, 功能较弱
1
首先不支持回滚, 然后集群版本要求一次事务操作的key必须在一个slot上, 比较麻烦;
  • Redis集群版本上在使用lua上有特殊要求;
1
2
3
1.所有key都应该由 KEYS 数组来传递,redis.call/pcall 里面调用的redis命令,key的位置,必须是KEYS array, 否则直接返回error,"-ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS arrayrn"

2.所有key,必须在1个slot上,否则直接返回error, "-ERR eval/evalsha command keys must in same slotrn"
  • 必要情况下使用monitor命令时, 要注意不要长时间使用;

三.客户端使用

  1. 尽量避免多个应用使用同一个Redis实例;
1
因为redis是单线程的, 如果使用同一个, 极易让两个应用互相影响;
  1. 使用连接池控制连接; 提供效率;
1
spring boot1.x是自带Jedis连接池, 2.x以上使用lettuce连接池
  1. 高并发最好增加熔断功能(如 netflix hystrix)
  2. 设置合理密码, 提高安全性, 内网访问, ssl加密
  3. 选择好内存淘汰策略
1
2
3
4
5
6
volatile-lru(默认): 优点是不会淘汰掉不过期的key,但缺点可能会OOM;
allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。
allkeys-random:随机删除所有键,直到腾出足够空间为止。
volatile-random:随机删除过期键,直到腾出足够空间为止。
volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略。
noeviction:不会剔除任何数据,拒绝所有写入操作并返回客户端错误信息"(error) OOM command not allowed when used memory",此时Redis只响应读操作。

四.删除bigkey方法

1.可以用pipeline加速;

2.4.0以上版本可以支持异步删除;

  • Hash删除: hscan + hdel
  • List删除: ltrim
  • Set删除: sscan + ssrem
  • SortedSet删除: zscan + zrem

五.推荐书籍

  1. Redis开发与运维

参考链接

1.https://yq.aliyun.com/articles/531067

hyhcoder wechat
扫码关注我的个人订阅号