Redis
2020-09-29 15:50:05 0 举报
AI智能生成
Redis脑图
作者其他创作
大纲/内容
独立功能
发布与订阅
命令
PUBLISH
SUBSCRIBE
PSUBSCRIBE
实现
redisServer中publish_channels字典
key:被订阅的频道
value:订阅的客户端链表
redisServer中publish_patterns字典(模式)
事务
命令
MULTI
EXEC
WATCH
实现
事务开始
MULTI
切换到事务状态
命令入队
redisclient中保存事务的命令队列
事务执行
EXEC
1、遍历该客户端的事务队列
2、执行队列的所有命令
3、结果全部返回
WATCH
乐观锁
在EXEC命令执行前,监视键是否被修改过
是
拒绝执行事务
返回客户端事务执行失败
慢查询日志
slowlog-log-slower-than
超过多少微秒的命令请求会被记录到日志上
slowlog-max-len
最多保存多少条慢查询日志
基本概念
Redis是什么
Redis是一个开源的、基于内存的数据结构存储器,分布式缓存,可以用作数据库、缓存和消息中间件。
Redis优点
(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
(2)支持丰富数据类型,支持string,list,set,sorted set,hash
(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
Redis缺点
(一)缓存和数据库双写一致性问题
(二)缓存雪崩问题
(三)缓存击穿问题
(四)缓存的并发竞争问题
应用场景
缓存
队列
网站访问统计(计数器)
分布式session
排行榜
Redis与Memcached的区别与比较
1 、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。memcache支持简单的数据类型,String。
2 、Redis支持数据的备份,即master-slave模式的数据备份。
3 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而Memecache把数据全部存在内存之中
4、 redis的速度比memcached快很多
5、Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的IO复用模型。
Redis常见性能问题和解决方案
1、Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
2、如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
3、为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
4、尽量避免在压力很大的主库上增加从库
5、主从复制不要用网状结构,用单向链表结构更为稳定,即master<-slave1<-slave2<-slave3
数据结构与对象
简单动态字符串
SDS
simple dynamic string
没有直接使用C语言的字符串
和Java的String很像
与C字符串的区别
常数复杂度获取字符串长度
杜绝缓冲区溢出
自动扩展buf数组
降低修改字符串导致的内存重分配次数
空间预分配
惰性空间释放(缩短时)
二进制安全
C字符串
字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串结尾
SDS
Redis不是用这个数组来保存字符,而是用它来保存一系列二进制数据。
数据结构
链表
Redis构建了自己的链表
保存不同类型的值
双端
无环
带头指针、尾指针
带链表长度计数器
多态
分支主题
数据结构
字典
Redis构建了自己的字典实现
同java实现几乎一样
C语言的实现版本
特点
哈希算法
解决冲突
链地址法
新节点添加到表头(为了速度)
rehash
1)为字典的ht[1]哈希表分配空间,这个哈希表的空间大小取决于要执行的操作,以及ht[0]当前包含的键值对数量
2)将保存在ht[0]中的所有键值对rehash到ht[1]上面:rehash指的是重新计算键的哈希值和索引值,然后将键值对放置到ht[1]哈希表的指定位置上。
3)当ht[0]包含的所有键值对都迁移到了ht[1]之后(ht[0]变为空表),释放ht[0],将ht[1]设置为ht[0],并在ht[1]新创建一个空白哈希表,为下一次rehash做准备。
渐进式rehash
why
避免rehash对服务器性能造成影响
how
维护2个table
增删改查均在2个table中进行
查找
h[0],h[1]都找
增加
h[1]
步骤
1)为ht[1]分配空间,让字典同时持有ht[0]和ht[1]两个哈希表。
2)在字典中维持一个索引计数器变量rehashidx,并将它的值设置为0,表示rehash工作正式开始。
3)在rehash进行期间,每次对字典执行添加、删除、查找或者更新操作时,程序除了执行指定的操作以外,还会顺带将ht[0]哈希表在rehashidx索引上的所有键值对rehash到ht[1],当rehash工作完成之后,程序将rehashidx属性的值增一。
4)随着字典操作的不断执行,最终在某个时间点上,ht[0]的所有键值对都会被rehash至ht[1],这时程序将rehashidx属性的值设为-1,表示rehash操作已完成。
数据结构
跳跃表
有序数据结构
查找效率
平均O(logN)
最坏O(N)
和平衡树相当
可批量处理节点
结构
跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。
整数集合
有序
无重复
可类型升级,但不能降级
结构
数组实现
压缩列表
特点
列表键、哈希键的底层实现
每个列表项
小整数
长度比较短的字符数组
节约内存
一系列特殊编码的连续内存块
一个字节数组
一个整数值
顺序数据结构
连锁更新
对象
特点
Redis没有直接使用上述数据结构
使用对象(数据结构的组合)
判断是否可以执行给定的命令
分类
字符串对象
int
整数值
raw
字符串,len>39字节
embstr
短字符串的优化编码
列表对象
ziplist
所有字符串len<64字节
元素个数<512个
linkedlist
哈希对象
ziplist
key,value紧挨着
hashtable
集合对象
intset
所有元素:整数
元素数量<512个
hashtable
有序集合对象
编码(key+score)
ziplist
所有字符串len<64字节
元素个数<64个
skiplist
skiplist
特点
类型检查(值)
多态命令
内存回收
引用计数
refcount
对象共享
refcount
对象的空转时长
lru
最后一次被访问时间
数据结构
单机数据库
数据库
键空间
redisDb dict字典
保存所有键值对
操作
增加
删除
更新
获取
维护操作
键空间命中次数
更新键空间的LRU
WATCH
设置键的生存时间、过期时间
TTL:Time to live
redisDb expires字典
过期字典
所有键的过期时间
过期删除策略
定时删除
惰性删除
定期删除
Redis删除策略
惰性删除+定期删除
数据库通知
AOF、RDB和复制功能对过期键的处理
执行SAVE命令或者BGSAVE命令所产生的新RDB文件不会包含已经过期的键。
执行BGREWRITEAOF命令所产生的重写AOF文件不会包含已经过期的键。
当一个过期键被删除之后,服务器会追加一条DEL命令到现有AOF文件的末尾,显式地删除过期键。
当主服务器删除一个过期键之后,它会向所有从服务器发送一条DEL命令,显式地删除过期键。
从服务器即使发现过期键也不会自作主张地删除它,而是等待主节点发来DEL命令,这种统一、中心化的过期键删除策略可以保证主从服务器数据的一致性。
结构
回收策略
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据
RDB持久化
RDB文件
压缩的二进制文件
命令
SAVE
阻塞Redis服务器进程
BGSAVE
属性
dirty
距离上次SAVE成功后,进行的修改次数
lastsave
上次SAVE成功时间
AOF持久化
特点
Append Only File
保存服务器所执行的写命令
纯文本格式
实现
命令追加
写命令-->aof_buf缓冲区
文件写入、同步
flushAppendOnlyFile
AOF重写
减少AOF文件体积
读取当前数据库状态
事件
事件驱动程序
时间事件
定时事件
周期性事件
文件事件
Reactor模式
网络通信程序
文件事件处理器:单线程
I/O多路复用,监听多个套接字
select
epool
kqueue
对套接字操作的抽象,相应的文件事件
可应答
可写
可读
服务器
命令请求的执行过程
发送命令请求
客户端->(协议格式)->服务器
读取命令请求
命令执行器
查找命令实现
执行预备操作
调用命令的实现函数
执行后续操作
命令回复给客户端
serverCron函数
更新服务器时间缓存
更新LRU时钟
更新服务器每秒执行命令次数
更新服务器内存峰值记录
管理客户端资源
执行被延迟的BGREWRITEAOF
检查持久化操作的运行状态
将AOF缓冲区写入AOF文件
关闭异步客户端
增加cronloops计数器的值
多机数据库
复制
特点
命令:SLAVEOF
主服务器:master
从服务器:slave
实现
PSYNC
完整重同步
初次复制
让master创建并发送RDB文件
向slave发送缓冲区的写命令
部分重同步
断线后重复制
条件允许,仅复制断开区间
复制偏移量
复制积压缓冲区
命令传播
Sentinel
哨兵
Redis的高可用解决方案
监视任意多个服务器(主从)
集群
特点
分布式数据库方案
集群通过分片来进行数据共享,并提供复制和故障转移功能
节点
启动节点
集群数据结构
clusterNode
记录自己的状态
集群其他节点的状态
CLUSTER MEET实现
MEET
PING
PONG
通过Gossip协议传播给集群
槽指派
特点
整个数据库:16384个槽
每个键都是其中之一
每个节点可处理0~16384个槽
当槽都有节点,集群处于上线状态
记录节点的槽指派信息
传播节点的槽指派信息
记录集群所有的指派信息
在集群中执行命令
接受命令的节点,计算处于哪个槽
是自己?处理
否
返回客户端MOVED错误
指引客户端redirect至正确节点
计算键属于哪个槽
CRC16(key)&16383
节点只能使用0号数据库
重新分片
特点
将某节点的槽->另一节点
键值对也转移
ASK错误
特点
重新分片时,槽的键值对恰好迁移一半
流程
类似与渐进式rehash
先在源节点找
找不到发送ASK错误,指引客户端找到目标节点
复制与故障转移
主从切换
选举新的主节点
命令
1、CLUSTER NODES:查看集群当前节点情况
2、CLUSTER MEET:将节点添加到集群中
3、CLUSTER ADDSLOTS:分派10384个槽
4、CLUSTER KEYSLOT:查看给定键属于哪个槽
5、CLUSTER REPLICATE:设置从节点
0 条评论
下一页