玩转Redis的高可用(主从、哨兵、集群)
所谓的高可用,也叫 HA(High Availability),是分布式系统架构设计中必须考虑的因素之一,它是保证系统SLA的重要指标。Redis 高可用的主要有三种模式: 主从模式 , 哨兵模式和集群模式 。
Redis 提供了 Redis 提供了复制(replication)功能,当一台 redis 数据库中的数据发生了变化,这个变化会被自动地同步到其他的 redis 机器上去。
Redis 多机器部署时,这些机器节点会被分成两类,一类是主节点(master 节点),一类是从节点(slave 节点)。一般 主节点可以进行读、写操作 ,而 从节点只能进行读操作 。一个主节点可以有多个从节点,但是一个从节点只会有一个主节点,也就是所谓的 一主多从结构 。
· 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离;
· Master 是以非阻塞的方式为主 Slaves 提供服务。所以在 Master-Slave 同步期间,客户端仍然可以提交查询或修改请求;
· Slave 同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis 则返回同步之前的数据。
· Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的 IP 才能恢复;
· 主机宕机,宕机前有部分数据未能及时同步到从机,切换 IP 后面还会引入数据不一致的问题,降低了系统的可用性;
· Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂;
· Redis 的主节点和从节点中的数据是一样的,降低的内存的可用性
实际生产中,我们优先考虑哨兵模式。这种模式下,master 宕机,哨兵会自动选举 master 并将其他的 slave 指向新的 master。
在主从模式下,redis 同时提供了哨兵命令 redis-sentinel ,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵进程向所有的 redis 机器人发送命令,等待 Redis 服务器响应,从而监控运行的多个 Redis 实例。一般为了便于决策选举,使用 奇数个哨兵 。多个哨兵构成一个哨兵集群,哨兵直接也会相互通信,检查哨兵是否正常运行,同时发现 master 战机哨兵之间会进行决策选举新的 master
哨兵模式的作用:
· 通过发送命令,让 Redis 服务器返回监控其运行状态,包括主服务器和从服务器;
· 然而一个哨兵进程对 Redis 服务器进行监控,也可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多种哨兵模式。
哨兵很像 kafka 集群中的 zookeeper 的功能。
· 哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。
· 主从可以自动切换,系统更健壮,可用性更高。
· 具有主从模式的缺点,每台机器上的数据是一样的,内存的可用性较低。
· Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。
Redis 集群模式本身没有使用一致性 hash 算法,而是使用 slots 插槽 。
Redis 哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在 redis30 上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,对数据进行分片,也就是说每台 Redis 节点上存储不同的内容;每个节点都会通过集群总线(cluster bus),与其他的节点进行通信。 通讯时使用特殊的端口号,即对外服务端口号加 10000。例如如果某个 node 的端口号是 6379,那么它与其它 nodes 通信的端口号是 16379。nodes 之间的通信采用特殊的二进制协议。
对客户端来说,整个 cluster 被看做是一个整体,客户端可以连接任意一个 node 进行操作,就像操作单一 Redis 实例一样, 当客户端操作的时候 key 没有分配到该 node 上时,Redis 会返回转向指令,指向正确的 node,这有点儿像浏览器页面的 302 redirect 跳转。
根据官方推荐,集群部署至少要 3 台以上的 master 节点,最好使用 3 主 3 从六个节点的模式。
在 Redis 的每一个节点上,都有这么两个东西, 一个是插槽(slot),它的的取值范围是:0-16383, 可以从上面 redis-tribrb 执行的结果看到这 16383 个 slot 在三个 master 上的分布。还有一个就是 cluster,可以理解为是一个集群管理的插件,类似的哨兵。
当我们的存取的 Key 到达的时候,Redis 会根据 crc16 的算法对计算后得出一个结果,然后把结果和 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
为了保证高可用, redis-cluster 集群引入了主从模式 ,一个主节点对应一个或者多个从节点。当其它主节点 ping 主节点 master 1 时,如果半数以上的主节点与 master 1 通信超时,那么认为 master 1 宕机了,就会启用 master 1 的从节点 slave 1,将 slave 1 变成主节点继续提供服务。
如果 master 1 和它的从节点 slave 1 都宕机了,整个集群就会进入 fail 状态,因为集群的 slot 映射不完整。 如果集群超过半数以上的 master 挂掉,无论是否有 slave,集群都会进入 fail 状态。
redis-cluster 采用去中心化的思想 ,没有中心节点的说法,客户端与 Redis 节点直连,不需要中间代理层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
对 redis 集群的扩容就是向集群中添加机器,缩容就是从集群中删除机器,并重新将 16383 个 slots 分配到集群中的节点上(数据迁移)。
扩缩容也是使用集群管理工具 redis-trirb。
扩容时,先使用 redis-trirb add-node 将新的机器加到集群中,这是新机器虽然已经在集群中了,但是没有分配 slots,依然是不起做用的。在使用 redis-trirb reshard 进行分片重哈希(数据迁移),将旧节点上的 slots 分配到新节点上后,新节点才能起作用。
缩容时,先要使用 redis-trirb reshard 移除的机器上的 slots,然后使用 redis-trirb add-del 移除机器。
采用去中心化思想,数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布;
可扩展性:可线性扩展到 1000 多个节点,节点可动态添加或删除;
高可用性:部分节点不可用时,集群仍可用。通过增加 Slave 做 standby 数据副本,能够实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave 到 Master 的角色提升;
降低运维成本,提高系统的扩展性和可用性。
1Redis Cluster 是无中心节点的集群架构,依靠 Goss 协议(谣言传播)协同自动化修复集群的状态。但 GosSIp 有消息延时和消息冗余的问题,在集群节点数量过多的时候,节点之间需要不断进行 PING/PANG 通讯,不必须要的流量占用了大量的网络资源。虽然 Reds40 对此进行了优化,但这个问题仍然存在。
2数据迁移问题
Redis Cluster 可以进行节点的动态扩容缩容,这一过程,在目前实现中,还处于半自动状态,需要人工介入。在扩缩容的时候,需要进行数据迁移。
而 Redis 为了保证迁移的一致性,迁移所有操作都是同步操作 ,执行迁移时,两端的 Redis 均会进入时长不等的阻塞状态,对于小 Key,该时间可以忽略不计,但如果一旦 Key 的内存使用过大,严重的时候会接触发集群内的故障转移,造成不必要的切换。
主从模式:master 节点挂掉后,需要手动指定新的 master,可用性不高,基本不用。
哨兵模式:master 节点挂掉后,哨兵进程会主动选举新的 master,可用性高,但是每个节点存储的数据是一样的,浪费内存空间。数据量不是很多,集群规模不是很大,需要自动容错容灾的时候使用。
集群模式:数据量比较大,QPS 要求较高的时候使用。 Redis Cluster 是 Redis 30 以后才正式推出,时间较晚,目前能证明在大规模生产环境下成功的案例还不是很多,需要时间检验。
在现有企业中80%公司大部分使用的是redis单机服务,在实际的场景当中单一节点的redis容易面临风险。
面临问题
解决办法
要实现分布式数据库的更大的存储容量和承受高并发访问量,我们会将原来集中式数据库的数据分别存储到其他多个网络节点上。
什么是主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
主从复制的作用
主从复制启用
从节点开启主从复制,有3种方式:
主从复制过程大体可以分为3个阶段:连接建立阶段(即准备阶段)、数据同步阶段、命令传播阶段。
在从节点执行 slaveof 命令后,复制过程便开始运作,下面图示大概可以看到,
从图中可以看出复制过程大致分为6个过程
1)保存主节点(master)信息。
执行 slaveof 后 Redis 会打印如下日志:
2)从节点(slave)内部通过每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与该节点建立网络连接
从节点与主节点建立网络连接
从节点会建立一个 socket 套接字,从节点建立了一个端口为51234的套接字,专门用于接受主节点发送的复制命令。从节点连接成功后打印如下日志:
如果从节点无法建立连接,定时任务会无限重试直到连接成功或者执行 slaveof no one 取消复制
关于连接失败,可以在从节点执行 info replication 查看 master_link_down_since_seconds 指标,它会记录与主节点连接失败的系统时间。从节点连接主节点失败时也会每秒打印如下日志,方便发现问题:
3)发送 ping 命令。
连接建立成功后从节点发送 ping 请求进行首次通信,ping 请求主要目的如下:
·检测主从之间网络套接字是否可用。
·检测主节点当前是否可接受处理命令。
如果发送 ping 命令后,从节点没有收到主节点的 pong 回复或者超时,比如网络超时或者主节点正在阻塞无法响应命令,从节点会断开复制连接,下次定时任务会发起重连。
从节点发送的 ping 命令成功返回,Redis 打印如下日志,并继续后续复制流程:
4)权限验证。如果主节点设置了 requirepass 参数,则需要密码验证,从节点必须配置 masterauth 参数保证与主节点相同的密码才能通过验证;如果验证失败复制将终止,从节点重新发起复制流程。
5)同步数据集。主从复制连接正常通信后,对于首次建立复制的场景,主节点会把持有的数据全部发送给从节点,这部分操作是耗时最长的步骤。
6)命令持续复制。当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。
答案:A
A、正确。客户机/服务器环境(主从式环境)下的客户端程序分散在各个客户机中,当升级应用程序版本时,必须保证版本在全网络上的同步,否则旧版的客户程序可能不能正常工作甚至影响到服务器中的数据。而在大型机环境(主机环境)下应用程序集中存放在主机中,只需升级主机中的程序即可。B、不正确。客户机/服务器环境和大型机环境都必须制定程序紧急改动的条文规定并要求遵守执行。C、不正确。两种环境下都要求用户参与程序改变测试。D、不正确。两种环境下从测试资料库到成品资料库的传送都应受到控制。
一. 准备服务器
准备两台主机,分别安装好Mysql (要相同版本),确定版本无误,确保mysql服务正常启动,确保两台主机处于同一个局域网中,确定好哪台做为主、备机器,假设A为主机,B为备机,假设:
A主机IP地址为:172161690 端口3306
B主机IP地址为: 172169998 端口3306
二. Mysql建立主-从服务器热备配置步骤
1 创建同步用户
进入MySql操作界面,在主服务器上为从服务器建立一个连接帐户,该帐户必须授予REPLICATION SLAVE权限。
操作指令如下:
1) grant select,replication slave on to 'replicate'@'172169998' identified by '1234567';
2) flush privileges;
2 修改Mysql配置
如果上面的准备工作做好,就可以进行对Mysql配置文件进行修改了,首先找到主服务器Mysql安装文件所有在目录,找到myini文件用记事本打开。在[mysqld]下增加如下内容:
server-id = 1
log-bin=mysql-bin
binlog-do-db =test #需要备份的数据库,多个写多行
binlog-ignore-db = mysql #不需要备份的数据库,多个写多行
3 重启mysql服务
修改完配置文件保存后,重启一下mysql服务。
4 查看主服务器状态
进入A服务器Mysql 客户端输入命令
1)Show master STATUS;
2)返回结果如下:
注意看里面的参数,特别前面两个File和Position,在从服务器(Slave)配置主从关系会有用到的。
5 从服务器Slave配置修改配置文件
因为这里面是以主-从方式实现mysql双机热备的,所以在从服务器就不用在建立同步帐户了,直接打开配置文件myini进行修改即可,道理还是同修改主服务器上的一样,只不过需要修改的参数不一样。
如下:
[mysqld]
server-id = 2
log-bin=mysql-bin
replicate-do-db = test
replicate-ignore-db =mysql
6 重启mysql服务
修改完配置文件保存后,重启一下mysql服务。
7 配置从服务器
先停止slave服务线程,这个是很重要的,如果不这样做会造成下面操作不成功,再用change mster 语句指定同步位置,操作如下:
1) stop slave;
2) change master to master_host='172161690',
master_user='replicate',master_password='1234567',master_port=3306,
master_log_file='mysql-bin000001',master_log_pos=98;
3) start slave
4) show slave status
查看下面两项值均为Yes,即表示设置从服务器成功。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
0条评论