redis5.0集群部署
一、集群介绍
Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。
Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的行为。
Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
Redis 集群提供了以下两个好处:
将数据自动切分(split)到多个节点的能力。
当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。
二、Redis 集群数据共享
Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
集群中的每个节点负责处理一部分哈希槽。 举个例子, 一个集群可以有三个哈希槽, 其中:
- 节点 A 负责处理 0 号至 5500 号哈希槽。
- 节点 B 负责处理 5501 号至 11000 号哈希槽。
- 节点 C 负责处理 11001 号至 16384 号哈希槽。
这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说:
如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。
与此类似, 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。
因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。
三、Redis 集群中的主从复制
为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下, 仍然可以正常运作, Redis 集群对节点使用了主从复制功能: 集群中的每个节点都有 1 个至 N 个复制品(replica), 其中一个复制品为主节点(master), 而其余的 N-1 个复制品为从节点(slave)。
在之前列举的节点 A 、B 、C 的例子中, 如果节点 B 下线了, 那么集群将无法正常运行, 因为集群找不到节点来处理 5501 号至 11000 号的哈希槽。
另一方面, 假如在创建集群的时候(或者至少在节点 B 下线之前), 我们为主节点 B 添加了从节点 B1 , 那么当主节点 B 下线的时候, 集群就会将 B1 设置为新的主节点, 并让它代替下线的主节点 B , 继续处理 5501 号至 11000 号的哈希槽, 这样集群就不会因为主节点 B 的下线而无法正常运作了。
不过如果节点 B 和 B1 都下线的话, Redis 集群还是会停止运作。
四、创建并使用 Redis 集群
必须使用六个节点: 其中三个为主节点, 而其余三个则是各个主节点的从节点。否则集群无法正常运行!!
安装过程
1. 下载并解压
cd /root/software
wget http://download.redis.io/releases/redis-5.0.0.tar.gz
tar -zxvf redis-5.0.0.tar.gz
2. 编译安装
cd redis-5.0.0
make && make install
3. 将 redis-trib.rb 复制到 /usr/local/bin 目录下
cd src
cp redis-trib.rb /usr/local/bin/
4. 创建 Redis 节点
首先在 10.90.6.157 机器上 /root/software/redis-5.0.0 目录下创建 redis_cluster 目录;
mkdir redis_cluster
在 redis_cluster 目录下,创建名为6379的目录,并将 redis.conf 拷贝到这个目录中
mkdir 6379
cp redis.conf redis_cluster/6379
分别修改这三个配置文件,修改如下内容
port 6379 //端口默认
#bind 127.0.0.1 //注释掉默认ip为127.0.0.1 需要改为其他节点机器可访问的ip 否则创建集群时无法访问对应的端口,无法创建集群
daemonize yes //redis后台运行
pidfile /var/run/redis_6379.pid //pidfile文件对应6379
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_6379.conf //集群的配置 配置文件首次启动自动生成 6379
cluster-node-timeout 15000 //请求超时 默认15秒,可自行设置
appendonly yes //aof日志开启 有需要就开启,它会每次写操作都记录一条日志
集群的完整配置文件如下:
protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly yes
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
Redis 官方提供了 redis-trib.rb 这个工具是用 ruby 实现的,所以需要安装 ruby。安装命令如下:
yum -y install ruby ruby-devel rubygems rpm-build
gem install redis
其中 gem install redis命令执行时出现了:
redis requires Ruby version >= 2.2.2的报错,查了资料发现是Centos默认支持ruby到2.0.0,可gem 安装redis需要最低是2.2.2
解决办法是 先安装rvm,再把ruby版本提升至2.3.3
1.安装curl
sudo yum install curl
2. 安装RVM
curl -L get.rvm.io | bash -s stable
3. 加载配置
source /usr/local/rvm/scripts/rvm
4. 查看rvm库中已知的ruby版本
rvm list known
5. 安装一个ruby版本
rvm install 2.3.3
6. 使用一个ruby版本
rvm use 2.3.3
7. 设置默认版本
rvm remove 2.0.0
8. 卸载一个已知版本
ruby --version
9. 再安装redis就可以了
gem install redis
好了,重复以上的安装步凑把剩下的5个节点部署好!!!
10.创建集群
在6个节点中执行以下命令启动redis:
src/redis-server ./redis_cluster/6379/redis.conf &
在1个节点上执行以下创建集群命令:
src/redis-cli --cluster create 10.90.6.156:6379 10.90.6.157:6379 10.90.6.158:6379 10.90.6.159:6379 10.90.6.160:6379 10.90.6.161:6379 --cluster-replicas 1
[root@Redis1 redis-5.0.0]# src/redis-cli --cluster create 10.90.6.156:6379 10.90.6.157:6379 10.90.6.158:6379 10.90.6.159:6379 10.90.6.160:6379 10.90.6.161:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.90.6.159:6379 to 10.90.6.156:6379
Adding replica 10.90.6.160:6379 to 10.90.6.157:6379
Adding replica 10.90.6.161:6379 to 10.90.6.158:6379
M: ddebff330f23552db26eadb51c4f9926473cb485 10.90.6.156:6379
slots:[0-5460] (5461 slots) master
M: 4256ffaa3ad3d1c8ad3174898f97114629922a8e 10.90.6.157:6379
slots:[5461-10922] (5462 slots) master
M: 9b7c727852f4bde936b8bb8f6cbda2cf621b7c9b 10.90.6.158:6379
slots:[10923-16383] (5461 slots) master
S: e52195f35519ac8c360b008a354415ad39190027 10.90.6.159:6379
replicates ddebff330f23552db26eadb51c4f9926473cb485
S: 06d022e927a8f166cd08e333e8723d4c5b5a1092 10.90.6.160:6379
replicates 4256ffaa3ad3d1c8ad3174898f97114629922a8e
S: b57ebc5c247f01e9e35cf798bd6932bdaee04098 10.90.6.161:6379
replicates 9b7c727852f4bde936b8bb8f6cbda2cf621b7c9b
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 10.90.6.156:6379)
M: ddebff330f23552db26eadb51c4f9926473cb485 10.90.6.156:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: b57ebc5c247f01e9e35cf798bd6932bdaee04098 10.90.6.161:6379
slots: (0 slots) slave
replicates 9b7c727852f4bde936b8bb8f6cbda2cf621b7c9b
S: e52195f35519ac8c360b008a354415ad39190027 10.90.6.159:6379
slots: (0 slots) slave
replicates ddebff330f23552db26eadb51c4f9926473cb485
S: 06d022e927a8f166cd08e333e8723d4c5b5a1092 10.90.6.160:6379
slots: (0 slots) slave
replicates 4256ffaa3ad3d1c8ad3174898f97114629922a8e
M: 4256ffaa3ad3d1c8ad3174898f97114629922a8e 10.90.6.157:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 9b7c727852f4bde936b8bb8f6cbda2cf621b7c9b 10.90.6.158:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
如果报错,请看下面!!
[root@Redis1 redis-5.0.0]# src/redis-cli --cluster create 10.90.6.156:6379 10.90.6.157:6379 10.90.6.158:6379 10.90.6.159:6379 10.90.6.160:6379 10.90.6.161:6379 --cluster-replicas 1
[ERR] Node 10.90.6.157:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
的问题
解决办法:
1)将每个节点下aof、rdb、nodes.conf本地备份文件删除;
[root@redis-5.0.0]# rm -fr appendonly.aof dump.rdb nodes-*
[root@redis-5.0.0]# pwd
/fs01/redis-5.0.0
2)10.90.6.157:6379> flushdb #清空当前数据库
3)之后再执行脚本,成功执行;
这里解释一下dump.rdb文件:
dump.rdb是由Redis服务器自动生成的 默认情况下 每隔一段时间redis服务器程序会自动对数据库做一次遍历,把内存快照写在一个叫做“dump.rdb”的文件里,这个持久化机制叫做SNAPSHOT。有了SNAPSHOT后,如果服务器宕机,重新启动redis服务器程序时redis会自动加载dump.rdb,将数据库状态恢复到上一次做SNAPSHOT时的状态。
SNAPSHOT即快照
重新连接redis集群,成功
8. 集群验证
在一台机器上连接方式为 redis-cli -h -c 10.90.6.157 ,加参数 -c 可连接到集群,因为上面 redis.conf 将 bind 改为了ip地址,所以 -h 参数不可以省略。
[root@Redis2 src]# ./redis-cli -c -h 10.90.6.157
10.90.6.157:6379> get hello
"2"
10.90.6.157:6379>