Redis开发规范和建议

  1. 冷热数据分离,不要将所有数据全部都放到 Redis 中
    虽然 Redis 支持持久化,但是 Redis 的数据存储全部都是在内存中的,成本昂贵。建议根据业务只将高频热数据存储到 Redis 中【QPS 大于 5000】,对于低频冷数据可以使用 MySQL/ElasticSearch/MongoDB 等基于磁盘的存储方式,不仅节省内存成本,而且数据量小在操作时速度更快、效率更高!
  2. 不同的业务数据要分开存储
    不要将不相关的业务数据都放到一个 Redis 实例中,建议新业务申请新的单独实例。因为 Redis 为单线程处理,独立存储会减少不同业务相互操作的影响,提高请求响应速度;同时也避免单个实例内存数据量膨胀过大,在出现异常情况时可以更快恢复服务! 在实际的使用过程中,redis 最大的瓶颈一般是 CPU,由于它是单线程作业所以很容易跑满一个逻辑 CPU,可以使用 redis 代理或者是分布式方案来提升 redis 的 CPU 使用率。
  3. 存储的 Key 一定要设置超时时间
    如果应用将 Redis 定位为缓存 Cache 使用,对于存放的 Key 一定要设置超时时间!因为若不设置,这些 Key 会一直占用内存不释放,造成极大的浪费,而且随着时间的推移会导致内存占用越来越大,直到达到服务器内存上限!另外 Key 的超时长短要根据业务综合评估,而不是越长越好!
  4. 对于必须要存储的大文本数据一定要压缩后存储
    对于大文本【+超过 500 字节】写入到 Redis 时,一定要压缩后存储!大文本数据存入 Redis,除了带来极大的内存占用外,在访问量高时,很容易就会将网卡流量占满,进而造成整个服务器上的所有服务不可用,并引发雪崩效应,造成各个系统瘫痪!(推荐使用gzcompress, 解压缩速度快, 压缩比也很高)
  5. 线上 Redis 禁止使用 Keys 正则匹配操作
    Redis 是单线程处理,在线上 KEY 数量较多时,操作效率极低【时间复杂度为 O(N)】,该命令一旦执行会严重阻塞线上其它命令的正常请求,而且在高 QPS 情况下会直接造成 Redis 服务崩溃!如果有类似需求,请使用 scan 命令代替!
  6. 可靠的消息队列服务
    Redis List 经常被用于消息队列服务。假设消费者程序在从队列中取出消息后立刻崩溃,但由于该消息已经被取出且没有被正常处理,那么可以认为该消息已经丢失,由此可能会导致业务数据丢失,或业务状态不一致等现象发生。
    为了避免这种情况,Redis 提供了 RPOPLPUSH 命令,消费者程序会原子性的从主消息队列中取出消息并将其插入到备份队列中,直到消费者程序完成正常的处理逻辑后再将该消息从备份队列中删除。同时还可以提供一个守护进程,当发现备份队列中的消息过期时,可以重新将其再放回到主消息队列中,以便其它的消费者程序继续处理。
  7. 谨慎全量操作 Hash、Set 等集合结构
    在使用 HASH 结构存储对象属性时,开始只有有限的十几个 field,往往使用 HGETALL 获取所有成员,效率也很高,但是随着业务发展,会将 field 扩张到上百个甚至几百个,此时还使用 HGETALL 会出现效率急剧下降、网卡频繁打满等问题【时间复杂度 O(N)】,此时建议根据业务拆分为多个 Hash 结构;或者如果大部分都是获取所有属性的操作,可以将所有属性序列化为一个 STRING 类型存储!同样在使用 SMEMBERS 操作 SET 结构类型时也是相同的情况!
  8. 根据业务场景合理使用不同的数据结构类型
    目前 Redis 支持的数据库结构类型较多:字符串(String),哈希(Hash),列表(List),集合(Set),有序集合(Sorted Set), Bitmap, HyperLogLog 和地理空间索引(geospatial)等,需要根据业务场景选择合适的类型。
    常见的如:String 可以用作普通的 K-V、计数类;Hash 可以用作对象如商品、经纪人等,包含较多属性的信息;List 可以用作消息队列、粉丝/关注列表等;Set 可以用于推荐;Sorted Set 可以用于排行榜等!
  9. 命名规范
    虽然说 Redis 支持多个数据库(默认 32 个,可以配置更多),但是除了默认的 0 号库以外,其它的都需要通过一个额外请求才能使用。所以用前缀作为命名空间可能会更明智一点。
    另外,在使用前缀作为命名空间区隔不同 key 的时候,最好在程序中使用全局配置来实现,直接在代码里写前缀的做法要严格避免,这样可维护性实在太差了。
    如:系统名:业务名:业务数据:其他
    但是注意,key 的名称不要过长,尽量清晰明了,容易理解,需要自己衡量
  10. 线上禁止使用 monitor 命令
    禁止生产环境使用 monitor 命令,monitor 命令在高并发条件下,会存在内存暴增和影响 Redis 性能的隐患
  11. 禁止大 string
    核心集群禁用 1mb 的 string 大 key(虽然 redis 支持 512MB 大小的 string),如果 1mb 的 key 每秒重复写入 10 次,就会导致写入网络 IO 达 10MB;
  12. redis 容量
    单实例的内存大小不建议过大,建议在 10~20GB 以内。redis 实例包含的键个数建议控制在 1kw 内,单实例键个数过大,可能导致过期键的回收不及时。
  13. 可靠性
    需要定时监控 redis 的健康情况:使用各种 redis 健康监控工具,实在不行可以定时返回 redis 的 info 信息。客户端连接尽量使用连接池(长链接和自动重连)。

原文:Redis 的 KEYS 命令引起 RDS 数据库雪崩,RDS 发生两次宕机,造成几百万的资金损失
作者:陈浩翔

你可能感兴趣的:(redis)