Redis集群的分布式部署
阅读原文时间:2023年07月09日阅读:1

3.2.2:Redis Cluster:

Redis  分布式部署方案:

1)  客户端分区:由客户端程序决定 key 写分配和写入的 redis node,但是需要客户端自己处理写入

分配、高可用管理和故障转移等

2)代理方案:基于三方软件实现 redis proxy,客户端先连接之代理层,由代理层实现 key 的写入分

配,对客户端来说是有比较简单,但是对于集群管节点增减相对比较麻烦,而且代理本身也是单点和

性能瓶颈。

在哨兵 sentinel 机制中,可以解决 redis 高可用的问题,即当 master 故障后可以自动将 slave 提升为  master 从而可以保证 redis 服务的正常使用,但是无法解决 redis 单机写入的瓶颈问题,即单机的 redis  写入性能受限于单机的内存大小、并发数量、网卡速率等因素,因此 redis 官方在 redis 3.0 版本之后  推出了无中心架构的 redis cluster 机制,在无中心的 redis 集群汇中,其每个节点保存当前节点数据和  整个集群状态,每个节点都和其他所有节点连接,特点如下:

1:所有 Redis 节点使用(PING 机制)互联

2:集群中某个节点的失效,是整个集群中超过半数的节点监测都失效才算真正的失效

3:客户端不需要 proxy 即可直接连接 redis,应用程序需要写全部的 redis 服务器 IP。

4:redis cluster 把所有的 redis node 映射到  0-16383 个槽位(slot)上,读写需要到指定的 redis node 上

进行操作,因此有多少个 reids node 相当于 redis  并发扩展了多少倍。

5:Redis cluster 预先分配 16384 个(slot)槽位,当需要在 redis 集群中写入一个 key -value 的时候,会使

用 CRC16(key)    mod 16384 之后的值,决定将 key 写入值哪一个槽位从而决定写入哪一个 Redis 节点

上,从而有效解决单机瓶颈。

3.2.2.1:Redis cluster 架构:

3.2.2.1.1:Redis cluster 基本架构:

假如三个主节点分别是:A, B, C  三个节点,采用哈希槽  (hash slot)的方式来分配 16384 个 slot  的话,

它们三个节点分别承担的 slot  区间是:

3.2.2.1.2:Redis cluster 主从架构:

Redis cluster 的架构虽然解决了并发的问题,但是又引入了一个新的问题,每个 Redis master 的高可用

如何解决?

3.2.2.2:部署 redis 集群:

环境准备:

环境 A:三台服务器,每台服务器启动 6379 和 6380 两个 redis  服务。

172.16.99.127:6379/6380     

172.16.99.128:6379/6380

172.16.99.129:6379/6380

另外预留一台服务器做集群添加节点测试。

172.16.99.130:6379/6380

环境 B:生产环境建议直接 6 台服务器。

172.16.99.127

172.16.99.128

172.16.99.129

172.16.99.130

172.16.99.131

172.16.99.132

预留服务器

172.16.99.133

3.2.2.2.1:创建 redis cluster 集群的前提:

1.每个 redis node 节点采用相同的硬件配置、相同的密码

2.每个节点必须开启的参数

cluster-enabled yes #必须开启集群状态,开启后 redis  进程会有 cluster 显示

cluster-config-file nodes-6379.conf #此文件有 redis cluster 集群自动创建和维护,不需要任何手动操作

3.所有 redis 服务器必须没有任何数据

4.先启动为单机 redis 且没有任何 key value

注:我们可以在一个节点源码安装好redis并,修改好配置直接打包传到其他机器上,操作如下

# pwd

/usr/local

# tar -cvf redis.tar.gz redis/

# scp redis.tar.gz root@172.16.99.128:/usr/local/

配置文件/usr/local/redis/etc/redis.conf示范如下:

bind 0.0.0.0

protected-mode yes

port 6379

tcp-backlog 511

timeout 0

tcp-keepalive 300

daemonize yes

supervised systemd

requirepass "123456"

pidfile "/usr/local/redis/run/redis_6379.pid"

loglevel notice

logfile "/usr/local/redis/logs/redis_6379.log"

databases 16

always-show-logo yes

save 900 1

save 300 10

save 60 10000

stop-writes-on-bgsave-error no

rdbcompression yes

rdbchecksum yes

dbfilename "dump_6379.rdb"

dir "/usr/local/redis/data"

slave-serve-stale-data yes

slave-read-only yes

repl-diskless-sync no

repl-diskless-sync-delay 30

repl-disable-tcp-nodelay no

slave-priority 100

lazyfree-lazy-eviction no

lazyfree-lazy-expire no

lazyfree-lazy-server-del no

slave-lazy-flush no

maxmemory 1073741824

appendonly yes

appendfilename "appendonly_6379.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 no

lua-time-limit 5000

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

activerehashing yes

client-output-buffer-limit normal 0 0 0

client-output-buffer-limit slave 256mb 64mb 60

client-output-buffer-limit pubsub 32mb 8mb 60

hz 10

aof-rewrite-incremental-fsync yes

# Generated by CONFIG REWRITE

# slaveof 172.16.99.128 6379

cluster-enabled yes

cluster-config-file nodes-6379.conf

maxclients 4064

3.2.2.2.2:创建集群:

Redis 3 和  4 版本:

需要使用到集群管理工具 redis-trib.rb,这个工具是 redis 官方推出的管理 redis 集群的工具,集成在

redis 的源码 src 目录下,是基于 redis 提供的集群命令封装成简单、便捷、实用的操作工具,redis-trib.rb

是 redis 作者用 ruby 开发完成的,centos 系统 yum 安装的 ruby 存在版本较低问题,如下:

[root@redis-vm1 ~]# yum install ruby    rubygems    -y

[root@redis-vm1 ~]# find / -name redis-trib.rb

/usr/local/src/redis-4.0.14/src/redis-trib.rb

[root@redis-vm1 ~]# cp /usr/local/src/redis-4.0.14/src/redis-trib.rb /usr/bin/  [root@redis-vm1 src]# gem install redis

Fetching: redis-4.1.2.gem (100%)  ERROR:    Error installing redis:

redis requires Ruby version >= 2.3.0.

#解决 ruby 版本较低问题:

#ruby官方下载地址: https://cache.ruby-lang.org/pub/ruby/

[root@redis-vm1 src]# yum remove ruby rubygems     -y

[root@redis-vm1 src]# wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.tar.gz

[root@redis-vm1 src]# tar xf ruby-2.5.5.tar.gz

[root@redis-vm1 src]# cd ruby-2.5.5

[root@redis-vm1 ruby-2.5.5]# ./configure  

[root@redis-vm1 ruby-2.5.5]# make -j 2  

[root@redis-vm1 ruby-2.5.5]# make install

[root@redis-vm1 ruby-2.5.5]# gem  install redis   # gem install redis -v 4.1.2 联网安装指定版本

注1: 如果要安装固定版本的操作如下

# wget -P /root  https://rubygems.org/downloads/redis-4.1.2.gem 

# gem install -l redis-4.1.2.gem

官方下载地址:https://rubygems.org/gems/redis

注2:redis-trib.rb只要安装在一个节点上就可以了,主要是用于集群的创建

报错:ruby cannot load such file -- zlib

ruby 安装redis报错

[root@localhost tools]# gem install -l redis-4.1.2.gem

ERROR: Loading command: install (LoadError)

 cannot load such file -- zlib

ERROR: While executing gem … (NoMethodError)

    undefined method `invoke_with_build_args' for nil:NilClass

解决办法是:

yum -y install zlib-devel

进入ruby源码文件夹,安装ruby自身提供的zlib包

cd ruby-2.5.5/ext/zlib

ruby ./extconf.rb

修改ruby-2.5.5/ext/zlib/Makefile文件中的zlib.o: $(top_srcdir)/include/ruby.h为zlib.o: ../../include/ruby.h

make

make install

拷贝redis-trib.rb命令到/usr/bin/下,方便执行

# cp redis-4.0.14/src/redis-trib.rb /usr/bin/

验证 redis-trib.rb  命令是否可执行:

[root@redis-vm1 ruby-2.5.4]# redis-trib.rb

Usage: redis-trib

create                    host1:port1 … hostN:portN #创建集群

--replicas #指定 master 的副本数量

check                      host:port     #检查集群信息

info                        host:port #查看集群主机信息

fix                          host:port     #修复集群

--timeout

reshard                  host:port #在线热迁移集群指定主机的 slots 数据

--from

--to

--slots

--yes

--timeout

--pipeline

rebalance              host:port #平衡集群中各主机的 slot 数量

--weight

--auto-weights

--use-empty-masters

--timeout

--simulate

--pipeline

--threshold

add-node                new_host:new_port existing_host:existing_port #添加主机到集群

--slave

--master-id

del-node                host:port node_id #删除主机

set-timeout          host:port milliseconds #设置节点的超时时间

call                        host:port command arg arg .. arg #在集群上的所有节点上执行命令

import                     host:port #导入外部 redis 服务器的数据到当前集群

--from

--copy

--replace

help                        (show this help)

[root@redis-vm1 ruby-2.5.5]# vim /usr/local/lib/ruby/gems/2.5.0/gems/redis-4.1.2/lib/redis/client.rb #修改密码为redis  登录密码

创建 redis cluster 集群:

Redis 3/4 版本:

[root@redis-vm1~]# redis-trib.rb create --replicas 1 172.16.99.127:6379 172.16.99.128:6379 172.16.99.129:6379 172.16.99.130:6379 172.16.99.131:6379 172.16.99.132:6379

>>> Creating cluster

>>> Performing hash slots allocation on 6 nodes…

Using 3 masters:

172.16.99.127:6379

172.16.99.128:6379

172.16.99.129:6379

Adding replica 172.16.99.131:6379 to 172.16.99.127:6379

Adding replica 172.16.99.132:6379 to 172.16.99.128:6379

Adding replica 172.16.99.130:6379 to 172.16.99.129:6379

M: a91742cbe5a8a8b2a1ecc108613b20f62ab1f6bc 172.16.99.127:6379

   slots:0-5460 (5461 slots) master

M: 7ddc476c6c44509d3b975fab4fbee47b7a54e2cc 172.16.99.128:6379

   slots:5461-10922 (5462 slots) master

M: d2d51e267ee38502f9abac34afeae1c3e1814db2 172.16.99.129:6379

   slots:10923-16383 (5461 slots) master

S: 9d80a5143c0e899a06c9155439cf0bf7cc9caf74 172.16.99.130:6379

   replicates d2d51e267ee38502f9abac34afeae1c3e1814db2

S: e3f6ad6a03e49fcbca689a5a114529dcb09885c8 172.16.99.131:6379

   replicates a91742cbe5a8a8b2a1ecc108613b20f62ab1f6bc

S: 40342fbde4a93679ef4402852ea4cb6051104664 172.16.99.132:6379

   replicates 7ddc476c6c44509d3b975fab4fbee47b7a54e2cc

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 172.16.99.127:6379)

M: a91742cbe5a8a8b2a1ecc108613b20f62ab1f6bc 172.16.99.127:6379

   slots:0-5460 (5461 slots) master

   1 additional replica(s)

M: 7ddc476c6c44509d3b975fab4fbee47b7a54e2cc 172.16.99.128:6379

   slots:5461-10922 (5462 slots) master

   1 additional replica(s)

M: d2d51e267ee38502f9abac34afeae1c3e1814db2 172.16.99.129:6379

   slots:10923-16383 (5461 slots) master

   1 additional replica(s)

S: 9d80a5143c0e899a06c9155439cf0bf7cc9caf74 172.16.99.130:6379

   slots: (0 slots) slave

   replicates d2d51e267ee38502f9abac34afeae1c3e1814db2

S: 40342fbde4a93679ef4402852ea4cb6051104664 172.16.99.132:6379

   slots: (0 slots) slave

   replicates 7ddc476c6c44509d3b975fab4fbee47b7a54e2cc

S: e3f6ad6a03e49fcbca689a5a114529dcb09885c8 172.16.99.131:6379

   slots: (0 slots) slave

   replicates a91742cbe5a8a8b2a1ecc108613b20f62ab1f6bc

[OK] All nodes agree about slots configuration.

>>> Check for open slots…

>>> Check slots coverage…

[OK] All 16384 slots covered.

如果有之前的操作导致 Redis  集群创建报错,则执行清空数据和集群命令:

127.0.0.1:6379> FLUSHALL  OK

127.0.0.1:6379> cluster reset

OK

Redis 5 版本:

[root@redis-vm1 ~]# redis-cli -a 123456  --cluster create 172.16.99.127:6379 172.16.99.128:6379 172.16.99.129:6379 172.16.99.130:6379 172.16.99.131:6379 172.16.99.132:6379 --cluster-replicas 1

3.2.2.2.3:检查状态:

由于未设置 masterauth 认证密码,所以主从未建立起来,但是集群已经运行,所以需要在每个 slave控制台使用 config set 设置 masterauth 密码,或者写在每个 redis 配置文件中,最好是在控制点设置密码之后再写入配置文件当中。

172.16.99.130:6379> info Replication

# Replication

role:slave

master_host:172.16.99.130

master_port:6379

master_link_status:down

master_last_io_seconds_ago:10

master_sync_in_progress:0

slave_repl_offset:98

slave_priority:100

slave_read_only:1

connected_slaves:0

master_replid:fe4455d2435bdce459365baefaf99b4e6012505b

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:98

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:98

3.2.2.2.4:分别设置 masterauth 密码:

[root@redis-vm1 ~]# redis-cli -h 172.16.99.130 -p 6379 -a 123456

Warning: Using a password with '-a' option on the command line interface may not be safe.

172.16.99.130:6379> CONFIG SET masterauth 123456

OK

[root@redis-vm1 ~]# redis-cli -h 172.16.99.131 -p 6379 -a 123456

Warning: Using a password with '-a' option on the command line interface may not be safe.

172.16.99.131:6379> CONFIG SET masterauth 123456

OK

[root@redis-vm1 ~]# redis-cli -h 172.16.99.132 -p 6379 -a 123456

Warning: Using a password with '-a' option on the command line interface may not be safe.

172.16.99.132:6379> CONFIG SET masterauth 123456

OK

3.2.2.2.5:确认 slave 状态为 up:

172.16.99.130:6379> info Replication

# Replication

role:slave

master_host:172.16.99.129

master_port:6379

master_link_status:up

master_last_io_seconds_ago:10

master_sync_in_progress:0

slave_repl_offset:98

slave_priority:100

slave_read_only:1

connected_slaves:0

master_replid:b038887bf85f8efd42ff581089eff7fa79e94dd0

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:98

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:98

3.2.2.2.6:验证 master 状态:

[root@redis-vm1 ~]# redis-cli    -h 172.16.99.127   -p 6379 -a 123456

# Replication

role:master

connected_slaves:1

slave0:ip=172.16.99.131,port=6379,state=online,offset=420,lag=1

master_replid:fe4455d2435bdce459365baefaf99b4e6012505b

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:420

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:420

3.2.2.2.7:验证集群状态:

172.16.99.127:6379> CLUSTER INFO

cluster_state:ok

cluster_slots_assigned:16384

cluster_slots_ok:16384

cluster_slots_pfail:0

cluster_slots_fail:0

cluster_known_nodes:6

cluster_size:3

cluster_current_epoch:6

cluster_my_epoch:1

cluster_stats_messages_ping_sent:1323

cluster_stats_messages_pong_sent:1436

cluster_stats_messages_sent:2759

cluster_stats_messages_ping_received:1431

cluster_stats_messages_pong_received:1323

cluster_stats_messages_meet_received:5

cluster_stats_messages_received:2759

3.2.2.2.8:查看集群 node 对应关系:

使用命令 cluster nodes:

172.16.99.127:6379> cluster nodes

7ddc476c6c44509d3b975fab4fbee47b7a54e2cc 172.16.99.128:6379@16379 master - 0 1581846649000 2 connected 5461-10922

d2d51e267ee38502f9abac34afeae1c3e1814db2 172.16.99.129:6379@16379 master - 0 1581846650568 3 connected 10923-16383

9d80a5143c0e899a06c9155439cf0bf7cc9caf74 172.16.99.130:6379@16379 slave d2d51e267ee38502f9abac34afeae1c3e1814db2 0 1581846650000 4 connected

40342fbde4a93679ef4402852ea4cb6051104664 172.16.99.132:6379@16379 slave 7ddc476c6c44509d3b975fab4fbee47b7a54e2cc 0 1581846649000 6 connected

a91742cbe5a8a8b2a1ecc108613b20f62ab1f6bc 172.16.99.127:6379@16379 myself,master - 0 1581846649000 1 connected 0-5460

e3f6ad6a03e49fcbca689a5a114529dcb09885c8 172.16.99.131:6379@16379 slave a91742cbe5a8a8b2a1ecc108613b20f62ab1f6bc 0 1581846648000 5 connected

3.2.2.2.9:验证集群写入 key:

172.16.99.127:6379> SET key1  value1    #经过算法计算,当前 key 的槽位需要写入指定的 node

(error) MOVED 9189 172.16.99.128:6379 #槽位不在当前 node 所以无法写入

172.16.99.129:6379> SET key1  value1  (error) MOVED 9189  172.16.99.128:6379

172.16.99.128:6379> SET key1  value1 #指定的 node 就可以写入

OK

172.16.99.128:6379> KEYS *

1) "key1"

172.16.99.127:6379> KEYS  * (empty list or set)

172.16.99.129:6379> KEYS  * (empty list or set)

3.2.2.2.10:集群状态监控:

Redis 4: 

[root@redis-vm1 ~]# redis-trib.rb check 172.16.99.127:6379

>>> Performing Cluster Check (using node 172.16.99.127:6379)

M: a91742cbe5a8a8b2a1ecc108613b20f62ab1f6bc 172.16.99.127:6379

   slots:0-5460 (5461 slots) master

   1 additional replica(s)

M: 7ddc476c6c44509d3b975fab4fbee47b7a54e2cc 172.16.99.128:6379

   slots:5461-10922 (5462 slots) master

   1 additional replica(s)

M: d2d51e267ee38502f9abac34afeae1c3e1814db2 172.16.99.129:6379

   slots:10923-16383 (5461 slots) master

   1 additional replica(s)

S: 9d80a5143c0e899a06c9155439cf0bf7cc9caf74 172.16.99.130:6379

   slots: (0 slots) slave

   replicates d2d51e267ee38502f9abac34afeae1c3e1814db2

S: 40342fbde4a93679ef4402852ea4cb6051104664 172.16.99.132:6379

   slots: (0 slots) slave

   replicates 7ddc476c6c44509d3b975fab4fbee47b7a54e2cc

S: e3f6ad6a03e49fcbca689a5a114529dcb09885c8 172.16.99.131:6379

   slots: (0 slots) slave

   replicates a91742cbe5a8a8b2a1ecc108613b20f62ab1f6bc

[OK] All nodes agree about slots configuration.

>>> Check for open slots…

>>> Check slots coverage…

[OK] All 16384 slots covered.

[root@redis-vm1 ~]# redis-trib.rb info 172.16.99.127:6379

172.16.99.127:6379 (a91742cb…) -> 0 keys | 5461 slots | 1 slaves.

172.16.99.128:6379 (7ddc476c…) -> 0 keys | 5462 slots | 1 slaves.

172.16.99.129:6379 (d2d51e26…) -> 0 keys | 5461 slots | 1 slaves.

[OK] 0 keys in 3 masters.

0.00 keys per slot on average.

Redis 5:

# redis-cli -a 123456   --cluster check 172.16.99.127:6379

热门专题

map list嵌套取值

S4类设定泛型函数的函数名

r语言如何将csv文件的值以矩阵形式取出来

mysql *100 浮点数溢出

红米6 pro root

安卓8 发送广播 ComponentName

html元素包含判断

virtualbox 后台运行 centos

谷歌浏览器无法向下滚动

获取一个div的高度

AD域如何看下发的脚本有没有执行

把外部可变对象引用存储到对象的内部

vue三级路由嵌套会刷新二级路由

ffmpeg 设置timeout

cglib 空指针报错

unity键盘控制人物转向

jquery如何拿到标签属性值

wordpress ajax 获取不到 user_id

ubuntu的共享文件夹在哪

renren security 部署