基础
特性:速度快/基于kv结构/功能稳定/持久化/高可用
基本类型:字符串/列表/hash/集合/有序集合
速度快原因:单线程/基于内存的操作/epollo模型
memcached对比:1.支持更多数据类型2.数据持久化3.文件大小限制 redis 512G4.redis单进程mc多进程
遍历:keys 遍历所有 scan渐进式遍历
3种移动key的方式 move,dump/restore,migrate
扩展应用
lua
通过eval和evalsha(加载到服务端执行)执行lua脚本
好处:1.lua脚本在redis是原子操作不插入其他命令2.可以扩展redis功能3.多条命令打包减少开销
pipeline
1.批量执行2.非原子性3.只能操作一个实例4.使用时避免过大堵塞
事务
1.使用multi和exec执行事务2.命令是原子顺序执行3.事务不支持回滚
持久化
AOF
使用日志记录每次的命令,重启后再执行AOF中的命令恢复数据,解决数据持久化的实时性。使用文本协议保存。也可以手动和自动触发命令。redis启动时优先判断AOF文件是否存在
重写文件变小:1.过期数据不再写入2.去除无效命令只保存最终结果3.多条命令合并成一个
RDB
定义:把当前进程数据生成快照保存到硬盘,可以手动和自动触发。bgsave(子进程方式)非阻塞 save阻塞。
优点:1.紧凑二进制文件,适合备份 2.加载RDB速度比AOF快
缺点:1.不能做到实时/秒级持久化2.新老版本格式不一致不容易兼容
内存管理
回收策略(删除过期时间的键)
惰性删除:过期对象被使用时才删除,可能存在内存泄露
定时任务扫描:每秒运行10次,使用快慢两种方式回收键
内存溢出控制:1.拒绝写入2.最近最少使用3.随机删除所有键等
使用优化:1.缩减key和value的大小 2.使用共享对象池(LRU相关淘汰策略无效,只支持整数对象池)3.避免频繁操作减少碎片
碎片产生的原因:频繁append setrang等
高可用
主从复制
配置从节点同步数据,支持树状结构复制。
主从节点维护心跳和偏移量监测保证通讯和数据一致
哨兵
能够实现高可用,实现故障发现,故障转移,客户端通知。在对节点做失败判断时分为主观下线和客观下线(Page:257)。
集群(Redis Cluster)
实现原理:使用哈希分布,一致性哈希通过哈希环实现。哈希槽0-16383
集群功能限制:1.key批量操作支持有限(mset/mget),因为分配到不同的槽中2.事务操作的限制3.不支持多数据库空间 4.复制结构只能一层
缓存设计
更新策略
LRU/LRF/FIFO算法
超时剔除
主动更新
穿透优化
缓存空对象,并设置一定过期时间
布隆过滤器(对有效key的验证)
雪崩
保持高可用
使用组件限流降级
热点key优化
互斥更新value
不过期
异步更新策略
进阶
bigkeys
危害:内存空间不均衡,超时,网络堵塞
如何发现:redis_cli --bigkeys,被动收集/scan + debug object主动发现
惰性删除:lazy delete free 异步操作,不会堵塞
实现原理
string
raw(动态字符串编码)
embstr(优化内存分配的字符串编码)
int(整数编码)
hash
hashtable
ziplist(压缩列表)
list
linkedlist(双向链表)
ziplist(压缩列表)
quicklist
set
hashtable
intset(整数集合编码)
zset
ziplist(压缩列表)
skiplist(跳跃表)
底层实现
ziplist(压缩表):https://www.kancloud.cn/kancloud/redisbook/63856
skiplist(跳跃表):字典保存member到score的映射。基于链表按照score从小到大排列,增加跳跃功能,新增加数据时候会随机分层。跳表保存key用于排序和范围查找
intset(整数集合编码) https://www.kancloud.cn/kancloud/redisbook/63849
阻塞
导致阻塞的原因:数据类型使用不合理,持久化阻塞,cpu饱和,网络等问题
对应几个解决方法:慢日志,关注CPU使用率,禁止不合理使用命令 keys,sort等