您当前的位置:首页 > 文章 > 代码规范 —— Redis 开发规范

代码规范 —— Redis 开发规范

作者:程序猿进阶 时间:2024-08-15 阅读数:781 人阅读

一、开发规范

【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达到134217728,rehash需要有2gb空闲内存资源,达到268435456时,rehash需要有4gb空闲内存资源。如果没有组够的内存资源rehash时会发生Key剔除(数据丢失/程序超时/甚至引起切换)。
    单实例key个数达到134217728已经很大了,实例元素过大对于后续分析rdb遍历大key时会非常耗时。

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

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

五、命令使用
【1】禁用KEYS正则匹配,可用SCAN代替
     禁止线上使用keys、flushall、flushdb等,通过redis的rename机制禁掉命令,或者使用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】使用批量操作提高效率
     原生命令:例如mget、mset。
     非原生命令:可以使用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,除了带来极大的内存占用外,在访问量高时,很容易就会将网卡流量占满,进而造成整个服务器上的所有服务不可用,并引发雪崩效应,造成各个系统瘫痪

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        

原文链接:https://blog.csdn.net/zhengzhaoyang122/article/details/141091316

本站大部分文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了您的权益请来信告知我们删除。邮箱:1451803763@qq.com