[NoSQL数据库] Redis集群部署

时间:2021-07-16 02:48:29

一、Redis集群配置

为每一个集群的节点准备一个配置文件:

# 7000.conf
port 7000
bind 192.168.1.181
daemonize yes
pidfile 7000.pid
cluster-enabled yes
cluster-config-file 7000_node.conf
cluster-node-timeout 15000
appendonly yes
# 7001.conf
port 7001
bind 192.168.1.181
daemonize yes
pidfile 7001.pid
cluster-enabled yes
cluster-config-file 7001_node.conf
cluster-node-timeout 15000
appendonly yes
# 7002.conf
port 7002
bind 192.168.1.181
daemonize yes
pidfile 7002.pid
cluster-enabled yes
cluster-config-file 7002_node.conf
cluster-node-timeout 15000
appendonly yes

以上三个配置文件都在192.168.1.181机器上,三个集群节点分别绑定的端口为7000、7001、7002。相当于三台redis服务器。

 

在另外一台机器192.168.1.180上,同样也准备三个redis服务:

# 7003.conf
port 7003
bind 192.168.1.180
daemonize yes
pidfile 7003.pid
cluster-enabled yes
cluster-config-file 7003_node.conf
cluster-node-timeout 15000
appendonly yes
# 7004.conf
port 7004
bind 192.168.1.180
daemonize yes
pidfile 7004.pid
cluster-enabled yes
cluster-config-file 7004_node.conf
cluster-node-timeout 15000
appendonly yes
# 7005.conf
port 7005
bind 192.168.1.180
daemonize yes
pidfile 7005.pid
cluster-enabled yes
cluster-config-file 7005_node.conf
cluster-node-timeout 15000
appendonly yes

这三个redis服务跑在192.168.1.180机器上,使用7003、7004、7005端口。

 

二、运行Redis节点

使用第一节中的6个配置文件,分别在两台机器上启动6个redis实例(服务)。

[[email protected] ~]# redis-server ./7000.conf 
1855:C 05 Jan 2020 22:29:55.465 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1855:C 05 Jan 2020 22:29:55.465 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=1855, just started
1855:C 05 Jan 2020 22:29:55.465 # Configuration loaded
[[email protected]-base ~]# redis-server ./7001.conf  
1860:C 05 Jan 2020 22:30:01.587 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1860:C 05 Jan 2020 22:30:01.587 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=1860, just started
1860:C 05 Jan 2020 22:30:01.587 # Configuration loaded
[[email protected]-base ~]# redis-server ./7002.conf  
1865:C 05 Jan 2020 22:30:03.438 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1865:C 05 Jan 2020 22:30:03.438 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=1865, just started
1865:C 05 Jan 2020 22:30:03.438 # Configuration loaded
[[email protected] ~]# redis-server ./7003.conf 
21201:C 05 Jan 2020 22:35:57.144 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
21201:C 05 Jan 2020 22:35:57.144 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=21201, just started
21201:C 05 Jan 2020 22:35:57.144 # Configuration loaded
[[email protected]-base ~]# redis-server ./7004.conf  
21206:C 05 Jan 2020 22:35:59.415 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
21206:C 05 Jan 2020 22:35:59.415 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=21206, just started
21206:C 05 Jan 2020 22:35:59.415 # Configuration loaded
[[email protected]-base ~]# redis-server ./7005.conf  
21211:C 05 Jan 2020 22:36:01.211 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
21211:C 05 Jan 2020 22:36:01.211 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=21211, just started
21211:C 05 Jan 2020 22:36:01.211 # Configuration loaded

查看进程:

root       1856      1  0 22:29 ?        00:00:00 redis-server 192.168.1.181:7000 [cluster]
root       1861      1  0 22:30 ?        00:00:00 redis-server 192.168.1.181:7001 [cluster]
root       1866      1  0 22:30 ?        00:00:00 redis-server 192.168.1.181:7002 [cluster]
root       1871   1403  0 22:30 pts/0    00:00:00 grep --color=auto redis
root      21202      1  0 22:35 ?        00:00:00 redis-server 192.168.1.180:7003 [cluster]
root      21207      1  0 22:35 ?        00:00:00 redis-server 192.168.1.180:7004 [cluster]
root      21212      1  0 22:36 ?        00:00:00 redis-server 192.168.1.180:7005 [cluster]
root      21217   9126  0 22:36 pts/0    00:00:00 grep --color=auto redis

 

三、创建集群

1.创建集群

执行以下命令创建集群:

[[email protected] src]# redis-cli --cluster create --cluster-replicas 1 192.168.1.181:7000 192.168.1.181:7001 192.168.1.181:7002 192.168.1.180:7003 192.168.1.180:7004 192.168.1.180:7005       
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.1.180:7005 to 192.168.1.181:7000
Adding replica 192.168.1.181:7002 to 192.168.1.180:7003
Adding replica 192.168.1.180:7004 to 192.168.1.181:7001 M: 0e8ad6ec3c1dbd9bc4aa7571717b98f2eddfae7f 192.168.1.181:7000 slots:[0-5460] (5461 slots) master M: b42102dab52497b36ed5b768b01463b09f7e7eab 192.168.1.181:7001 slots:[10923-16383] (5461 slots) master
S: 75a547cdad955d5b77812fb7db7b276594cdcde2 192.168.1.181:7002
   replicates 6fa4cbb6d52841c91a0e9f747e5b906a8b6f10b1
M: 6fa4cbb6d52841c91a0e9f747e5b906a8b6f10b1 192.168.1.180:7003 slots:[5461-10922] (5462 slots) master
S: 00e3e7ed62c230ebbafb15ab5a7194ca28221112 192.168.1.180:7004
   replicates b42102dab52497b36ed5b768b01463b09f7e7eab
S: 240f6cc79a637db17d35d39edd42475484ca56ad 192.168.1.180:7005
   replicates 0e8ad6ec3c1dbd9bc4aa7571717b98f2eddfae7f
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.1.181:7000)
M: 0e8ad6ec3c1dbd9bc4aa7571717b98f2eddfae7f 192.168.1.181:7000
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: b42102dab52497b36ed5b768b01463b09f7e7eab 192.168.1.181:7001
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 6fa4cbb6d52841c91a0e9f747e5b906a8b6f10b1 192.168.1.180:7003
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 240f6cc79a637db17d35d39edd42475484ca56ad 192.168.1.180:7005
   slots: (0 slots) slave
   replicates 0e8ad6ec3c1dbd9bc4aa7571717b98f2eddfae7f
S: 75a547cdad955d5b77812fb7db7b276594cdcde2 192.168.1.181:7002
   slots: (0 slots) slave
   replicates 6fa4cbb6d52841c91a0e9f747e5b906a8b6f10b1
S: 00e3e7ed62c230ebbafb15ab5a7194ca28221112 192.168.1.180:7004
   slots: (0 slots) slave
   replicates b42102dab52497b36ed5b768b01463b09f7e7eab
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

注意,在命令中,我们使用了 --cluster-replicas 1 ,这个表示每一个主节点配一个从节点。所以将6个redis实例,分成了3个主,3个从。

其中主节点为7000、7001、7003。他们的从节点分别是:7005、7004、7002。

 

2.槽(slots)

注意,redis一共有16384个slots,用于存储数据。

当我们只有一个redis服务的时候,所有的数据都存放在这些槽里面。

而当我们使用集群的时候,例如上述的3个主节点,那么这16384个槽会分配到三台主节点中。(注意上述命令中标黄的部分)

 

当我们向集群中存储数据的时候,例如:

set name leo

Redis会通过CRC16算法来计算name对应的值,然后再除以16384,余数就是对应该存放的slot编号(公式:CRC16(key)384)。然后根据这个编号去连接对应的主节点,进行存储。

 

我们随便连接一个redis实例(在集群中,连接任何一个实例都相当于连接到了集群),并执行set name leo:

[[email protected] src]# redis-cli -h 192.168.1.181 -c -p 7002
192.168.1.181:7002> set name leo
-> Redirected to slot [5798] located at 192.168.1.180:7003
OK
192.168.1.180:7003> 

可以看到,我们连接的192.168.1.181:7002其实属于slave,使用-c表示连接到集群,否则会报错。当执行set name leo的时候,redis计算到name对应的slot编号为5798,对应的是192.168.1.180:7003主节点。

然后自动跳转连接了192.168.1.180:7003,并存储了数据。

 

3.主从切换

当某个主节点宕机的时候,与他连接的从节点会自动变为主节点。

例如,我们杀掉192.168.1.181:7000的redis进程:

[[email protected] src]# kill -9 1856
[[email protected]-base src]# ps -ef | grep redis
root       1861      1  0 22:30 ?        00:00:04 redis-server 192.168.1.181:7001 [cluster]
root       1866      1  0 22:30 ?        00:00:04 redis-server 192.168.1.181:7002 [cluster]
root       1906   1403  0 22:56 pts/0    00:00:00 grep --color=auto redis

 

此时,我们查看7000对应slave节点192.168.1.180:7005的状态:

[[email protected] src]# redis-cli -h 192.168.1.180 -p 7005 info replication 
# Replication
role:master
connected_slaves:0
master_replid:43d5b373d03e9a1ef4853b60c0504e25a562a62a
master_replid2:97def7c7993bcfbcbb6105aef2e86ae51190d236
master_repl_offset:1148
second_repl_offset:1149
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1148

可以看到7005已经变成了主节点。

 

如果此时,7000重新上线,则会作为7005的Slave节点存在:

[[email protected] ~]# redis-cli -h 192.168.1.181 -p 7000 info replication   
# Replication
role:slave master_host:192.168.1.180 master_port:7005
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:1176
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:43d5b373d03e9a1ef4853b60c0504e25a562a62a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1176
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1149
repl_backlog_histlen:28

 

4.集群注意事项

注意:集群必须存在3个以及3个以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点的一半时,整个集群就无法提供服务了。

 

5.Python操作Redis集群

安装redis-py-cluster:

pip install redis-py-cluster

使用python连接集群:

from rediscluster import RedisCluster

if __name__ == __main__:
    try:
        startup_nodes = [
            # 这里可以将所有的主总节点都写上
            {host: 192.168.1.181, port: 7000},
            {host: 192.168.1.181, port: 7001},
            {host: 192.168.1.181, port: 7002},
            {host: 192.168.1.180, port: 7003},
            {host: 192.168.1.180, port: 7004},
            {host: 192.168.1.180, port: 7005},
        ]

        src = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
        res = src.set(name, leo)
        print(res)
    except Exception as e:
        print(e)

对集群的操作和对单个redis的操作是一样的。