目录
特点
单线程、内存、多数据结构、键值对
单进程速度快的原因
- 单进程不用切换、加锁
- 内存操作
- IO多路复用
- 数据结构的各种方式加快查询,Hash的键值对模型
- 根据存储数目来切换数据结构
过期键删除策略
作用:
- 内存有限,淘汰不常用的数据,只维护热点数据
- 作为分布式锁时,防止锁线程挂掉,锁一直不释放
策略:
- 定时删除:根据过期时间设置一个定时器,过期就立即删除
- 惰性删除:访问数据时才检查数据是否过期,过期就删除
- 定期删除:每过一段时间,组织一次过期键删除
对比
定时删除 惰性删除 定期删除 内存友好 最佳
立即释放内存
最差
过期数据长期占据内存
次之
CPU友好 最差
CPU紧张时把时间花在无用的过期数据上
最佳
只有清理在非做不可时才做,能拖就拖
次之
需要合理设置周期、清理范围
举例 垃圾立刻就扔 妈妈检查时才仍 过一段时间整理下房间
redis 增量式迭代
返回0时结束(缺点是值可能会被修改)
- SCAN cursor [MATCH pattern] [COUNT count] 迭代所有Key
- SSCAN 迭代Value
- HSCAN 迭代hash的键值
- ZSCAN 迭代分值、元素
数据结构
字符串 列表 哈希 集合 有序集合 特点 SDS 1 动态,有长度,也以'\0'结尾,可以预先分配内存 双向链表 数量多、长字符串 有长度 字典 数量多、长字符串 数量多、长字符串 两个哈希表,一个渐进式rehash时使用;链地址法
整数集合 只含数值,且数值小 存3种类型整数,数组是int8_t类型的,元素类型升级(int16升int32,省内存)
有序、无重复
压缩列表 元素少、小整数或段字符串 元素少、小整数或段字符串 元素少、小整数或段字符串 顺序数据结构,每个节点保存字节数组和整数值,连锁更新 跳跃表 数量多、长字符串 特殊链表,每个节点含多个指向后面节点的指针;随机层数(每层指向下一个同级层)
存(分值+数据),按分值排序
String
在Redis里,字符串字面量用C中的字符串,其余字符串用SDS(Simple Dynamic String)
SDS与C字符串的区别
SDS C字符串 区别1 求长度 O(1) O(n) 区别2 缓冲区溢出 修改前判断容量是否足够,不够则扩容 buf操作时容易溢出 区别3 内存重分配 1. 预分配内存
2. 惰性释放
由增长、缩减引起 区别4 二进制安全 直接操作二进制,能处理图像、视频等二进制数据 字符必须符合某种编码 区别5 兼容部分C的函数
跳跃表
特点:链表的一种,每个节点含多个指向其他节点的指针,以加快查找速度
- 每个指针被称为层,节点创建时会根据幂次定律(大值出现概率小),初始化1-32个层,同一级别层相连
- 层会指向下一个同级别层的位置,span记录距离,用于查询下一个节点的位置
struct skiplistNode{ struct layer{ skiplistNode *forward;//向前移动的指针 unsigned int span;//跨度,到前方节点的距离,计算所在位置 }layers[]; skiplistNode *backward;//后退指针 float score; object *obj; }; struct zkkiplist{ skiplistNode *head,*tail; unsigned int length;//节点个数 int level;//节点最大层数 };
结构见上图,引自redis设计与实现(第二版)
为什么用跳跃表不用红黑树:跳跃表能实现O(n)的范围查询,红黑树是O(nlogn)
有序集合实现
元素组成:分值+成员
特点:元素按分值排序
实现:跳跃表+哈希
- 跳跃表实现zrange O(N)的范围查询
- 哈希存储成员->分值的映射,实现O(1)的score操作
- 两者存的节点都是链表结构,共享内存,可以理解是所有跳跃表节点都放到了哈希表里了,所以不会浪费内存
zrange过程:
- 先查找区间左端点位置
- 从头节点层数最高层往下遍历,找链接节点中第一个不大于score的,跳到那
- 如果=就找到了,没有就继续重复跳,直到遍历所有层都没有就结束
- 复杂度:最坏O(N),都是1层,遍历,平均O(logN),层数遍历不影响复杂度,因为层数32是常量
- 然后根据第一层指针开始遍历,直至右端点,时间复杂度O(n),n是区间长度
持久化
RDB持久化
SAVE:阻塞,写入RDB文件中
BGSAVE:fork子线程进行写RDB,父线程继续处理请求
载入RDB时一直阻塞
AOF持久化
修改操作写入AOF文件,恢复时创建一个没有网络连接的客户端来重新执行AOF中的命令
过于庞大后可进行AOF重写,即将现存数据转化成插入操作写到新的AOF,之后替换掉原先的
Redis的应用
Redis多机的三种模式