Redis 之 (4) redis集群介绍、搭建配置、操作

19. redis集群介绍

  • 集群概念应该不陌生了,多台机器组成,用来解决像存储空间,查询速度,负载等提供一个或多个服务支持!
  • Redis集群 是一个分布式的一种架构,支持横向扩展,也就是说之前咱们配置的LVS+keepalived需要配置好基础环境,然后加入到集群系统。现在的Redis分布式,是**只需要把Redis这个集群配置到当前配置内就可以自动的去工作了~ **

Redis Cluster设计要点

  • redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

  • 那么redis 是如何合理分配这些节点和数据的呢?

  • Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。

  • 注意的是:必须要3个以后的主节点,否则在创建集群时会失败,我们在后续会实践到。

  • 所以,我们假设现在有3个节点已经组成了集群,分别是:A, B, C 三个节点,它们可以是一台机器上的三个端口,也可以是三台不同的服务器。那么,采用哈希槽 (hash slot)的方式来分配16384个slot 的话,它们三个节点分别承担的slot 区间是:

  • 节点A覆盖0-5460; 节点B覆盖5461-10922; 节点C覆盖10923-16383. 如下图所示:

那么,现在我想设置一个key ,比如叫my_name:

  • set my_name xyz 按照redis cluster的哈希槽算法:CRC16(‘my_name’)%16384 = 2412。 那么就会把这个key 的存储分配到 A 上了。
  • 同样,当我连接(A,B,C)任何一个节点想获取my_name这个key时,也会这样的算法,然后内部跳转到B节点上获取数据。
  • 这种哈希槽的分配方式有好也有坏,好处就是很清晰,比如我想新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot到D上,我会在接下来的实践中实验。大致就会变成这样:
  • 节点A覆盖1365-5460 节点B覆盖6827-10922 节点C覆盖12288-16383 节点D覆盖0-1364,5461-6826,10923-12287 同样删除一个节点也是类似,移动完成后就可以删除这个节点了。
  • 所以redis cluster 就是这样的一个形状:

Redis cluster是分布式集群,支持横向扩展,Redis从V3.0版本后才支持集群功能。Redis集群的工作原理类似于磁盘的raid5。

  • 多个redis节点网络互联,数据共享。
  • 所有的节点都是一主一从(可以是多个从),其中从不提供服务,仅作为备用(主一旦宕机,从马上顶替工作!)。
  • 不支持同时处理多个键(如mset/mget),因为redis需要把键均匀分布在各个节点上,并发量很高的情况下同时创建键值会降低性能并导致不可预测的行为。
  • 支持在线增加、删除节点。
  • 客户端可以连任何一个主节点进行读写。

误区: 好多人会认为Redis集群上的数据都是一致的,大错特错!Redis 上面的数据是共享式的,也就是A server有的B server不一定有。类似于Raid 5,写入数据可能是A磁盘 可能是B磁盘。你可以正常读取,但真正的存储位置你是不晓得在哪儿的!

20. redis集群搭建配置

1 场景设置

  • 两台机器,分别开启三个Redis服务(端口)
  • A机器上三个端口:7000、7002、7004,全部为主
  • B机器上三个端口:7001、7003、7005,全部为从
  • 两台机器上都要编译安装Redis,然后编译并复制三个不同的Redis.conf,分别设置不同的端口号、dir等参数,还需要增加cluster相关参数,然后分别启动6个Redis服务
  • **注意:**一定需要关闭selinux,iptables放行对应端口

2 安装Ruby v2.2(master)

Redis集群需要ruby的支持,需要先安装ruby(Ruby只需在一台机器上运行)。 Redis4.0需要使用Ruby2.2,安装方法如下(因为本机自带的是2.0版本的ruby,所以需要使用如下方法把源码包包制作成yum安装包,然后借助yum工具安装ruby2.2——升级ruby版本)

安装yum开发工具组:
[root@yt-01 ~]# yum -y groupinstall "Development Tools"

升级库文件:
[root@yt-01 ~]# yum -y install gdbm-devel libdb4-devel libffi-devel libyaml libyaml-devel ncurses-devel openssl-devel readline-devel tcl-devel

[root@yt-01 ~]# cd /root/

创建制作rpm包的目录:
[root@yt-01 ~]# mkdir -p rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}

下载Ruby的源码包:
[root@yt-01 ~]# wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.3.tar.gz -P rpmbuild/SOURCES

下载specs文件,用于制作rpm包:
[root@yt-01 ~]# wget https://raw.githubusercontent.com/tjinjin/automate-ruby-rpm/master/ruby22x.spec -P rpmbuild/SPECS

制作rpm包:
[root@yt-01 ~]# rpmbuild -bb rpmbuild/SPECS/ruby22x.spec
#此处需要耐心等待,大约需要5分钟

安装Ruby2.2:
[root@yt-01 ~]# yum -y localinstall rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.centos.x86_64.rpm
[root@yt-01 ~]# ruby -v
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]

注意: 除此方法之外,还可以编译安装ruby。 好了,ruby 2.2已经安装完成。

3 准备机器master(ip:192.168.122.130)

[root@yt-01 ~]# vim /etc/redis_7000.conf
port 7000
bind 192.168.122.130
daemonize yes
pidfile /var/run/redis_7000.pid
dir /data/redis_data/7000
cluster-enabled yes
#开启cluster功能
cluster-config-file nodes_7000.conf
#该配置文件可以在dir目录下自动生成
cluster-node-timeout 10100
appendonly yes

[root@yt-01 ~]# vim /etc/redis_7002.conf
port 7002
bind 192.168.122.130
daemonize yes
pidfile /var/run/redis_7002.pid
dir /data/redis_data/7002
cluster-enabled yes
cluster-config-file nodes_7002.conf
cluster-node-timeout 10100
appendonly yes

[root@yt-01 ~]# vim /etc/redis_7004.conf
port 7004
bind 192.168.122.130
daemonize yes
pidfile /var/run/redis_7004.pid
dir /data/redis_data/7004
cluster-enabled yes
cluster-config-file nodes_7004.conf
cluster-node-timeout 10100
appendonly yes

创建各配置文件对应的数据库目录:
[root@yt-01 ~]# mkdir /data/redis_data
[root@yt-01 ~]# mkdir /data/redis_data/{7000,7002,7004}

依次启动Redis服务7000,7002,7004:
[root@yt-01 ~]# redis-server /etc/redis_7000.conf
33019:C 08 Apr 11:37:10.782 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
33019:C 08 Apr 11:37:10.782 # Redis version=4.0.9, bits=64, commit=00000000, modified=0, pid=33019, just started
33019:C 08 Apr 11:37:10.782 # Configuration loaded
[root@yt-01 ~]# redis-server /etc/redis_7002.conf
[root@yt-01 ~]# redis-server /etc/redis_7004.conf

启动完成后,结果如下:
[root@yt-01 ~]# ps aux |grep redis
root 33020 0.0 0.1 145264 2632 ? Ssl 11:37 0:00 redis-server 192.168.122.130:7000 [cluster]
root 33032 0.0 0.1 145264 2628 ? Ssl 11:37 0:00 redis-server 192.168.122.130:7002 [cluster]
root 33054 0.0 0.1 145264 2644 ? Ssl 11:37 0:00 redis-server 192.168.122.130:7004 [cluster]

4 准备slave(IP:192168.122.131)

安装redis
先在yt-01上传redis到yt-02上
[root@yt-01 ~]# cd /usr/local/src/
[root@yt-01 src]# ll
[root@yt-01 src]# scp -r redis-4.0.9 192.168.122.131:/usr/local/src/
[email protected]'s password:
在yt-02上
[root@yt-02 ~]# cd /usr/local/src
[root@yt-02 src]# ll
[root@yt-02 src]# cd redis-4.0.9/
[root@yt-02 redis-4.0.9]# make install 
cd src && make install
make[1]: 进入目录“/usr/local/src/redis-4.0.9/src”
Hint: It's a good idea to run 'make test' ;)
    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
make[1]: 离开目录“/usr/local/src/redis-4.0.9/src”
# 因为之前在yt-01上编译过,这里只需要install就可以了

[root@yt-02 ~]# vim /etc/redis_7001.conf
port 7001
bind 192.168.122.131
daemonize yes
pidfile /var/run/redis_7001.pid
dir /data/redis_data/7001
cluster-enabled yes
cluster-config-file nodes_7001.conf
cluster-node-timeout 10100
appendonly yes

[root@yt-02 ~]# vim /etc/redis_7003.conf
port 7003
bind 192.168.122.131
daemonize yes
pidfile /var/run/redis_7003.pid
dir /data/redis_data/7003
cluster-enabled yes
cluster-config-file nodes_7003.conf
cluster-node-timeout 10100
appendonly yes

[root@yt-02 ~]# vim /etc/redis_7005.conf
port 7005
bind 192.168.122.131
daemonize yes
pidfile /var/run/redis_7005.pid
dir /data/redis_data/7005
cluster-enabled yes
cluster-config-file nodes_7005.conf
cluster-node-timeout 10100
appendonly yes

创建各配置文件对应的数据库目录:
[root@yt-02 ~]# mkdir /data/redis_data
[root@yt-02 ~]# mkdir /data/redis_data/{7001,7003,7005}

依次启动Redis服务7001,7003,7005:
[root@yt-02 ~]# redis-server /etc/redis_7001.conf
[root@yt-02 ~]# redis-server /etc/redis_7003.conf
[root@yt-02 ~]# redis-server /etc/redis_7005.conf

启动完成后结果如下:
[root@yt-02 ~]# ps aux |grep redis
root 25413 0.0 0.4 145264 7564 ? Ssl 11:50 0:00 redis-server 192.168.122.131:7001 [cluster]
root 25418 0.0 0.4 145264 7564 ? Ssl 11:50 0:00 redis-server 192.168.122.131:7003 [cluster]
root 25427 0.0 0.4 145264 7564 ? Ssl 11:50 0:00 redis-server 192.168.122.131:7005 [cluster]

5 配置redis集群

安装Redis配置集群的工具:
[root@yt-01 ~]# gem install redis

将命令redis-trib.rb加入环境变量目录下:
[root@yt-01 ~]# cp /usr/local/src/redis-4.0.2/src/redis-trib.rb /usr/bin/
[root@yt-01 ~]# redis-trib.rb create --replicas 1 192.168.122.130:7000 192.168.122.130:7002 192.168.122.130:7004 192.168.122.131:7001 192.168.122.131:7003 192.168.122.131:7005
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.122.130:7000
192.168.122.131:7001
192.168.122.130:7002
Adding replica 192.168.122.131:7005 to 192.168.122.130:7000
Adding replica 192.168.122.130:7004 to 192.168.122.131:7001
Adding replica 192.168.122.131:7003 to 192.168.122.130:7002
M: 8c76e2bcb05c8d911b57989b973376a1a4ae8d0e 192.168.122.130:7000
   slots:0-5460 (5461 slots) master
M: 89b6e94a7c8c5b3660aa94b8492ebf2bb8684b5b 192.168.122.130:7002
   slots:10923-16383 (5461 slots) master
S: 702d2db77c3a9a5e5b5a2fb3348e5a894479ad93 192.168.122.130:7004
   replicates c097cca2ac912c6d867336683d31cf4dbdbb8818
M: c097cca2ac912c6d867336683d31cf4dbdbb8818 192.168.122.131:7001
   slots:5461-10922 (5462 slots) master
S: 3ef5d3b9a607259ff7b57f722c9eda9b38a1b083 192.168.122.131:7003
   replicates 89b6e94a7c8c5b3660aa94b8492ebf2bb8684b5b
S: 0e3946acca8ee2f093ea5951591b592a9bee4d45 192.168.122.131:7005
   replicates 8c76e2bcb05c8d911b57989b973376a1a4ae8d0e
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.122.130:7000)
M: 8c76e2bcb05c8d911b57989b973376a1a4ae8d0e 192.168.122.130:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 89b6e94a7c8c5b3660aa94b8492ebf2bb8684b5b 192.168.122.130:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 702d2db77c3a9a5e5b5a2fb3348e5a894479ad93 192.168.122.130:7004
   slots: (0 slots) slave
   replicates c097cca2ac912c6d867336683d31cf4dbdbb8818
S: 3ef5d3b9a607259ff7b57f722c9eda9b38a1b083 192.168.122.131:7003
   slots: (0 slots) slave
   replicates 89b6e94a7c8c5b3660aa94b8492ebf2bb8684b5b
S: 0e3946acca8ee2f093ea5951591b592a9bee4d45 192.168.122.131:7005
   slots: (0 slots) slave
   replicates 8c76e2bcb05c8d911b57989b973376a1a4ae8d0e
M: c097cca2ac912c6d867336683d31cf4dbdbb8818 192.168.122.131:7001
   slots:5461-10922 (5462 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.

# 注意:redis-trib.rb create --replicas 1 表示一个master对应几个slave,此处的参数“1”表示master和slave一一对应
# 主从是redis-trib.rb自动分配的

Redis集群配置完成!

21. redis集群操作

1 连接redis集群

因为Redis集群是分布式结构,所以可以连接任何一个端口。

连接:
[root@yt-02 ~]# redis-cli -c -h 192.168.122.130 -p 7000
#-c:=cluster,表示以集群方式连接

创建数据:
192.168.122.130:7000> set key1 123
-> Redirected to slot [9189] located at 192.168.122.131:7001
OK
#该操作会被重定向到192.168.122.131:7001

192.168.122.131:7001> set key2 abc
-> Redirected to slot [4998] located at 192.168.122.130:7000
OK
192.168.122.130:7000> set key3 cbd
OK
# 该操作会被重定向到本地

192.168.122.130:7000> set key5 test5
-> Redirected to slot [9057] located at 192.168.122.131:7001
OK

查看数据:
192.168.122.130:7000> get key1
-> Redirected to slot [9189] located at 192.168.122.131:7001
"123"
192.168.122.131:7001> get key2
-> Redirected to slot [4998] located at 192.168.122.130:7000
"abc"
192.168.122.130:7000> get key3
"cbd"
192.168.122.130:7000> get key4
-> Redirected to slot [13120] located at 192.168.122.130:7002
(nil)
192.168.122.130:7002> get key5
-> Redirected to slot [9057] located at 192.168.122.131:7001
"test5"

2 集群的操作

查看集群的状态:
[root@yt-01 ~]# redis-trib.rb check 192.168.122.130:7000
>>> Performing Cluster Check (using node 192.168.122.130:7000)
M: 8c76e2bcb05c8d911b57989b973376a1a4ae8d0e 192.168.122.130:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 89b6e94a7c8c5b3660aa94b8492ebf2bb8684b5b 192.168.122.130:7002
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 702d2db77c3a9a5e5b5a2fb3348e5a894479ad93 192.168.122.130:7004
   slots: (0 slots) slave
   replicates c097cca2ac912c6d867336683d31cf4dbdbb8818
S: 3ef5d3b9a607259ff7b57f722c9eda9b38a1b083 192.168.122.131:7003
   slots: (0 slots) slave
   replicates 89b6e94a7c8c5b3660aa94b8492ebf2bb8684b5b
S: 0e3946acca8ee2f093ea5951591b592a9bee4d45 192.168.122.131:7005
   slots: (0 slots) slave
   replicates 8c76e2bcb05c8d911b57989b973376a1a4ae8d0e
M: c097cca2ac912c6d867336683d31cf4dbdbb8818 192.168.122.131:7001
   slots:5461-10922 (5462 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@yt-01 ~]# redis-cli -c -h 192.168.122.130 -p 7000
192.168.122.130:7000> cluster nodes
89b6e94a7c8c5b3660aa94b8492ebf2bb8684b5b 192.168.122.130:7002@17002 master - 0 1523160379000 2 connected 10923-16383
702d2db77c3a9a5e5b5a2fb3348e5a894479ad93 192.168.122.130:7004@17004 slave c097cca2ac912c6d867336683d31cf4dbdbb8818 0 1523160380000 4 connected
8c76e2bcb05c8d911b57989b973376a1a4ae8d0e 192.168.122.130:7000@17000 myself,master - 0 1523160380000 1 connected 0-5460
3ef5d3b9a607259ff7b57f722c9eda9b38a1b083 192.168.122.131:7003@17003 slave 89b6e94a7c8c5b3660aa94b8492ebf2bb8684b5b 0 1523160378767 5 connected
0e3946acca8ee2f093ea5951591b592a9bee4d45 192.168.122.131:7005@17005 slave 8c76e2bcb05c8d911b57989b973376a1a4ae8d0e 0 1523160378000 6 connected
c097cca2ac912c6d867336683d31cf4dbdbb8818 192.168.122.131:7001@17001 master - 0 1523160377000 4 connected 5461-10922

查看集群信息:
192.168.122.130:7000> 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:548
cluster_stats_messages_pong_sent:581
cluster_stats_messages_sent:1129
cluster_stats_messages_ping_received:576
cluster_stats_messages_pong_received:548
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:1129

添加节点(执行该操作前先在slave创建redis_7007.conf并启动):
192.168.122.130:7000> cluster meet 192.168.122.131 7007
OK
192.168.122.130:7000> cluster nodes
84fa982c0a3314bb239eeba869238502752d2682 192.168.122.131:7007@17007 master - 0 1523160579000 0 connected
##此时7007以master身份存在

再添加一个节点:
192.168.122.130:7000> cluster meet 192.168.122.130 7006
OK
192.168.122.130:7000> cluster nodes
1daa74e086e82eee1dd091189f1a06547a149e26 192.168.122.130:7006@17006 master - 0 1523160976000 7 connected
#也是以master身份存在
#使用以上方式添加的新节点都是以master身份存在!

将当前节点设置为指定节点的从

先更换到要设置的节点:
[root@yt-01 ~]# redis-cli -c -h 192.168.122.130 -p 7006

设定为7007的从:
192.168.122.130:7006> cluster replicate 84fa982c0a3314bb239eeba869238502752d2682
OK

查看:
192.168.122.130:7006> cluster nodes
1daa74e086e82eee1dd091189f1a06547a149e26 192.168.122.130:7006@17006 myself,slave 84fa982c0a3314bb239eeba869238502752d2682 0 1523161084000 7 connected
84fa982c0a3314bb239eeba869238502752d2682 192.168.122.131:7007@17007 master - 0 1523161084000 0 connected
#对比node号,即7006为7007的从。。

移除某节点:
192.168.122.130:7006> cluster forget 84fa982c0a3314bb239eeba869238502752d2682
(error) ERR Can't forget my master!
192.168.122.130:7006> 1daa74e086e82eee1dd091189f1a06547a149e26
(error) ERR I tried hard but I can't forget myself...
# 从节点不能移除master节点和也不能移除自己

切换到一个主节点
[root@yt-01 ~]# redis-cli -c -h 192.168.122.130 -p 7000
192.168.122.130:7000> cluster forget 677f27fb209ce45c823126fe38dbcf0b9fc43d93
OK

查看:
192.168.122.130:7000> cluster nodes
#此时7006已经不存在了。

保存当前配置:
192.168.122.130:7000> CLUSTER SAVECONFIG
OK

猜你喜欢

转载自my.oschina.net/zhouyuntai/blog/1791163