1. 基于主从+哨兵的集群模式

  1. 说明:
    由一主双从 + Sentinel哨兵集群(三个节点)实现的高可用。
    为保证可用性,需要三台机器。
  2. 适用场景:
    数据量不大、写入量少、扩展性要求不高
  3. 部署结构
  4. redis高可用性方案 redis生产环境下的高可用_redis

  5. 拓扑图
  6. redis高可用性方案 redis生产环境下的高可用_redis_02

  7. Redis主从安装部署说明:
    假定IP:
MASTER: 192.168.0.1
SLAVE1: 192.168.0.2
SLAVE2: 192.168.0.3

Redis的安装不做赘述,侧重讲解如何配置,这里主要列出差异性的配置:

1) 主节点(master)配置:

port 6379
bind 192.168.0.1
daemonize yes
pidfile /home/hadoop/redis/6379/redis.pid
logfile /home/hadoop/redis/6379/log/redis.log
dir /home/hadoop/redis/6379/data

2)从节点1(slave-1)配置

port 6380
bind 192.168.0.2
daemonize yes
pidfile /home/hadoop/redis/6380/redis.pid
logfile /home/hadoop/redis/6380/log/redis.log
dir /home/hadoop/redis/6380/data
slaveof 192.168.0.1 6379

3)从节点2(slave-2)配置

port 6381
bind 192.168.0.3
daemonize yes
pidfile /home/hadoop/redis/6381/redis.pid
logfile /home/hadoop/redis/6381/log/redis.log
dir /home/hadoop/redis/6381/data
slaveof 192.168.0.1 6379

主从依次启动三台服务节点: MASTER ->SLAVE1->SLAVE2

启动完成后, 通过命令检查服务是否正常启动:

ps -ef | grep redis-server

最后检查主从关系是否正常,进入redis控制台:

redis-cli -h 127.0.0.1 -p 6379

出现以下信息,代表一主双从的配置关系建立正常:

#RepLication
roLe:master
connected _sLaves: 2
slave0:ip=192.168.0.2, port=6380, state=onLine, offset=658, Lag= 0
slave1:ip=192.168.0.3, port=6381, state=online, offset=658, Lag= 0
master_replid:5c5e937e31c8cfa5142416011bca47902d2a1f34
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:658
second _repl_offset:-1
repL_backlog_active: 1
rept_backlog_size:1048576
repL_backLog_ first _byte_offset: 1
repl_backLog_histten:658
  1. Sentinel集群配置
    Sentinel集群不参与数据的处理, 主要作用是保障Redis主从节点的高可用, 在主节点出现故障时,能够自动实现切换。
    1)Sentinel节点配置
    依次在三台机器上做好配置, 注意端口不能填写错误, 示例:
    sentinel-26379.conf
#设置 sentinel 工作端口
port 26379
#后台运行 
daemonize yes
#日志文件名称
logfile "/home/hadoop/redis/26379/log/redis.log"
#设置当前 sentinel 监控的 redis ip 和 端口
sentinel monitor mymaster 192.168.0.1 6379 2
#设置判断 redis 节点宕机时间 (30秒)
sentinel down-after-milliseconds mymaster 30000
#设置自动故障转移超时(20秒)
sentinel failover-timeout mymaster 20000
#设置同时故障转移个数
sentinel parallel-syncs mymaster 1

2)启动Sentinel集群

有两种命令:

  1. redis-sentinel /path/sentinel.conf
  2. redis-server /path/sentinel.conf --sentinel

3)查看Sentinel集群状态

[root@redis]#redis-cli -h 192.168.0.1 -p 26379
192.168.0.1:26379>info sentinel
#Sentinel
sentinel_masters: 1
sentinel_tilt: 0
sentinel_running_scripts: 0
sentinel_scripts_queue_Length: 0
sentinel_simuLate_failure_fLags: 0
master0:name=mymaster, status=ok, address=192.168.0.1:6379, sLaves=2, sentinels=3

能够正常识别主节点,2个从节点和3个sentinel节点。

整体就完成了主从+哨兵的集群模式部署。可以自行验证,KILL Redis的主节点进程,对高可用进行测试。

2. Redis原生Cluster集群模式(推荐)

  1. 说明
    由多个主从节点群组成的分布式服务集群, 具有复制、高可用和分片特性。
    需要三台以上机器。
  2. 适用场景
    数据量大、写入量多、支持扩容。
  3. 部署结构
    搭建三个master节点、每个master主节点再配置两个slave节点、总共9个Redis节点。
  4. redis高可用性方案 redis生产环境下的高可用_redis高可用性方案_03

  5. 拓扑结构

redis高可用性方案 redis生产环境下的高可用_redis高可用性方案_04

  1. 安装部署说明
    ① 先在一台机器安装三个redis节点
    创建目录:
1.在每台机器Redis目录下, 创建redis-cluster文件夹
  mkdir redis-cluster
2.在redis-cluster文件夹下按照不同端口号创建三个文件夹
  mkdir 6379 6380 6381

② 修改三个redis节点的配置文件

将以下内容按照实际端口号与服务器IP替换:

10
port 端口号
bind 服务器IP
daemonize yes
cluster-enabled yes
pidfile /home/hadoop/redis-cluster/端口号/redis.pid
logfile /home/hadoop/redis-cluster/端口号/log/redis.log
dir /home/hadoop/redis-cluster/端口号/data

③ 启动redis,验证是否成功

[root@locaLhost redis] #ps -ef | grep redis
root 41340 12月02 00:06:26 ./bin/redis-server*: 6379[cluster]
root 413541 12月02 00:06:26 ./bin/redis-server*:6380[cluster]
root 1183090 10:54 00:00:08 ./bin/redis-server*:6381[cluster]

④ 其余两台机器按照redis节点

参照以上步骤执行。

⑤ 集群创建

1)先创建主节点:

假定三台机器IP为: 192.168.0.1、192.168.0.2、192.168.0.3,主节点端口为6379

redis-cli --cluster create 192.168.0.1:6379 192.168.0.2:6379 192.168.0.3:6379 --cluster-replicas 0

如果设定了密码, 需要加入-a参数。

2)再创建从节点:

先添加第一台从节点:192.168.0.2:6380

redis-cli --cluster add-node 192.168.0.2:6380 192.168.0.1:6379 --cluster-slave --cluster-master-id ***************

这里的master-id 为对应主节点的身份标识, 进入redis集群控制台,通过cluster nodes命令查看:

[root@had oop 2_bin] #:/redis-c1i-h 192.168.0.1 -p 6379
192.168.0.1:7000>c1uster nodes
d35a50c334f9b3b734191294838c3f86a80e9d73 192.168.0.1:6379@17000 myse1f,master -016406747240003 connected 5461-10922
5601505fdfFcbodbobf26e7df66dc3264c5834d6 192.168.0.2:6379@17000 master -016406747250005 connected 10923-16383
7835e24616839fc65ffa26583166bbb79c827c7a 192.168.0.3:6379@17000 master -016406747232771 connected 0-5460

192.168.0.1:6379主机点对应的ID标识为:d35a50c334f9b3b734191294838c3f86a80e9d73

再添加第二台从节点:192.168.0.3:6380

redis-cli --cluster add-node 192.168.0.3:6380 192.168.0.1:6379 --cluster-slave --cluster-master-id d35a50c334f9b3b734191294838c3f86a80e9d73

3)按照以上步骤,给另外两个主节点增加从节点

按照拓扑图,

给第二台主节点192.168.0.2:6379添加从节点:192.168.0.1:6381、192.168.0.3:6381;

给第三台主节点192.168.0.3:6379添加从节点:192.168.0.1:6380、192.168.0.2:6381。

4)检查

接入redis集群,通过cluster nodes命令与info replication检查集群配置是否正常。

3. Redis Cluster集群实现水平扩展

  1. 说明
    模拟将两台新机器加入机器, IP为192.168.0.100(主),192.168.0.101(从)
  2. 拓扑结构
  3. 安装Redis
    参照上述2.4的集群安装配置, 安装配置Redis服务
  4. 添加新的集群主节点
redis-cli -a 123456 --cluster add-node 192.168.0.100:6379 192.168.0.1:6379

输出结果:

[root@localhost redis] # redis-cli -a 123456 --cluster add-node 192.168.0.100:6379 192.168.0.1:6379
Warning:Using a password with '-a' or'-u'option on the command Line interface may not be safe.
>>>Adding node 192.168.0.100:6379 to cLuster 192.168.0.1:6379
>>>Perfoming Cluster Check(using node 192.168.0.1:6379)
M:4eledel370d1901c8c58b64a8234d5ea0lbf595d 192.168.0.1:6379
slots:[0-5460] (546l slots) master
2 additional replica(s)
S:7994c015e32875b77lec345038fdb92bcel9bde0 192.168.0.2:6380
slots :( 0 slots) slave
replicates 4eledel370d1901c8c58b64a8234d5ea0lbf595d
S:2c4ca39ffe6lbea03a4fa79f6dfeb2f17fb006b4 192.168.0.1:6381
slots:(O slots) slave
replicates b70c14316e403a4a of fabl3fdf39bdd9997399df
S:6lfd413lf8213fd4f46a5eddfc927d62c57146le 192.168.0.3:638l
slots:(O slots) sLave
replicates b70c14316e403a4a of fabl3fdf39bdd9997399df
S:604f4ldfce224777c8067f8778ac2e92bcdb6el4 192.168.0.1:6380
slots :( 0 slots) slave
replicates 75a0lef1056a0982a7edd330776518db37a6dl0b
M:b70c14316e403a4a of fabl3fdf39bdd9997399df 192.168.0.2:6379
slots:[5461-10922] ( 5462 slots) master
2 additional replica(s)
S:Ocd033e5b717b98cd76593048196dcl4849c4ff7 192.168.0.3:6380
slots :( 0 slots) slave
replicates 4eledel370d1901c8c58b64a8234d5ea0lbf595d
M:75aOlef1056a0982a7edd330776518db37a6dl0b 192.168.0.2:6381
slots:[10923-16383] ( 5461 slots) master
2 additional replica(s)
S:0199c65eeefl 4 34a9af4448c2dofod02b20fd314 192.168.0.3:6379
slots:(O slots) slave
replicates 75a0lef1056a0982a7edd330776518db37a6dl0b
[OK] ALL nodes agree about slots configuration.
>>>Check for open slots...
>>>Check slots coverage.
[OK] ALL 16384 slots covered
>>>Send CLUSTER MEET to node 192.168.0.100:6379 to make it join the cLuster.
[OK] Newnode added correctLy.
  1. 重新分配数据
    分配数据槽位给新加入的主节点
redis-cli -a 123456 --cluster reshard 192.168.0.100:6379

输出结果:

[root@localhost redis] #redis-cli-a 123456 --cluster reshard 192.168.0.100:6379
Warning:Using a password with '-a' or'-u'option on the command Line interface may not be safe.
>>Performing CLuster Check(using node 192.168.0.100:6379)
M:2126fdf84a7b23c83e7cdfc5cb3bdl366d4f7601 192.168.0.100:6379
s tots:(est ots) master
S:Ocd033e5b717b98cd76593048196dcl4849c4ff7 192.168.0.3:6380
slots :( 0 slots) sLave
replicates4eledel370d1901c8c58b64a8234d5ea0lbf595d
S:7994c015e32875b77lec345038fdb92bcel9bde0 192.168.0.2:6380
slots :( 0 slots) slave
replicates 4eledel370d1901c8c58b64a8234d5ea0lbf595d
M:4eledel370d1901c 8c58b64a8234d5ea0lbf595d 192.168.0.1:6379
slots:[0-5460] (546l slots) master
2 additional replica(s)
S:2c4ca39ffe6lbea 03a4fa79f6dfeb2fl7fb006b4 192.168.0.1:638l
slots :( 0 slots) sLave
replicates b70c14316e403a4a0ffabl3fdf39bdd9997399df
S:0199c65eeefl434a9af4448c2d0fod02b20fd314 192.168.0.3:6379
slots :( 0 slots) sLave
replicates 75aOlef1056a0982a7edd330776518db37a6dl0b
M:75a0lef1056a0982a7edd330776518db37a6dl0b 192.168.0.2:6381
slots:[10923-16383] ( 5461 slots) master
2 additional replica(s)
S:604f4ldfce224777c8067f8778ac2e92bcdb6el4 192.168.0.1:6380
slots :( 0 slots) slave
replicates 75aOlef1056a0982a7edd330776518db37a6dl0b
M:b70cl4316e403a4a of fabl3fdf39bdd9997399df 192.168.0.2:6379
slots:[5461-10922] ( 5462 slots) master
2 additional replica(s)
S:61fd4131f8213fd4f46a5eddfc927d62c57146le 192.168.0.3:6381
slots:(O slots) sLave
replicates b70c14316e403a4a of fabl3fdf39bdd9997399df
[OK] ALl nodes agree about slots configuration.
>>>Check for open slots...
>>Check slots coverage...
[OK] ALL 16384 slots covered

这里的数据槽位设定为600,可以根据需要设定。这里需要记录新加入的节点192.168.0.100所对应的ID: 2126fdf84a7b23c83e7cdfc5cb3bd1366d4f7601, 下面需要输入:

How many slots do you want to move(from l to 16384) ? 600
What is the receiving nodeID? 2126fdf84a7b23c83e7cdfc5cb3bd1366d4f7601
PLease enter all the source node IDs.
Type'all'to use all the nodes as source nodes for the hash slots.
Type'done'once you entered all the source nodes IDs.
Source node#l:all

输入all是代表从集群中的所有节点抽取600个数据槽位进行重新分配。

Moving slot 11068from75a0let1056a0982a7edd330776518db37a6dl0b
Moving sLot 11069from75a0lef1056a0982a7edd330776518db37a6dl0b
Moving slot 11070from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 11071from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 11072from75a0lef1056a0982a7edd330776518db37a6dl0b
Moving slot 11073from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 11074from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 11075from75a0lef1056a0982a7edd330776518db37a6dl0b
Moving slot 11076from75a0lefl056a0982a7edd330776518db37a6dlob
Moving slot 11077from75a0lef1056a0982a7edd330776518db37a6dl0b
Moving slot 11078from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 11079from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot l1080from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 1108lfrom75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot l1082from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 11083from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot l1084from75a0lefl056a0982a7edd330776518db37a6dlob
Moving slot 11085from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 11086from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 11087from75a0lef1056a0982a7edd330776518db37a6dlob
Moving slot 11088from75a0lef1056a0982a7edd330776518db37a6dlob
Do you want to proceed with the proposed reshard plan(yes/no) ?yes

输入yes,确认开始执行分片计划, 执行完毕后会自动退出, 代表新的主节点正常加入。

  1. 添加从节点
    192.168.0.100主节点加入成功后,加入对应的从节点192.168.0.101。
    可以参照上面的集群从节点加入步骤, 执行命令:
redis-cli --cluster add-node 192.168.0.101:6380 192.168.0.1:6379 --cluster-slave --cluster-master-id 2126fdf84a7b23c83e7cdfc5cb3bd1366d4f7601

cluster-master-id为新加入的192.168.0.100节点所对应的ID。最后通过cluster nodes命令检查集群信息。

4. Redis Cluster集群动态剔除节点

  1. 说明
    如果要调整Redis整个集群部署结构,可以通过动态增加和剔除节点的方式实现。
  2. 迁移节点的槽数据
./redis-cli --cluster reshard 192.168.0.100:6379

提示我们要移动多少哈希槽 ?

输入全部数量

选择接受的槽节点ID?

找一个新加入的主节点接受哈希槽

选择数据源槽?

输入需要剔除的节点ID
  1. 确保节点无数据, 执行剔除动作
redis-cli --cluster del-node 192.168.0.1:6379 <node-id>

注意:node-id为要剔除的节点ID标识。192.168.0.1:6379为集群中任意主节点。

  1. 如果要重平衡, 可以执行以下指令
./redis-cli --cluster rebalance --cluster-threshold 1 192.168.0.1:6379

5. FAQ

  1. 脑裂问题

网络分区出错现象:比如其中一个master节点的网络出现问题,slave节点无法取得联系,但是客户端可以连接,那么slave在无法联系master一段时间, 就会触发重新选举主节点,从而导致脑裂现象。如果产生多个主节点对外提供写服务,一旦网络分区恢复, 会将其中一个主节点变为从节点,就会有大量数据丢失。
规避方法: 在redis.conf里面添加min‐replicas‐to‐write 1。写数据成功最少同步的slave数量。这个配置在一定程度上会影响集群的可用性,比如slave要是少于1个,这个集群就算leader正常也不能 提供服务了,需要根据具体场景权衡选择。

  1. 集群服务可用性配置问题

当redis.conf的配置cluster-require-full-coverage为no时,表示当负责一个插槽的主库下线且没有相应的从 库进行故障恢复时,集群仍然可用,如果为yes则集群不可用

  1. You requested maxclients of 10000 requiring at least 10032 max file descriptors.

问题:你设置的最大连接数是10000 那么服务器的最大连接数最少需要10032
原因:服务器的最大连接数 < redis.conf中设置的最大连接数。对应属性是maxclients,没设置默认为10000。

解决:

1、修改服务器最大连接数: vi etc/profile,调整: ulimit -n 20000

2、修改redis.conf配置文件中maxclients的属性。改小些: maxclients 9000