Redis-复制
概要:
背景及redis加密升级方案讨论
redis复制原理
--------------------------------------------------------------------------------------------
一、背景
工作中,由历史原因使用的redis(版本2.8)集群是无密码的,因此需要进行密码升级。
单单谈redis,设置密码其实很简单,设置redis的masterauth和requireauth然后修改config文件新增密码重启即可。
但是如何在生产环境中做平滑的加密设置呢?
二、讨论方案
在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,满足故障恢复和负载均衡等需求。
我们使用的集群结构如下:
可能上来想就直接设置呗,设置中发现,设置密码会触发复制机制。(后面详述)
那么那些方案呢?
1、切空集群,互倒。冷操作
再准备一套类似结构的集群,设置密码,搞一套带有密码的空集群,然后将线上流量切向这个集群,在去设置原线上的这组redis集群。但是实际上,redis集群的缓存数据很大,直接切向空redis会导致新请求流量打向DB,然后触发回写。虽然DB是加锁访问,如果流量一致大的情况,势必对DB (DB数据已经是分库分表)造成压力。这是不可估量的,这种风险只能是没有退路所选择的下策方案。
优:操作简单,完成密码设置完全在无线上流量后的集群操作
劣:资源要充足。
边界:请求流量不大时,数据在请求不足对库造成压力。实现回源redis;
边界补充:如果公司已经存在了数据迁移组件(平滑的将DB数据刷新到空集群,然后在做了完整的数据对比等综合考虑,在进行切换也是可行的。)一般会考虑托复制的方式
2、利用redis复制特点,切换隔离操作
基于现有结构,采用切预案【如切右3写右4读】然后进行断复制【断右2右3】、设置无流量请求分支的密码,在挂复制【master挂右5】,再进行切预案【原始预案】断复制【断右5和master】,设置无流量请求分支密码,再次挂复制【右3挂右2】的方式将集群进行加密。
优:缓存可用,不影响DB
劣:操作复杂
三、思考-redis复制原理
为什么不能直接在集群中直接设置密码呢?操作及现象:
- 设置masterauth密码,slave的节点执行masterauth,和顺序无关。
- 设置requirepass密码。如果从master节点开始设置,其slave会进行全量复制。
- 如果从slave开始设置,日志:“Unable to AUTH to MASTER: -ERR Client sent AUTH, but no password is set”
如果要理解为什么发生上述问题,需要知晓redis的复制触发情况,因此将从四个方面探究redis复制:
复制的使用方式、支持的拓扑结构、复制原理、问题
①、复制的使用方式
1、建立复制
参与复制的redis实例划分为主节点(master)和从节点(slave)。默认情况下,redis都是主节点。每个从节点只能有一个从节点,而主节点可以同时具有多个从节点。复制的数据是单向的、只能由主节点复制到从节点。Slaveof命令从节点发起。
配置方式有三种:
1、在redis.conf文件中配置slaveof <masterip> <masterport>选项,然后指定该配置文件启动Redis生效。
2、在redis-server启动命令后加上--slaveof <masterip> <masterport>启动生效。
3、直接使用 slaveof <masterip> <masterport>命令在从节点执行生效。
slaveof是异步命令,执行slaveof命令时,节点只保存主节点信息后返回,后续复制流程在节点内部异步执行。
2、断复制
执行slaveof no one。方式同上。
1、节点接收命令,断开与主节点复制关系。
2、从节点晋升为主节点。
从节点断开复制关系不会抛弃原有数据,只是无法再获取主节点上的数据变化。
通过slaveof命令还可以实现切主操作,只是相当于切换了另一个主。操作流程:
1、断开与旧主节点复制关系;
2、与新主节点建立复制关系;
3、删除从节点当前所有数据;
4、对新主节点进行复制操作。
3、安全性
密码:主节点通过设置requirepass参数进行密码验证,这时所有的客户端访问必须使用auth命令实行校验。从节点与主节点的复制连接是通过一个特殊标识的客户端来完成,因此需要配置从节点的masterauth参数与主节点密码保存一致,这样从节点才可以正确地连接到主节点并发起复制流程。
只读:默认情况下,从节点使用slave-read-only=yes配置为只读模式。由于复制是单向的,对从节点的任何修改主节点都无法感知,修改从节点会造成主从数据不一致。