是什么
[Remote Dictionary Server] 开源高性能键值对内存数据库
优点
- 读的速度是110000次/s,写的速度是81000次/s
- 支持AOF和RDB及混合持久化方式
- 单个命令操作原子性,LUA操作整体原子性
- 数据结构丰富
- 支持主从,集群,哨兵等多种部署模式
缺点
- 宕机有丢数据风险
- 在线扩容困难
高性能原因
- 基于内存
- 高效的简单动态字符串(simple dynamic string,SDS)
- 单线程处理命令
- NIO通信
数据类型
字符串string:字符串、 整数、 浮点数;做简单的 键值对缓 存;最大512M
列表list:双端队列
散列表hash:MAP
无序集合set:支持交集、并集、差集
有序集合zset:根据分值排序
底层数据结构
摘自:https://juejin.cn/post/6844903936520880135
作者:TurboSnail
SDS
常数复杂度获取字符串长度
空间预分配和惰性空间释放策略,杜绝缓冲区溢出,减少修改字符串时带来的内存重分配次数
二进制安全
内存利用精确到缓存行
链表
双端链表:带有指向前置节点和后置节点的指针,获取这两个节点的复杂度为O(1)
无环:表头节点的prev和表尾节点的next都指向NULL,对链表的访问以NULL结束
链表长度计数器:带有len属性,获取链表长度的复杂度为O(1)
多态:链表节点使用 void*指针保存节点值,可以保存不同类型的值
哈希表
跳表SkipList
有序集合(Sorted Set)的底层实现之一[当如果有序集合包含的元素比较多,或者元素的成员是比较长的字符串时]
应用场景
string——短信验证 码,配置信息等
hash——商品详情, 个人信息详情,新闻详情等。
list——适合存储一些有序且数据相对固定的数据。异步队列rpush生产,blpop阻塞等待消费[pub/sub在没有消费者的时候会丢消息]
set——提供交集、并集、差集操作。例如:查找两个人 共同的好友等。
sortedset——top 10。延时队列,时间戳做score, 消息内容作为key,调用zadd来生产消息, 消费者使用zrangbyscore获取n秒之前的数据做轮询处理。
持久化
- RDB:定时对全量内存数据产生单dump.rdb文件
大数据集启动效率更高
fork 子进程处理
有丢失一段时间数据的风险 - AOF:所有的命令行记录以 redis 命令请求协议的格式完全持久化存储为 aof 文件
可配 appendfsync为always,持久化每次操作
rewrite机制合并命令
AOF 文件比 RDB 文件大
大数据集启动效率较低 - 混合
优先加载AOF
RDB后自动清除过期AOF
选择持久化
- 最大化保障数据不丢失:混合模式
- 业务可以承受数分钟以内的数据丢失:只RDB
- 不推荐只AOF
- 酌情不开启持久化
过期键删除策略
- 惰性过期:仅当key被访问时才判断是否已过期,过期则清除
节省CPU资源,内存有浪费 - 定期过期:定时扫描expires字典中一定数量的key,并清除其中已过期的key
通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果
expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中 的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该 Redis集群中保存的所有键
内存淘汰策略
如果达到设置的内存上限,Redis的写命令会返回错误信息(但是读命令还可以正常返回。)或者适用以下配置的策略丢弃旧的内容
全局的键空间选择性移除
当内存不足以容纳新写入数据时,在键空间中
- noeviction:新写入操作会报错。
- [常用]allkeys-lru:移除最近最少使用的key。
- allkeys-random:随机移除某个key。
设置过期时间的键空间选择性移除
当内存不足以容纳新写入数据时,在设置了过期时间的键空间中
- volatile-lru:移除最近最少使用的key。
- volatile-random:随机移除某个key。
- volatile-ttl:有更早过期时间的key优先移除。
Redis事务
MULTI、EXEC、DISCARD、WATCH
Redis事务不保证原子性,且没有回滚
推荐:Lua脚本执行多个命令
模糊查询key
keys会导致主线程阻塞
scan可以无阻塞获取keys,有概率重复