Redis开发指南
基本数据类型
数据类型
String
- 值类型可以是:字符串、数字、二进制
- 最大不超过512M
Hash
- 键值对结构
- ziplist
- 元素个数 < hash-max-ziplist-entries(默认512)
- 所有的值 < hash-max-ziplist-value(默认64字节)
- 比hashtalbe节省内存
- Hashtable
- 读写复杂度为 O(1)
List
- 存储多个有序的字符串
- 最多 2^32−1 个元素
- 列表中的元素是有序的,可以通过
- 列表中的元素可以重复
Set
- 集合中不允许有重复元素,元素是无序的
- 最多 2^32−1 个元素
- 支持交集、并集、差等操作
Sorted Set
- 集合中不允许有重复元素
- 每个元素有一个score,score可以重复,可以按照score 排序
Redis使用注意事项
- key不要使用特殊字符
- value不要使用大value,string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000
- 控制key的生命周期,设置过期时间
- 命令查询:https://redis.io/commands
- O(N)命令关注N的数量。例如hgetall、lrange、smembers、zrange、sinter等并非不能使用,但是需要明确N的值。有遍历的需求可以使用hscan、sscan、zscan代替。
- 禁止线上使用keys、flushall、flushdb等命令。删除大key时,尽量不要直接删除
- 阿里Redis规范:https://yq.aliyun.com/articles/531067
常见场景
扫描Redis中所有的key
- 千万不要使用 keys 命令,线上已屏蔽该命令
- 使用 scan 命令进行扫描,类似的命令还有:sscan、hscan、zscan
大key删除
- Hash删除: hscan + hdel
- List删除: ltrim
- Set删除: sscan + srem
- SortedSet删除: zscan + zrem
清空redis
- 不要使用 flushAll, flushDB
- 阻塞进程。集群模式下触发主从切换
批量操作
- 单类型:mget/mset/hmset/hmget等
- 多类型:pipeline
- pipeline非原子操作
- 集群模式下,只支持所有key在同一个slot的情况;
- JedisCluster不支持集群命令
数据库缓存
常见更新逻辑
-
查询:先在Cache中查询,如果不存在,查询Database,值写回Cache
-
更新:先更新 cache ,还是先更新数据库?
-
空对象处理(缓存空对象、布隆过滤器)
-
热点key重建(互斥锁)
常见套路
- 失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中;
- 命中:应用程序从cache中取数据,取到后返回
- 更新:先把数据存到数据库中,成功后,再让缓存失效
- 配置合理的过期时间
- 参考:https://coolshell.cn/articles/17416.html
发送手机验证码
分布式锁
基本实现
-
获取锁: SET resource_name my_random_value NX PX 30000
-
释放锁: if redis.call("get",KEYS[1])==ARGV[1] then return redis.call("del",KEYS[1])
-
这样实现有什么问题?
-
安全性:任意时刻只有一个客户端可以获得锁
-
避免死锁:客户端最终一定可以获得锁
-
容错性:只要Redsi集群中的大部分节点存活,client就可以进行加锁解锁操作
-
RedLock,基于多个Redis锁实现
-
Redisson
-
http://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html
Redis常用工具
大Key查找
- RDB dump后,分析RDB文件
- redis-cli –bigkeys
- scan + debug object key
- 阿里提供的工具:https://yq.aliyun.com/articles/117042?spm=a2c4e.11153940.blogcont531067.15.fdaf45b5XKtjzI
- 建议客户端在出现异常时,把异常的key打印出来
热点key发现
- 服务端:monitor + 数据分析
- Redis-faina:https://github.com/facebookarchive/redis-faina
- 客户端:通过客户端埋点收集数据上报
- 通过抓起机器上Redis端口所有的TCP数据包进行热点key分析
热点key处理
- 本地缓存 + 通知机制
- 迁移到单独的集群
- 拆分复杂的数据结构
慢查询分析
- Slowlog,不包含网络时间,大于10ms都会记录
- info commandstats
- 跨机房时,注意网络延迟
- 从池中获取连接时,设置合理的等待时间
- Swap 会导致部分查询较慢,从而导致阻塞后续操作
- Redis持久化等操作也会导致慢查询