redis知识脑图
2022-03-01 16:57:10 0 举报
AI智能生成
redis知识脑图
作者其他创作
大纲/内容
hash数据结构
lpush/rpop
子主题
list数据结构
数据结构
Pipeline
发布订阅
一主一从
优点
一主多从
优点:当读请求并发高的时候可以将读命令发送到从节点,分担主节点的压力;缺点:当从节点过多的时候会影响主节点性能;影响主节点带宽以及负载;
树状主从
优点:可以减轻主节点的复制压力,A到B只需要推送一次数据,D和E的数据由B进行推送
主从复制方案
1、在配置文件中加入slaveof {masterHost} {masterPort}随Redis启动生效redis5.0之后用replicaof {masterHost} {masterPort}
2、在redis-server启动命令中加入--slaveof {masterHost} {masterPort} 生效
3、直接使用命令: slaveof {masterHost} {masterPort}
主从配置
命令:slaveof {newMasterHost} {masterPort}
切主操作流程:1、断开与旧主节点复制关系2、与新主节点建立复制关系3、删除从节点当前所有数据4、对新主节点进行复制操作
换主
命令:slaveof no one
断开复制流程:1、断开与主节点复制关系2、从节点晋升为主节点
断开复制
主从配置方式slaveof命令
查看验证
1、保存主节点信息2、主从建立socket连接3、发送ping命令4、权限校验5、同步数据集6、命令持续复制
后台同步原理
主节点(master)在处理完写入命令后,会把命令的字节长度做累加记录;统计信息在info relication中的master_repl_offset指标中:127.0.0.1:6379> info replication# Replicationrole:master...master_repl_offset:1055130
参与复制的主从节点都会维护自身的复制偏移量
主从节点维护自身的复制偏移量
1、复制偏移量
复制积压缓冲区是保存在主节点上的一个固定长度的队列,默认大小为1MB,当主节点有连接的从节点(slave)时被创建,这时主节点(master)响应写命令时,不但会把命令发送给从节点,还会写入复制积压缓冲区
根据统计指标,可算出复制积压缓冲区内的可用偏移量范围:[repl_backlog_first_byte_offset,repl_backlog_first_byte_offset+repl_backlog_histlen]。
复制积压缓冲区是先进先出的队列,相关信息在主节点的replication中显示127.0.0.1:6379> info replication# Replicationrole:master...repl_backlog_active:1 // 开启复制缓冲区repl_backlog_size:1048576 // 缓冲区最大长度repl_backlog_first_byte_offset:7479 // 起始偏移量,计算当前缓冲区可用范围repl_backlog_histlen:1048576 // 已保存数据的有效长度
复制积压缓冲区
2、复制积压缓冲区replication buffer
为什么不用ip+port呢?如果只使用ip+port的方式识别主节点,那么主节点重启变更了整体数据集(如替换RDB/AOF文件),从节点再基于偏移量复制数据将是不安全的,因此当运行ID变化后从节点将做全量复制。
每个Redis节点启动后都会动态分配一个40位的十六进制字符串作为运行ID。运行ID的主要作用是用来唯一识别Redis节点,比如从节点保存主节点的运行ID识别自己正在复制的是哪个主节点。
可以通过info server查看运行id127.0.0.1:6379> info server# Serverredis_version:3.0.7...run_id:545f7c76183d0798a327591395b030000ee6def9
debug reload
可以使用debug reload命令重新加载RDB并保持运行ID不变,从而有效避免不必要的全量复制
debug reload命令会阻塞当前Redis节点主线程,阻塞期间会生成本地RDB快照并清空数据之后再加载RDB文件。因此对于大数据量的主节点和无法容忍阻塞的应用场景,谨慎使用。
如何在不改变run id的情况下重启
Redis关闭再启动后,运行ID会随之改变
3、主节点运行ID
psync -1代表全量同步
命令格式:psync {runId} {offset}·runId:从节点所复制主节点的运行id。·offset:当前从节点已复制的数据偏移量。
1、返回全量复制标记,从节点触发全量复制流程2、返回部分复制标记,从节点触发部分复制流程3、错误,可能是2.8以下版本不支持psync命令,从节点将发送sync触发全量同步
4、psync命令
数据同步原理
一般用于初次复制场景,如果数据量较大会对主从节点间的网络产生很大影响Redis2.8之前只有全量复制
使用psync进行全量复制的过程
1、从节点发送psync -1
2、主节点解析发现是全量复制命令,则回复+FULLRESYNC响应
3、从节点接收响应数据并保存运行ID和偏移量offset
4、主节点开始执行bgsave保存RDB文件到本地
这里需要注意如果文件过大可能会导致总时间超过repl-timeout所配置的值(默认60秒)(也依赖网络情况)一旦超过repl-timeout从节点将放弃接收RDB文件并清理已经下载的临时文件;如果数据量较大(比如超过6G)则需要调大repl-timeout的值才可以;否则从节点会再次发起同步请求造成复制风暴
为了降低主节点磁盘开销,可以开启无盘复制,生成的RDB文件不保存磁盘直接通过网络发给从节点
通过repl-diskless-sync参数控制,默认关闭
适用场景:磁盘性能较差但网络带宽较充裕的情况下
无盘复制
5、主节点发送RDB文件给从节点,从节点接收RDB文件并保存作为从节点数据文件
全量同步失败日志如下:M 27 May 12:13:33.669 # Client id=2 addr=127.0.0.1:24555 age=1 idle=1 flags=Sqbuf=0 qbuf-free=0 obl=18824 oll=21382 omem=268442640 events=r cmd=psyncscheduled to be closed ASAP for overcoming of output buffer limits.
如果写操作很多的话有可能会导致复制客户端缓冲区溢出默认配置为 client-output-buffer-limit slave 256MB 64MB 6060秒内缓冲区消耗持续大于64MB或者直接超过256M时,主节点将直接关闭复制客户端连接,造成全量同步失败
对于主节点,当发送完所有数据后就认为全量复制完成了
6、在从节点接收RDB快照期间,主节点可以继续响应读写命令,主节点会把这期间的写命令保存在复制客户端缓冲区内当从节点加载完RDB后,主节点再把缓冲区内的数据发送给从节点,保证主从之间数据一致性。
16:24:02.234 * MASTER <-> SLAVE sync: Flushing old data
7、从节点接收完主节点传过来的全部数据的时候会清空自身旧数据
因为在读写分离场景下,从节点还负责响应读命令;此时可能会出现数据过期或者错误的问题
8、从节点清空数据后会进行加载RDB文件,对于较大的RDB文件这一步是比较耗时的
9、从节点成功加载完RDB后,如果当前节点开启了AOF持久化功能,则会立即开始做bgrewriteaof操作
全量复制过程
主节点bgsave时间
RDB文件网络传输时间
从节点清空数据时间
从节点加载RDB时间
可能的AOF时间
全量复制是非常耗时费力的操作
全量复制特点
全量复制
1、主从节点网络中断超过repl-timeout时间,主节点会认为从节点故障并中断复制连接
2、主节点继续响应命令,并将写命令写入到复制积压缓冲区,默认最大缓存1MB(可以通过repl-backlog-buffer进行设置)
3、当主从节点恢复网络后,从节点会再次连上主节点
4、从节点发送psync {runId} {offset}给主节点,主节点返回+CONTINUE进行部分复制。
5、主节点根据偏移量把复制积压缓冲区里的数据发送给从节点
具体步骤
如果网络断开时间很长或者写入数据很大将从节点保存的offset冲没了怎么办?会进行全量复制吗?是的,会
问题:
用于处理在主从复制中因网络闪断等原因造成的数据丢失场景,当从节点再次连上主节点后,如果条件允许,主节点会补发丢失数据给从节点。
部分复制
数据同步psync命令
其中最后cmd应该是说该客户端最后执行的命令
2、主节点默认每隔10s对从节点发送ping命令,从而判断从节点的存活性和连接状态可以通过repl-ping-slave-period进行修改
主节点根据replconf命令判断从节点超时时间,体现在info replication统计中的lag信息中,lag表示与从节点最后一次通信延迟的秒数,正常延迟应该在0和1之间。如果超过repl-timeout配置的值(默认60秒),则判定从节点下线并断开复制客户端连接。
3、从节点在主线程中每隔1秒发送replconf ack {offset}命令,给主节点上报自身当前的复制偏移量
主从心跳判断机制
心跳
主节点不但负责数据读写,还负责把写命令同步给从节点。写命令的发送过程是异步完成,也就是说主节点自身处理完写命令后直接返回给客户端,并不等待从节点复制完成
offset是从节点的值,master_repl_offset是主节点的值,两者的差值是当前从节点的复制延迟量
由于主从复制过程是异步的,就会造成从节点的数据相对主节点存在延迟。具体延迟多少字节,我们可以在主节点执行info replication命令查看相关指标获得。
异步复制
当关闭时,主节点产生的命令数据无论大小都会及时的发送给从节点,这样主从延迟变小,但增加了网络带宽的消耗。适用于同机架或同机房部署的情况下。
当开启时,主节点会合并较小的TCP数据包从而节省带宽。默认发送时间间隔取决于Linux的内核,一般默认为40毫秒。这种配置节省了带宽但增大了主从之间的延迟。使用于跨机房部署。
repl-disable-tcp-nodelay控制是否关闭TCP_NODELAY默认关闭
传输延迟
复制原理
对于读占比较高的场景,可以通过把一部分读流量分摊到从节点(slave)来减轻主节点(master)压力,同时需要注意永远只对主节点执行写操作
因为主从复制是异步操作,所以这是不可平避免的
解决方案:使用集群模式做水平扩展来规避从节点读操作
复制数据延迟
主节点每次处理读取命令时,都会检查键是否超时,如果超时则执行del命令删除键对象,之后del命令也会异步发送给从节点。
惰性删除
Redis主节点在内部定时任务会循环采样一定数量的键,当发现采样的键过期时执行del命令,之后再同步给从节点
定时删除
redis维护了两种过期数据删除策略
读到过期数据
从节点故障
使用从节点进行读可能会存在的问题
读写分离
待补充
主从配置不一致
第一次建立复制,无可避免,可以选择在业务低峰期进行
从架构上避免,比如采用故障转移(使用哨兵模式或者集群模式)
运行ID不一致导致的比如主节点重启后运行ID就变了
调大repl_backlog_size,默认是1Mrepl_backlog_size>net_break_time*write_size_per_minutenet_break_time网络断网时间 write_size_per_minute每分钟写入数据大小
复制积压缓冲区不足
规避全量复制
一个主节点挂了多个从节点,针对RDB快照redis做了优化会共享一份RDB文件,但同时给多个从节点发送数据会加剧主节点机器的网络开销
采用树形结构
优点:增加了一个中间层,减少了主节点的压力
缺点:运维复杂度高
解决方案
1、单主节点复制风暴
应该把主节点尽量分散在多台机器上,避免在单台机器上部署过多的主节点。
当主节点所在机器故障后提供故障转移机制,避免机器恢复后进行密集的全量复制。(比如哨兵模式或者集群模式)
2、单机器复制风暴
复制风暴是指大量从节点对同一主节点或者对同一台机器的多个主节点短时间内发起全量复制的过程。复制风暴对发起复制的主节点或者机器造成大量开销,导致CPU、内存、带宽消耗。
规避复制风暴
开发与运维中的问题
复制
哨兵模式介绍
哨兵选举规则
故障转移流程
Sentinel哨兵模式
Redis Cluster概念
分区规则
虚拟槽分区
集群通讯Gossip协议
集群重定向
Cluster集群模式
部署方式
RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。
阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。
save命令
Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。
显然bgsave是对save命令的优化,save命令已经废弃
bgsave命令
手动触发
1、save相关配置save m n 在m秒内有n次修改即自动触发bgsave
2、从节点执行全量复制的时候,主节点自动执行bgsave生成RDB文件
3、执行debug reload命令的时候,自动触发
4、执行shutdown命令的时候,如果没有开启AOF则自动触发bgsave
自动触发
触发方式
可以通过info stats命令查看latest_fork_usec,查看最后一次fork子进程的时候花费的微妙数
最后一次生成RDB文件的时间可以通过info统计的rdb_last_save_time选项
执行流程
1、加载快,在做数据恢复时加载RDB要比AOF要快,AOF需要回放每一条命令
1、需要对内存整体做一个快照,如果内存很大则占用时间较长,快照的频率不好把控
缺点
RDB持久化
AOF内文件内容如下:set testkey testvalue *3 (当前命令有三部分组成,每一部分都由$+数字组成,这个数字表示字节)$3(后边紧跟的set是三个字节)set$7testkey$9testvalue
AOF里面记录的是每一条执行的写命令
虽然AOF避免了对当前命令的阻塞但可能会导致下一个操作的阻塞。因为AOF日志是在主线程操作的,当磁盘写入压力大的时候,就会导致磁盘慢,导致后续的操作出问题
同步写回,每个写命令执行完立马同步将日志写回磁盘
1、Always
每秒写回,先把日志写到AOF文件的内存缓存页,每隔一秒把缓冲区的内容写入磁盘
2、Everysec
操作系统控制写回,先把日志写到AOF文件的内存缓存页,由操作系统决定何时将缓冲区内容写回磁盘
3、No
AOF的三种写回策略
AOF持久化
持久化方法
故障恢复加载顺序
CopyOnWrite
Redis持久化
弱事务性
Redis客户端一条命令执行的4个步骤
Redis客户端一条命令执行分4个步骤
1、设置慢查询阈值,单位微妙(1秒=1000毫秒,1毫秒=1000微妙)slowlog-log-slower-than,默认是10毫秒
2、设置慢查询日志条数slowlog-max-len,默认128,如果队列满了采用先进先出的策略
redis慢查询参数配置
redis慢查询信息解读
Redis客户端一条命令执行分4个步骤:1、发送命令2、排队3、执行命令(redis慢查询统计是算的这里的时间)4、返回结果
客户端timeout时间设置的是1234加起来的时间吗?
执行过程
慢查询
redis
收藏
0 条评论
回复 删除
下一页