Fork me on GitHub

Redis主从同步,哨兵

Redis简介

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步

编译安装

1、下载redis安装包,下载地址:https://redis.io/download,选择安装的版本,即

wget http://download.redis.io/releases/redis-4.0.14.tar.gz

2、 解压并编译安装

#解压
tar -xvf redis-4.0.14.tar.gz
#安装
cd redis-4.0.14
make PREFIX=/usr/local/redis install   

3、复制配置文件至redis安装目录

cp redis-4.0.14/redis.conf  /usr/local/redis/redis.conf
cp redis-4.0.14/sentinel.conf  /usr/local/redis/sentinel.conf  

环境

192.168.1.49 master 6379 sentinel1 26379
192.168.1.63 slave1 6380 sentinel2 26380
192.168.1.144 slave2 6381 sentinel3 26381

主从同步(master-slave)

Redis 支持简单且易用的主从复制(master-slave replication)功能

特点

Redis 复制功能的几个重要方面:

1、一个主服务器可以有多个从服务器。
2、不仅主服务器可以有从服务器, 从服务器也可以有自己的从服务器, 多个从服务器之间可以构成一个图状结构。
3、复制功能不会阻塞主服务器: 即使有一个或多个从服务器正在进行初次同步, 主服务器也可以继续处理命令请求。
4、复制功能也不会阻塞从服务器: 只要在 redis.conf 文件中进行了相应的设置, 即使从服务器正在进行初次同步, 服务器也可以使用旧版本的数据集来处理命令查询。
不过, 在从服务器删除旧版本数据集并载入新版本数据集的那段时间内, 连接请求会被阻塞。
你还可以配置从服务器, 让它在与主服务器之间的连接断开时, 向客户端发送一个错误。
5、复制功能可以单纯地用于数据冗余(data redundancy), 也可以通过让多个从服务器处理只读命令请求来提升扩展性(scalability): 比如说, 繁重的 SORT 命令可以交给附属节点去运行。
6、可以通过复制功能来让主服务器免于执行持久化操作: 只要关闭主服务器的持久化功能, 然后由从服务器去执行持久化操作即可。

简单搭建

1、修改配置redis.conf
1) master配置

protected-mode no
#允许远程访问
#bind 0.0.0.0
#protected-mode yes
port 6379

#设置密码
requirepass 123456
#哨兵监控主从切换时使用,否则无需配置
masterauth 123456

启动master如下图所示:
master

2) slave1配置

protected-mode no
#允许远程访问
#bind 0.0.0.0
#protected-mode yes

port 6380
slaveof 192.168.1.49

#master设置了密码,slave必须一致
masterauth 123456
#哨兵监控主从切换时使用,否则无需配置
requirepass 123456

启动slave1如下图所示:
slave1

3) slave2配置

protected-mode no
#允许远程访问
#bind 0.0.0.0
#protected-mode yes

port 6381
slaveof 192.168.1.49

#master设置了密码,slave必须一致
masterauth 123456
#哨兵监控主从切换时使用,否则无需配置
requirepass 123456

启动slave1如下图所示:
slave2

从服务器均启动后,在此查看主服务器:
master-slave

2、客户端连接测试
1)master服务器:
master-test
2)slave1服务器:
slave1-test
3)slave2服务器:
slave2-test

Redis持久化

redis支持两种方式的持久化,可以单独使用或者结合起来使用。
1、第一种:RDB方式redis默认的持久化方式(快照)
2、第二种:AOF方式(日志追加)

RDB快照模式(snapshot):

save 900 1  //900秒内如果超过1个key被修改,则发起快照保存
save 300 10 //300秒内容如超过10个key被修改,则发起快照保存
save 60 10000  //(这3个选项都屏蔽,则rdb禁用)

stop-writes-on-bgsave-error yes  // 后台备份进程出错时,主进程停不停止写入
rdbcompression yes      // 导出的rdb文件是否压缩
Rdbchecksum   yes       //导入rbd恢复时数据时,要不要检验rdb的完整性
dbfilename dump.rdb     //导出来的rdb文件名
dir /var/lib/redis/     //rdb的放置路径

AOF日志模式:

appendonly yes              //启用aof持久化方式
# appendfsync always        //每收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec        //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# appendfsync no            //完全依赖os,性能最好,持久化没保证(操作系统自身的同步)
no-appendfsync-on-rewrite  yes   //正在导出rdb快照的过程中,要不要停止同步aof
auto-aof-rewrite-percentage 100  //aof文件大小比起上次重写时的大小,增长率100%时,重写
auto-aof-rewrite-min-size 64mb   //aof文件,至少超过64M时,重写

注意:
1、AOF和RDB同时存在的时候,优先使用AOF恢复数据,因为AOF保存的数据集更完整;
2、AOF和RDB恢复的时候,RDB更快,直接拷贝数据,AOF还要执行语句;
3、建议同时使用AOF和RDB

哨兵(sentinel)

Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:

监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

简单搭建

1、修改配置sentinel.conf
sentinel1、sentinel2、sentinel3配置的不同之处在于端口号的不同

port 26379
#port 26380
#port 26381
logfile "/var/log/sentinel.log"
dir "/tmp"

protected-mode no
#允许远程访问
#bind 0.0.0.0
#protected-mode yes

#每个master设置有个不同的名字,后面的数字2,是指当有两个及以上的sentinel服务检测到master宕机,才会去执行主从切换的功能
#sentinel monitor <master-name> <ip> <redis-port> <quorum>
#<master-name> :redis主服务名称,可以自行命名,但是在一个sentinel网络中,一个redis主服务只能有一个名称;
#<quorum>的大小即: floor(N/2) + 1 <= quorum <= N (N为sentinel总数)
# 备注:允许远程访问时<ip>必须是外网(非内网)IP
sentinel monitor mymaster 192.168.1.49 6379 2
#设置监控的master和访问密码
sentinel auth-pass mymaster 123456
#在10s这个时间范围内不能接收响应,master将会被标记为故障。
sentinel down-after-milliseconds mymaster 10000
#执行故障转移的timeout超时时长,当前即判定超过20s即为超时
sentinel failover-timeout mymaster 20000

启动sentinel1、sentinel2、sentinel3,其中sentinel1如下图所示:
sentinel1

查看日志:

3811:X 08 Dec 11:21:40.014 # +monitor master mymaster 192.168.1.49 6379 quorum 2
3811:X 08 Dec 11:21:40.016 * +slave slave 192.168.1.63:6380 192.168.1.63 6380 @ mymaster 192.168.1.49 6379
3811:X 08 Dec 11:21:40.018 * +slave slave 192.168.1.144:6381 192.168.1.144 6381 @ mymaster 192.168.1.49 6379   

从对应的日志观察到,一个master服务,两个slave服务。我们现在来kill master服务的进程,再次查看日志:

3811:X 08 Dec 11:36:58.678 # +sdown master mymaster 192.168.1.49 6379
3811:X 08 Dec 11:36:58.761 # +odown master mymaster 192.168.1.49 6379 #quorum 2/2
3811:X 08 Dec 11:36:58.761 # +new-epoch 1
3811:X 08 Dec 11:36:58.762 # +try-failover master mymaster 192.168.1.49 6379
3811:X 08 Dec 11:36:58.767 # +vote-for-leader 76c7f7a57920c33cdf4d8139270569f79b6c304c 1
3811:X 08 Dec 11:36:58.768 # cf5188ad057e38bdc3f33b138528adf44fe84779 voted for 3dbd90731d504fec0b4e667f9034f07b120e7932 1
3811:X 08 Dec 11:36:59.892 # +config-update-from sentinel 3dbd90731d504fec0b4e667f9034f07b120e7932 192.168.1.144 26381 @ mymaster 192.168.1.49 6379
3811:X 08 Dec 11:36:59.893 # +switch-master mymaster 192.168.1.49 6379 192.168.1.63 6380 

此时slave1服务的状态(切换为新的master):
sentinel-slave1-to-master

此时slave2服务的状态:
sentinel-slave2

我们重启下原来主服务之后,已经切换为slave服务了,状态如下:
sentinel-master-to-slave

再次查看新的主服务(slave1切换为新服务)状态如下:
sentinel-master-to-slave

查看日志:
sentinel-log

注意事项:

1.如果停掉master 后,sentinel 显示足够数量的 sdown 后,没有出现odown或try-failover,则检查密码等配置是否正确
2.如果停掉master后,试图切换的时候出现failover-abort-not-elected
1)如果redis实例没有配置

protected-mode yes
#bind 0.0.0.0
bind 192.168.1.49

则在sentinel 配置文件加上

protected-mode no 

2)如果redis实例有配置

protected-mode yes
#bind 0.0.0.0
bind 192.168.1.49

则在sentinel配置文件加上

protected-mode yes
#bind 0.0.0.0
bind 192.168.1.49

3.开启redis安全模式,即设置protected-mode为yes,它启用的条件,需满足:

1) 没有bind IP
2) 没有设置访问密码

远程调用时,若出现如下error:

protocol error, got 'p' as reply type byte

则需注意:
1)是否设置bind 127.0.0.1
2)开启之后protected-mode,是否设置bind 0.0.0.0

轻轻的我走了,正如我轻轻的来