一站式学习Redis, 从入门到高可用分布式实践-15-redis开发规范-16-内存管理
15. redis开发规范
- key设计
 三大建议
- 可读性和可管理型:以业务名或数据库名为前缀(防止key冲突),用冒号分割,比如业务名:表名:id,
- 简洁性:保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视,
- 不要包含特殊字符:反例:包含空格、换行、单双引号、以及其它转移字符
- 查看key的编码类型的命令
 object encoding hello
 查看redis版本
 info server
 查看incr键的类型
incr counter
object encoding counter
查看raw类型
set a asdjfkljadslkjadfslkasjlksadfjsadlkfjasdlkjasdklas
object encoding a
type a
type hello
type counter
三个命令都会输出string, 底层存储却不一样,如果是整型,底层会用int存储,如果字节小于45,会用embstr存储,如果字节大于等于45,会用raw存储
- 由此得出结论:我们在设置redis key的时候,尽量把key设置成小于45
 ![]() 
- value设计
- 拒绝bigkey:
 string类型控制在10kb以内,list、set、zset、hash中的元素个数控制在5000个以内,
 反例:一个包含几百万个元素的list、hash等,一个巨大的json字符串
- bigkey的危害
 网络的阻塞、redis的阻塞、集群节点数据不均衡、
 频繁序列化、应用服务器CPU消耗:
 redis本身不负责序列化和反序列化,应用频繁序列化和反序列化bigkey:本地缓存或redis缓存
- bigkey的发现
 应用异常、redis-cli -c -p 8005 --bigkeys、scan+debug object、DEBUG OBJECT hello`
 主动报警:网络流量监控、客户端监控
 内核热点Key问题优化
- 发现bigkey的方法
- 应用方异常
- redis-cli --bigkeys
- scan debug object
- 主动报警:网络流量监控、客户端监控
- 内核热点key问题优化以及工具
- bigkey的删除
- 阻塞:注意隐性删除(过期、rename等)
 删除hash、list、set、sorted set四种数据结构不同数量不同元素大小的耗时
 ![]() 
- redis4.0中有lazy delete(unlink命令)
- bigkey预防
 优化数据结构,例如二级拆分
 物理隔离或者万兆网卡,不是治标方案
 命令优化:hgetall-->hmget、hscan
 报警和定期优化
- bigkey总结
- 牢记redis单线程特性
- 选择合理的数据结构和命令
- 清楚自身的QPS
- 了解bigkey的危害
- 选择合适的数据结构
- 例如实体类型:数据结构内存优化,例如ziplist,注意内存和性能的平衡
 ![]() 
 反例:
set user:1:name zhangsan
set user:1:age 38
set user:1:gender true
正例:
hset user:1 name zhangsan age 38 gender true
- redis内存分析
 ![]() 
 ![]() 
- 注意:redis的二级结构是无法设置过期时间的
- 键值的声明周期
- 周期数据需要设置过期时间
- 过期时间不宜集中,缓存穿透和雪崩问题
- 命令优化技巧
- O(N)以上命令,关注N的数量
 例如:hgetall lrange smembers zrange sinter 等并非不能使用,但是要明确N的值
 有遍历的需求可以使用hscan sscan zscan
- 禁用命令
 禁止线上使用keys *, flushall flushdb等,通过redis的rename机制禁掉命令,或者使用scan的方式渐进式处理
- 推荐合适使用select
 redis的多数据库较弱,使用数字进行分区
 很多客户端支持较差
 同时多业务用多数据库实际还是单线程处理,会有干扰
- redis事务功能较弱,不建议过多使用(不支持回滚)
 而且集群版本自研和官方要求一次事务操作的Key必须在一个slot上(可以使用hashtag解决)
- redis集群版本在使用lua上有特殊要求
 所有的key必须在一个slot上,否则会返回error
- 必要情况下使用monitor命令时,要注意不要长时间使用
 ![]() 
- 客户端优化
- 避免多个应用使用一个redis实例
- 正例:不相干的业务拆分,公共数据做服务化
- 使用连接池,标准使用方式
 ![]() 
16. redis内存管理
本章主要讲解redis内存消耗,组成分析,redis内存管理设置及内存优化技巧
- 
redis内存优化介绍 
 内存消耗:AOF缓冲区、复制缓冲区、fork一个进程的时候
 内存管理:可以设置一个最大内存
 内存优化:内存的节省、以及开发中遇到的问题
- 
redis内存消耗 
- 
内存使用统计 
 info memory
 ![]() 
- 
内存消耗划分 
 ![]() 
 ![]() 
- 
子进程内存消耗 
- 客户端缓冲区
- 普通客户端
- slave客户端
- pubsub客户端
- 输入缓冲区
 注意:最大1GB,超过后会被强制断开,不可动态设置
- 输出缓冲区配置
 ![]() 
- 普通客户端缓冲区
 ![]() 
- slave客户端缓冲区
 默认:client-output-buffer-limit slave 256mb 64mb 64
 阻塞:主从延迟较高,或者从节点过多
 注意:主从网络,从节点不要超过2个
- pubsub客户端缓冲区
 默认:client-output-buffer-limit pubsub 32mb 8mb 60
 阻塞:生产大于消费
 注意:根据实际场景适当调试
 
                    
                     
                    
                 
                    
                












 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号