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不支持集群命令
    --1

--2

数据库缓存

常见更新逻辑

  • 查询:先在Cache中查询,如果不存在,查询Database,值写回Cache

  • 更新:先更新 cache ,还是先更新数据库?

  • 空对象处理(缓存空对象、布隆过滤器)

  • 热点key重建(互斥锁)

常见套路

  • 失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中;
  • 命中:应用程序从cache中取数据,取到后返回
  • 更新:先把数据存到数据库中,成功后,再让缓存失效
  • 配置合理的过期时间
  • 参考:https://coolshell.cn/articles/17416.html

--3

--4

发送手机验证码

分布式锁

基本实现

  • 获取锁: 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

  • https://redis.io/topics/distlock

  • http://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html

Redis常用工具

大Key查找

热点key发现

热点key处理

  • 本地缓存 + 通知机制
  • 迁移到单独的集群
  • 拆分复杂的数据结构

慢查询分析

  • Slowlog,不包含网络时间,大于10ms都会记录
  • info commandstats
  • 跨机房时,注意网络延迟
  • 从池中获取连接时,设置合理的等待时间
  • Swap 会导致部分查询较慢,从而导致阻塞后续操作
  • Redis持久化等操作也会导致慢查询
    --6
comments powered by Disqus