目录
分布式系统
引子
1.在分布式之前的结构都是单点结构,所谓单点指的是一个服务器程序或者一个主机.
2.单点结构会出现问题:可用性问题,如果当前运行的机器突然挂了,那么服务就会中断.更严重的数据可能都全丢失了 ; 性能问题,在高并发量的条件是运行不了的,比较单点结构的并发量是有限的
3.引入分布式结构就是为了解决上面的两问题.在分布式系统中,有多个服务器部署redis服务,使其形成了redis集群,那么就可以让这个集群给整个分布式系统的其他服务提供稳定高效的数据存储
分布式系统类型
类型:1.主从模式 2.主从+哨兵模式 3.集群模式
主从模式
定义:在若干个redis节点中,一部分主节点,有一些作为从节点.从节点上的数据是根据主节点的变化而变化的,从节点要和主节点的数据保持一致.即主节点的数据复制到从节点中,主节点能够进行修改,那么从节点也需要跟主节点保持一致,而从节点不能自己主动改变,只被运行读取数据
作用:引入了更多的计算资源,自然就能支持更多的并发量
一个主节点和多个从节点
1.此时的数据存在多份,所以客户端来读取数据可以在任意一个节点中读取,随后为这个客户端提供服务.
2.这样的好处其实显而易见,本来一个节点的并发量是有限的,多节点好处就分担了部分的并发量,使得支持更多的并发进行.
3.如果从节点挂掉了,那么其实不影响其他节点的读取,我们从其他节点上读取的效果是一样的,所以会出现多服务器多地点放置的情况,就是为了避免服务器集体挂掉导致服务器业务不能进行执行
4.如果主节点挂掉了,那么该集群就失去了写数据的操作,因为主节点只有一个.不过对于读取数据是没有影响的,因为所谓的读取在从节点也是一样的
5.此外,对于大部分的数据都是以读数据为主,写操作比读数据要少很多
6.主从结构下,读操作进行了并发量和可用性的提高;而写操作依赖主节点,主节点不能搞多,因为写数据会使得多主节点出现麻烦数据同步问题
创建多个节点方法
1.多个主机启动redis服务,该模式就是企业常见的
2.一个主机上打开多个redis服务.该模式需要生成多个配置文件,并且在文件中设置不同的port,直连即可
配置主从结构
1. 在配置⽂件中加⼊slaveof{masterHost}{masterPort}随Redis启动生效
2. 在redis-server启动命令时加⼊--slaveof{masterHost}{masterPort}生效
3. 直接使⽤redis命令:slaveof{masterHost}{masterPort}生效主从模式知识
1.如果是redis-server启动的,停止服务使用kill -9,不过此时的redis不会重启.而service redis-server start启动的,kill -9将会重启redis,而service redis-server stop直接停止服务
2.而服务器需要高可用和稳定性,那么服务器的某些程序可能会出现挂掉的情况,那么就需要立即自动重启进程,对于整体的服务不会产生严重的影响.这需要另外的进程监控服务器进程状态
3.一旦配置成功,我们能查看网络情况.此时我们知道从节点与主节点建立tcp连接
4.从节点的数据与主节点同步,不过从节点没有修改数据的能力
5.info replication查看主从节点的情况
主节点 6379
127.0.0.1:6379> info replication # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6380,state=online,offset=100,lag=0 master_replid:2fbd35a8b8401b22eb92ff49ad5e42250b3e7a06 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:100 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:100
从节点 6380
127.0.0.1:6380> info replication # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:170 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:2fbd35a8b8401b22eb92ff49ad5e42250b3e7a06 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:170 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:170
1)relo表示主从的身份,需要注意的是从节点可以挂从节点但是从节点的身份不能是主节点
2)connected_slaves当前节点拥有的从节点个数,slaveX从节点ip和port
3)master_replid:主节点id
4)offset:同步数据的进度
5)repl_backlog_active/size/first_byte_offset/histlen为积压缓冲区,支持部分同步机制
主从复制
1.主从复制的顺序是由主给从数据,虽然配置中允许从节点对数据进行修改,但是这样的数据主节点感知不到,数据就不一致了,这种做法不推荐
2.主从节点之间是通过TCP传输的,所以一定涉及网络带宽.TCP内部支持nagle算法,该算法开启会增加tcp传输延迟.增加延迟节省带宽数据不同步的概率变高,而减少带宽会增加带宽数据同步的概率变高.该指令为:repl-disable-tcp-nodelay,针对从节点进行设置.其原理就是对小的tcp数据包进行合并,使得减少包的传输次数
拓扑结构
1.一主一从
1.主节点读写数据,从节点读数据.
2.如果写数据过多就会对主节点一些压力,此时需要通过关闭主节点的AOF节省,只能在从节点上开启AOF
3.而这样做的缺点也是存在的,一旦主节点挂了,数据就不存在了,那么此时主节点不能立马重启,重启就会把从节点的数据冲掉,需要从从节点那里获取AOF再启动
2.一主多从
1.实际开发中,读请求要远超写请求,所以我们需要扩展从节点的并发量,所以需要更多从节点
2.不过一对多其实也有缺点,因为主节点修改数据时,需要对所有的从节点同步数据,主从是通过tcp通信的,那么就会花费带宽
3.树形主从
这样主节点就不需要很高的网络带宽了,但是与此同时从节点也要同步数据,所以所有数据同步会延时
主从实现原理
1.保存主节点IP和PORT
2.建立tcp连接,保证通信正常
3.发送ping给主节点收到pong.确保主节点的应用层时正常工作的
4.redis若设置了密码,那么就需要对比权限
5.全量同步,主从开启的那一刻所有指令
6.增量同步,之后变化的指令
psync数据同步
1.redis使用psync进行数据同步.其语法格式为 psync replicationid offset.该指令会自动进行同步,当然也可以手动设置
2.info replication可以获得replicationid
3.master_replid有两个.一般master_replid2用不上,因为当形成主从结构时,从节点的master_replid1就是主节点的replid,而master_replid2就会闲置下来不需要使用.
4.而主从节点进行通信时,发生了网络抖动,那么从节点就会认为主节点挂了,主节点挂了master_replid1就会自指,从节点自己成为主节点.而master_replid2保存曾经的主节点,网络稳定从节点可根据master_replid2找到之前的主节点,不过需要主动干预的哨兵机制完成
5.offset是主从节点维护数据的偏移量(整数),主节点的偏移量变更就说明主节点收到了修改数据的操作;而从节点的偏移量就是为了描述与主节点之间数据同步到哪个地方了.从节点每秒都会上报自身的offset与主节点同步
6.psync可同步全部数据或者部分数据,offset为-1表示同步所有数据;而为某正整数就是部分同步
全量复制和部分复制
1.psync是从节点主动给主节点发送的请求,请求数据数据同步
2.psync的数据同步用三种结果:FULLRESYNC表示全量数据同步,CONTINUE表示增量数据同步,ERR表示当前redis版本不支持psync,版本太老了,使用sync
3.全量复制的进行条件:首次和主节点进行数据同步 ; 主节点不方便进行部分复制时也会使用
4.部分复制的进行条件:从节点已经复制过主节点的数据,而网络波动或者从节点重启了,需要进行部分复制 ; 从节点需要重新在主节点处进行数据同步,此时策略是看看能否部分复制减少不必要的开销
psync流程
1.全量数据同步
流程
1.从节点发送psync ? -1请求,即需要主节点全局复制
2.主节点根据命令,解析出需要全量复制,回复 +FULLRESYNC 的响应
3.从节点接收主节点信息后并且保存
4.主节点进行rdb文件持久化.不可以使用原有的rdb,必须重新再生成一份,因为需要可靠的更新后的数据
5.主节点将rdb文件传送给从节点.之所以传送rdb文件而不是aof文件是因为rdb文件是二进制的方便传输
6.主节点将生成rdb文件时执行的其他命令写入缓冲区中,rdb保存后,将缓冲区数据传给从节点
7.从节点清空原本数据
8.从节点加载rdb文件与主节点数据保持一致
9.查看是否开启aof,如果开启需要对aof的冗余日志进行合并
无硬盘模式
1.主节点生成的rdb文件不保存,而是直接传给从节点(省下了一系列读硬盘和写硬盘的操作)
2.从节点直接将收到的rdb文件加载,而不保存再解析.(省下了读硬盘和写硬盘的操作)
3.但是只要主节点的数据多,无可避免网络传输的全量复制耗时
2.部分数据同步
部分数据同步出现的场景就是从节点网络波动之后又和主节点重新连接上
1.当主从节点发生网络波动而中断,如果超过repl-timeout时间,主节点会认为从节点故障并且终端复制连接
2.此时中断了数据的更新.而主节点依然响应命令,并且将命令都复制到repl-backlog-buffer的积压缓冲区中.
3.主从节点网络恢复,并且重新连接
4.从节点发送原来的 replicationid和offset 给主节点进行解析,请求部分复制 (这里需要注意的是:replicationid如果与原先不一样,说明不是之前的主节点,出发全量复制;replicationid相同,但是所谓的offset跟不上,也会重传.因为积压缓冲区是一个环形队列,其大小是有限制的,那么一旦更新的数据来,旧的就会被覆盖掉,那么offset就会不包含旧一点的数据,需要重新全量复制.)
5.接受到后,发送 +CONTINUE 的响应表示部分复制
6.主节点对比offset将部分数据复制给从节点
3.实时拷贝
1.从节点需要和主节点进行实时同步.因为主从节点之间建立了TCP长连接,主节点将自己修改过的数据结果发送给从节点.
2.不过这个过程也需要时间.如果是树状的拓扑结构,那么就会使得更新全部节点的时间增加
3.实时拷贝是需要双方都为可以可用状态.那么需要引入心跳机制.主节点默认每隔10s给从节点发ping命令,而从节点发送回pong说明从节点没有被挂;而从节点默认每隔1s发送特定请求,汇报从节点的当前进度,是否需要与主节点更新
从节点变为主节点的情况
1.从节点与主节点主动断开,slaveof no one,此时从节点就升为主节点
2.主节点因为网络挂了,那么此时需要人工干预恢复主节点
主节点断开无法重连恢复
可能存在两种情况:
1.几个节点共用一个服务器的同时,共用了一个aof文件.此时需要重新设置不同的路径保存aof文件
2.服务器aof的权限用户不为redis也会出现这种情况,因为root启动的redis,一旦redi被攻击,后果不堪设想.