代码规范 —— Redis 开发规范

优质博文:IT-BLOG-CN
在这里插入图片描述

一、开发规范

【1】弱依赖检查与线下确认:Redis必须是弱依赖,即Redis宕机不影响业务。包括超时检查。
【2】是否当存储使用检查:Redis不能作为存储设备来使用,只能作为缓存或状态等场景来使用。存储优先使用本地缓存。
【3】超时时间检查与线下确认:Redis使用需要设置超时时间。如果超时,对应的策略和方案是什么。
【4】无状态检查:Redis同一个Key不能被不同的应用,不同的场景使用。谁生产,谁消费的原则。
【5】同步锁检查:优先使用集团框架提供的分布式锁。
【6】Key检查:Key的唯一性是否存在明显问题,与其他场景和应用的重名的可能。Key的长度,尽可能的小于128字节,禁止超过1024简洁性
保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视可读性和可管理性 以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:id不要包含特殊字符,反例:包含空格、换行、单双引号以及其他转义字符需要规范(car+应用名+业务名+具体id
【7】审批记录检查:是否已经在审批记录conf完整记录,包括审批人。

二、场景使用

合理使用数据结构: Redis支持的数据库结构类型较多:字符串String,哈希Hash,列表List,集合Set,有序集合Sorted Set, Bitmap, HyperLogLog和地理空间索引geospatial redis命令

需要根据业务场景选择合适的类型,常见的如:
【1】String可以用作普通的K-V、计数类;
【2】Hash可以用作对象如商品、经纪人等,包含较多属性的信息;
【3】List可以用作消息队列(不推荐)、粉丝/关注列表等;
【4】Set可以用于推荐;
【5】Sorted Set可以用于排行榜等;

三、键值设计

key设计:
【1】可读性和可管理性【建议】
   ☑️ 以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔。
   ☑️ 应用名:表名:id
【2】简洁性,key长度适中【建议】
   ☑️ 保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视。
    eg:user:{uid}:friends:messages:{mid}简化为u:{uid}:fr:m:{mid}
【3】不要包含特殊字符【强制】
   ☑️ 禁止包含特殊字符如空格,换行,单双引号,其他转义字符。
【4】Key个数限制【强制】
   ☑️ 由于Redis Rehash机制,实例Key数量达到一定值rehash操作时,需要有一定量空闲内存资源,如key达到134217728rehash需要有2gb空闲内存资源,达到268435456时,rehash需要有4gb空闲内存资源。如果没有组够的内存资源rehash时会发生Key剔除(数据丢失/程序超时/甚至引起切换)。
    单实例key个数达到134217728已经很大了,实例元素过大对于后续分析rdb遍历大key时会非常耗时。

四、value设计

【1】拒绝bigkey(防止网卡流量、慢查询)
   ☑️ 防止网卡流量、慢查询,string类型控制在10KB以内,hashlistsetzset元素个数不要超过5000
   ☑️ 非字符串的bigkey,不要使用del删除,使用hscansscanzscan方式渐进式删除,同时要注意防止bigkey过期时间自动删除问题(例如一个200万的zset设置1小时过期,会触发del操作,造成阻塞,而且该操作不会出现在慢查询中(latency可查))
   ☑️ credis页面,群集所有者可以通过unlink异步清理或小批量迭代清理(或提事件给DBA来处理)

【2】一定要设置过期时间,当实例写满,根据volatile-lru淘汰老的数据
   ☑️ redis只是缓存,不能当成数据库来用。不设置过期时间,redis实例大小会一直无限增长,会出现机器内存耗尽、故障恢复耗时特别长等问题。
   ☑️ 建议使用expire设置过期时间(条件允许可以打散过期时间,防止集中过期),不过期的数据重点关注idletime(该命令返回的是当前键从上一次访问到现在经过的时间(单位,秒))
   ☑️ DBA会定期对redis集群中过期时间超过1年的数据做告警处理。

五、命令使用

【1】禁用KEYS正则匹配,可用SCAN代替
   ☑️ 禁止线上使用keysflushallflushdb等,通过redisrename机制禁掉命令,或者使用scan的方式渐进式处理。
【2】O(N)命令关注N,控制集合元素尽可能小
   ☑️ hgetall/lrange/smembers/zrange等在集合包含元素个数较少的情况下使用。
   ☑️ 若规模较大,有遍历需求,可用HSCAN/SSCAN/ZSCAN渐进式遍历。
【3】合理使用select
   ☑️ redis的多数据库较弱,使用数字进行区分,很多客户端支持较差,同时多业务用多数据库实际还是单线程处理,会有干扰。
【4】Redis事务支持较弱,不建议过多使用
   ☑️ redis的事务功能较弱(不支持回滚),而且集群版本(自研和官方)要求一次事务操作的key必须在一个slot上(可以使用hashtag功能解决)
【5】线上禁止使用monitor命令
   ☑️ 禁止生产环境使用monitor命令,monitor命令在高并发条件下,会存在内存暴增和影响Redis性能的隐患。
【6】使用批量操作提高效率
   ☑️ 原生命令:例如mgetmset
   ☑️ 非原生命令:可以使用pipeline提高效率。
   ☑️ 但要注意控制一次批量操作的元素个数(例如500以内,实际也和元素字节数有关)。
注意两者不同:
     1、原生是原子操作,pipeline是非原子操作。
     2、pipeline可以打包不同的命令,原生做不到。
     3、pipeline需要客户端和服务端同时支持。

六、数据保存

【1】容量合理评估
   ☑️ 在系统设计阶段,需要考虑当前redis集群的容量是否足够,设置合理的大小和过期时间
     1、内存使用率保持在[50%~85%]之间。
     2、使用率<50%需要考虑缩容。
     3、使用率>85%需要考虑扩容。

【2】冷热数据分离
   ☑️ 虽然Redis支持持久化,但是Redis的数据存储全部都是在内存中的,成本昂贵。
   ☑️ 建议根据业务只将高频热数据存储到Redis中【QPS大于5000】,对于低频冷数据可以使用MySQL/ElasticSearch/MongoDB等基于磁盘的存储方式,不仅节省内存成本,而且数据量小在操作时速度更快、效率更高。

【3】不同的业务数据要分开存储
   ☑️ 不要将不相关的业务数据都放到一个Redis实例中,建议新业务申请新的单独实例。
   ☑️ 因为Redis为单线程处理,独立存储会减少不同业务相互操作的影响,提高请求响应速度;同时也避免单个实例内存数据量膨胀过大,在出现异常情况时可以更快恢复服务。

【4】必须要存储的大文本数据一定要压缩后存储
   ☑️ 对于大文本【一般超过500字节】写入到Redis时,建议要压缩后存储。
   ☑️ 大文本数据存入Redis,除了带来极大的内存占用外,在访问量高时,很容易就会将网卡流量占满,进而造成整个服务器上的所有服务不可用,并引发雪崩效应,造成各个系统瘫痪

评论 64
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿进阶

千言万语都不及一句“谢谢”

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值