Redis cluster简介

  • redis 3.0版本之前,只支持单例模式,在3.0版本之后才支持集群
  • redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点
  • redis集群是没有统一的入口的,客户端连接集群中的任意节点即可,集群内部的节点是相互通信的(Gossip通信协议, PING-PONG机制),每个节点都是一个redis实例
  • 为了实现集群的高可用,即判断节点是否健康,redis cluster有这么一个投票容错机制:如果集群中找过半数的节点投票认为某节点挂了,那么该节点就挂了(fail)。
  • 如何判断机器是否挂了呢: 如果集群中任意一个主节点挂了,而该节点又没有从节点(备份节点),那么这个集群就挂了。
  • 为什么任意一个主节点挂了(又没有对应的从节点)这个集群就挂了呢:是因为集群内置了16384(0~16383)个slot(哈希槽),并且把所有的物理节点映射到了这16384个slot上,或者说把这些slot均等的分配给了各个节点。
    • 当需要redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果
    • 再把这个结果对16384进行取余,这个余数会对应到(0~16383)其中一个槽,进而决定key-value存储在哪个节点中
    • 所以一旦某个主节点(又没有从节点)挂了,该节点的slot就无法使用了,那么就会导致集群无法正常工作
  • redis集群至少需要3个主节点:因为投票容错机制要求超过半数节点认为某节点挂了该节点才是挂了,所以2个节点服务构建集群。
  • redis集群至少需要6台服务器
    • 因为要保证集群的高可用,需要每个主节点都有至少一个从节点(备份节点)
    • 如果手上没那么多服务,也可以采用伪分布式集群搭法,即一台物理机启动多个redis实例,比如一台服务器启动两个redis实例。三台服务器就可以搭建最小化的redis cluster集群

Redis cluster搭建

环境情况

本次环境共用了三台服务器,每台服务器启动两个redis实例,每台服务器一个主节点、一个从节点。每两个不同的服务器之间进行主从配置,从而保证高可用。如下所示:

主机名node1node2node3
主节点192.168.1.10:6379192.168.1.11:6379192.168.1.12:6379
槽位0-54615462-1092210923-16383
从节点192.168.1.12:6380192.168.1.10:6380192.168.1.11:6380

安装

所有节点操作

mkdir /opt/redis-cluster
cd !$
wget https://download.redis.io/releases/redis-6.2.6.tar.gz
tar xzvf redis-6.2.6.tar.gz
cd redis-6.2.6
yum install make gcc -y
make MALLOC=libc
make install
mkdir -p /opt/redis-cluster/redis_6379/{conf,pid,logs}
mkdir -p /opt/redis-cluster/redis_6380/{conf,pid,logs}
cp redis.conf ../redis_6379/conf/
cp redis.conf ../redis_6380/conf/
# 配置系统参数
echo 'net.core.somaxconn= 1024' >> /etc/sysctl.conf
echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf
echo never>/sys/kernel/mm/transparent_hugepage/enabled
echo 'echo never>/sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
sysctl -p

修改Redis配置文件:
每一个Redis实例都需要按照环境规划表中的信息修改配置文件的ip、port、pid、log等信息。修改后配置如下:

cat ../redis_6379/conf/redis.conf | egrep -v ^# | sed '/^$/d'
bind 192.168.1.10
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /opt/redis-cluster/redis_6379/pid/redis_6379.pid
loglevel notice
logfile /opt/redis-cluster/redis_6379/logs/redis_6379.log
databases 16
always-show-logo no
set-proc-title yes
proc-title-template "{title} {listen-addr} {server-mode}"
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename redis_6379.rdb
rdb-del-sync-files no
dir /opt/redis-cluster/redis_6379
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
lazyfree-lazy-user-flush no
oom-score-adj no
oom-score-adj-values 0 200 800
disable-thp yes
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes

主要修改配置如下:

# 守护进行模式启动
daemonize yes
# 设置数据库数量,默认数据库为0
databases 16
# 绑定地址,需要修改
bind 192.168.1.10
# 绑定端口,需要修改
port 6379
# pid文件存储位置,文件名需要修改
pidfile /opt/redis-cluster/redis_6379/pid/redis_6379.pid
# log文件存储位置,文件名需要修改
logfile /opt/redis-cluster/redis_6379/logs/redis_6379.log
# RDB快照备份文件名,文件名需要修改
dbfilename redis_6379.rdb
# 本地数据库存储目录,需要修改
dir /opt/redis-cluster/redis_6379
# 集群相关配置
# 是否以集群模式启动
cluster-enabled yes
# 集群节点回应最长时间,超过该时间被认为下线
cluster-node-timeout 15000
# 生成的集群节点配置文件名,文件名需要修改
cluster-config-file nodes_6379.conf

启动Redis服务

redis-server /opt/redis-cluster/redis_6379/conf/redis.conf
redis-server /opt/redis-cluster/redis_6380/conf/redis.conf

也可以配置systemd来进行服务的启动管理
略......

单节点操作

加入集群

# 随便选择一台服务器操作即可
redis-cli -h 192.168.1.10 -p 6379
192.168.1.10:6379> cluster meet 192.168.1.10 6380
OK
192.168.1.10:6379> cluster meet 192.168.1.11 6379
OK
192.168.1.10:6379> cluster meet 192.168.1.11 6380
OK
192.168.1.10:6379> cluster meet 192.168.1.12 6379
OK
192.168.1.10:6379> cluster meet 192.168.1.12 6380
192.168.1.10:6379> cluster nodes
28829d040afe6e91fb6b0dab095b147c5347577e 192.168.1.10:6380@16380 master - 0 1648011904529 1 connected
0771bb6663fee3ca8834c47475857424c13eee73 192.168.1.11:6380@16380 master - 0 1648011905532 3 connected
836108fc1673ddbf76b450bdae6ac685e518777a 192.168.1.12:6380@16380 master - 0 1648011902523 5 connected
b10a9d22051f13664215fbf2e198fc4bc2641b27 192.168.1.11:6379@16379 master - 0 1648011901520 0 connected
08299ba12962a8ae38daa6adb0970d344eae30c0 192.168.1.12:6379@16379 master - 0 1648011903526 4 connected
4f6edb7d3276e195bd3d12f02dc8f401a4be59d5 192.168.1.10:6379@16379 myself,master - 0 1648011902000 2 connected

配置主从

redis-cli -h 192.168.1.10 -p 6380
192.168.1.10:6380> cluster replicate b10a9d22051f13664215fbf2e198fc4bc2641b27
OK
192.168.1.10:6380> exit
redis-cli -h 192.168.1.11 -p 6380
192.168.1.11:6380> cluster replicate 08299ba12962a8ae38daa6adb0970d344eae30c0
OK
192.168.1.11:6380> exit
redis-cli -h 192.168.1.12 -p 6380
192.168.1.12:6380> cluster replicate 4f6edb7d3276e195bd3d12f02dc8f401a4be59d5
OK
192.168.1.12:6380> cluster nodes
b10a9d22051f13664215fbf2e198fc4bc2641b27 192.168.1.11:6379@16379 master - 0 1648012278782 0 connected
836108fc1673ddbf76b450bdae6ac685e518777a 192.168.1.12:6380@16380 myself,slave 4f6edb7d3276e195bd3d12f02dc8f401a4be59d5 0 1648012280000 2 connected
4f6edb7d3276e195bd3d12f02dc8f401a4be59d5 192.168.1.10:6379@16379 master - 0 1648012278000 2 connected
08299ba12962a8ae38daa6adb0970d344eae30c0 192.168.1.12:6379@16379 master - 0 1648012280000 4 connected
0771bb6663fee3ca8834c47475857424c13eee73 192.168.1.11:6380@16380 slave 08299ba12962a8ae38daa6adb0970d344eae30c0 0 1648012276775 4 connected
28829d040afe6e91fb6b0dab095b147c5347577e 192.168.1.10:6380@16380 slave b10a9d22051f13664215fbf2e198fc4bc2641b27 0 1648012279786 0 connected

槽位分配

redis-cli -h 192.168.1.10 -p 6379 cluster addslots {0..5461}
redis-cli -h 192.168.1.11 -p 6379 cluster addslots {5462..10922}
redis-cli -h 192.168.1.12 -p 6379 cluster addslots {10923..16383}
192.168.1.10:6379> cluster nodes
28829d040afe6e91fb6b0dab095b147c5347577e 192.168.1.10:6380@16380 slave b10a9d22051f13664215fbf2e198fc4bc2641b27 0 1648012533544 0 connected
0771bb6663fee3ca8834c47475857424c13eee73 192.168.1.11:6380@16380 slave 08299ba12962a8ae38daa6adb0970d344eae30c0 0 1648012530533 4 connected
836108fc1673ddbf76b450bdae6ac685e518777a 192.168.1.12:6380@16380 slave 4f6edb7d3276e195bd3d12f02dc8f401a4be59d5 0 1648012533000 2 connected
b10a9d22051f13664215fbf2e198fc4bc2641b27 192.168.1.11:6379@16379 master - 0 1648012531537 0 connected 5462-10922
08299ba12962a8ae38daa6adb0970d344eae30c0 192.168.1.12:6379@16379 master - 0 1648012531000 4 connected 10923-16383
4f6edb7d3276e195bd3d12f02dc8f401a4be59d5 192.168.1.10:6379@16379 myself,master - 0 1648012529000 2 connected 0-5461

自动分配

可以通过如下命令自动分配master/slave和槽位,无需执行上面的几个步骤

./redis-cli --cluster create --cluster-replicas 1 192.168.1.10:6379 192.168.1.10:6380 192.168.1.11:6379 192.168.1.11:6380 192.168.1.12:6379 192.168.1.12:6389

测试

redis-cli -c -h 192.168.1.10 -p 6379
192.168.1.10:6379> set k1 "v1"
-> Redirected to slot [12706] located at 192.168.1.12:6379
OK
192.168.1.12:6379> exit
# 槽位分配至12706,此槽位对应的主节点为192.168.1.12、从节点为192.168.1.11
# 登陆从节点查看,对应主节点是否写入对应数据且从节点是否同步成功
redis-cli -c -h 192.168.1.11 -p 6380
192.168.1.11:6380> keys *
1) "k1"

认证配置

所有节点redis配置文件增加如下配置
masterauth password
requirepass password

星霜荏苒 居诸不息