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