Redis Cluster 即 Redis 集群,是 Redis 官方在 3.0 版本推出的一套分布式存储方案。完全去中心化,由多个节点组成,所有节点彼此互联。Redis 客户端可以直接连接任何一节点获取集群中的键值对,不需要中间代理,如果该节点不存在用户所指定的键值,其内部会自动把客户端重定向到键值所在的节点。
Redis 集群是一个网状结构,每个节点都通过 TCP 连接跟其他每个节点连接。在一个有 N 个节点的集群中,每个节点都有 N-1 个流出的 TCP 连接,和 N-1 个流入的连接,这些 TCP 连接会永久保持。
Redis Cluster 同其他分布式存储系统一样,主要具备以下两个功能:
数据分区
Redis 集群会将用户数据分散保存至各个节点中,突破单机
Redis 内存最大存储容量。集群引入了 哈希槽slot的概念,其搭建完成后会生
16384 个哈希槽slot,同时会根据节点的数量大致均等的将 16384 个哈希槽映射到不同的节点上。当用户存储key-value时,集群会先对key进行 CRC16 校验然后对 16384 取模来决定key-value放置哪个槽,从而实现自动分割数据到不同的节点上。
数据冗余
Redis 集群支持主从复制和故障恢复。集群使用了主从复制模型,每个主节点master应至少有一个从节点slave。假设某个主节点故障,其所有子节点会广播一个数据包给集群里的其他主节点来请求选票,一旦某个从节点收到了大多数主节点的回应,那么它就赢得了选举,被推选为主节点,负责处理之前旧的主节点负责的哈希槽。
1.1 Ruby编译安装
Redis3.0需要安装ruby和rubygems环境,而且ruby版本要高于1.8.7;
tar -zxvf ruby-2.5.5.tar.gz
cd ruby-2.5.5
./configure
make &&make install
[root@hdp-03 cluster]# ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux]
1.2 Rubygems编译安装
下载最新的rubygems-3.0.4.tgz安装包上传服务器对应安装目录/opt
#tar -zxvf rubygems-3.0.4.tgz
#cd rubygems-3.0.4
#ruby setup.rb
[root@hdp-03 cluster]# gem -v
3.0.4
1.3 Redis3.0编译安装
tar -zxvf redis-3.0.0.tar.gz
cd redis-3.0.0/
make
make install
1.4 Redis3.0集群配置
1.4.1 创建集群需要的目录
[root@hdp-03 redis]# mkdir -pv cluster
[root@hdp-03 redis]# mkdir -pv /opt/redis/cluster/{8001,8002,8003,8004,8005,8006}
mkdir: created directory `/opt/redis/cluster/8001'
mkdir: created directory `/opt/redis/cluster/8002'
mkdir: created directory `/opt/redis/cluster/8003'
mkdir: created directory `/opt/redis/cluster/8004'
mkdir: created directory `/opt/redis/cluster/8005'
mkdir: created directory `/opt/redis/cluster/8006'
1.4.2 修改redis.conf配置文件并分发到集群节点目录
vim redis.conf
###修改配置文件中的下面选项
port 8001 #分别更改
daemonize yes #允许后台启动
cluster-enabled yes # 启用集群模式
cluster-config-file nodescode.conf # 设置当前节点集群配置文件路径
appendonly yes
pidfile /var/run/redis8001.pid #设置 Redis 实例 pid 文件
logfile "/var/8001.log" #设置 Redis 实例log文件
dir /opt/redis/cluster/8001
bind 192.168.56.131
分发各个节点配置文件:
[root@hdp-03 redis-3.0.0]# cp redis.conf /opt/redis/cluster/8001
[root@hdp-03 redis-3.0.0]# cp redis.conf /opt/redis/cluster/8002
[root@hdp-03 redis-3.0.0]# cp redis.conf /opt/redis/cluster/8003
[root@hdp-03 redis-3.0.0]# cp redis.conf /opt/redis/cluster/8004
[root@hdp-03 redis-3.0.0]# cp redis.conf /opt/redis/cluster/8005
[root@hdp-03 redis-3.0.0]# cp redis.conf /opt/redis/cluster/8006
将分发的配置文件进行批量修改:
sed -i 's/8001/8006/g' /opt/redis/cluster/8006/redis.conf
sed -i 's/8001/8005/g' /opt/redis/cluster/8005/redis.conf
sed -i 's/8001/8004/g' /opt/redis/cluster/8004/redis.conf
sed -i 's/8001/8003/g' /opt/redis/cluster/8003/redis.conf
sed -i 's/8001/8002/g' /opt/redis/cluster/8002/redis.conf
1.4.3 分别启动这6个redis实例
cd /opt/redis/redis-3.0.0/src
./redis-server /opt/redis/cluster/8001/redis.conf
./redis-server /opt/redis/cluster/8002/redis.conf
./redis-server /opt/redis/cluster/8003/redis.conf
./redis-server /opt/redis/cluster/8004/redis.conf
./redis-server /opt/redis/cluster/8005/redis.conf
./redis-server /opt/redis/cluster/8006/redis.conf
1.4.4 Redis集群创建
执行redis的创建集群命令创建集群:
[root@hdp-03 src]# ./redis-trib.rb create --replicas 1 192.168.56.131:8001 192.168.56.131:8002 192.168.56.131:8003 192.168.56.131:8004 192.168.56.131:8005 192.168.56.131:8006
Traceback (most recent call last):
2: from ./redis-trib.rb:25:in `<main>'
1: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- redis (LoadError)
报错缺少redis包,网上下载redis-3.2.1.gem ,离线安装。
[root@hdp-03 opt]# gem install -l redis-3.2.1.gem
Successfully installed redis-3.2.1
Parsing documentation for redis-3.2.1
Installing ri documentation for redis-3.2.1
Done installing documentation for redis after 5 seconds
1 gem installed
再次添加集群,报错解决
[root@hdp-03 src]# ./redis-trib.rb create --replicas 1 192.168.56.131:8001 192.168.56.131:8002 192.168.56.131:8003 192.168.56.131:8004 192.168.56.131:8005 192.168.56.131:8006
>>> Creating cluster
Connecting to node 192.168.56.131:8001: /usr/local/lib/ruby/gems/2.5.0/gems/redis-3.2.1/lib/redis/client.rb:443: warning: constant ::Fixnum is deprecated
OK
Connecting to node 192.168.56.131:8002: OK
Connecting to node 192.168.56.131:8003: OK
Connecting to node 192.168.56.131:8004: OK
Connecting to node 192.168.56.131:8005: OK
Connecting to node 192.168.56.131:8006: OK
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.56.131:8001
192.168.56.131:8002
192.168.56.131:8003
Adding replica 192.168.56.131:8004 to 192.168.56.131:8001
Adding replica 192.168.56.131:8005 to 192.168.56.131:8002
Adding replica 192.168.56.131:8006 to 192.168.56.131:8003
M: 17fafe3d446fbc39ec6dccc34ac587ef81b43d3e 192.168.56.131:8001
slots:0-5460 (5461 slots) master
M: 6bfff4b28c4f88474c69a44c686ba700ce4202a1 192.168.56.131:8002
slots:5461-10922 (5462 slots) master
M: bcccb5585c60c6e317395f1dd04ae67f0633f2f5 192.168.56.131:8003
slots:10923-16383 (5461 slots) master
S: 4dd53ed70f5b439c93e965450d5ff343992a982d 192.168.56.131:8004
replicates 17fafe3d446fbc39ec6dccc34ac587ef81b43d3e
S: f828adcac276ee202e4255962f9ee0fd455379c0 192.168.56.131:8005
replicates 6bfff4b28c4f88474c69a44c686ba700ce4202a1
S: 32dadc2dc23c8e512bc39b4ec5a3826d95b81642 192.168.56.131:8006
replicates bcccb5585c60c6e317395f1dd04ae67f0633f2f5
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join....
>>> Performing Cluster Check (using node 192.168.56.131:8001)
M: 17fafe3d446fbc39ec6dccc34ac587ef81b43d3e 192.168.56.131:8001
slots:0-5460 (5461 slots) master
M: 6bfff4b28c4f88474c69a44c686ba700ce4202a1 192.168.56.131:8002
slots:5461-10922 (5462 slots) master
M: bcccb5585c60c6e317395f1dd04ae67f0633f2f5 192.168.56.131:8003
slots:10923-16383 (5461 slots) master
M: 4dd53ed70f5b439c93e965450d5ff343992a982d 192.168.56.131:8004
slots: (0 slots) master
replicates 17fafe3d446fbc39ec6dccc34ac587ef81b43d3e
M: f828adcac276ee202e4255962f9ee0fd455379c0 192.168.56.131:8005
slots: (0 slots) master
replicates 6bfff4b28c4f88474c69a44c686ba700ce4202a1
M: 32dadc2dc23c8e512bc39b4ec5a3826d95b81642 192.168.56.131:8006
slots: (0 slots) master
replicates bcccb5585c60c6e317395f1dd04ae67f0633f2f5
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@hdp-03 src]#
从上面截图可以看出redis3.0集群配置成功。
分别有3主和对应的3个从节点。共同分配了16384个哈希槽位。
2 Redis运维
2.1 内存分配控制优化
Redis在启动的时候,可能会出现这样的日志:
75396:M 01 May 09:27:11.248 # Server started, Redis version 3.0.0
75396:M 01 May 09:27:11.248 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
vm.overcommit_memory = 1 表示内核允许超量使用内存,直到用完为止。
通过以上方法设置内存分配优化。
2.2 THP(Transparent Huge Pages)禁用
建议修改THP的相关配置,Linux 内核在2.6.38增加了THP的特性支持大内存页2MB的分配,默认开启。
开启的时候,可以降低fork子进程的速度,但fork之后,每一个内存页从原来4KB变为2MB,大幅度增加重写期间父进程的消耗。因此redis 建议禁用大内存页面。
2.3 Redis安全加密
设置redis 登录的访问密码,在没有密码的情况下,登录redis存在安全隐患,容易误操作,将数据flushdb 清空。
在redis.conf 里面将如下注释取消,设置master 的密码。
在主节点master 的redis.conf
requirepass AaWz123
在从节点slave的redis.conf
masterauth AaWz123
设置密码后,需重启生效,登录通过如下命令:
./redis-cli -p 8001 -a AaWz123