redis cluster集群

## 13.1 介绍

### 1.实现高性能
1、在多分片redis节点中,将16384个内存槽位,均匀分布到多个Redis分片节点中。

2、存取数据时,将key做crc16(key)计算生成一个数字,然后和16384进行取模,得出槽位值(0-16383之间)。

3、根据计算得出的槽位值,找到相对应的分片节点的主节点,到相应槽位上存取数据。

4、如果客户端当时连接的节点不是将来要存储的分片节点,分片集群会将客户端连接切换至真正存储节点进行数据存储


### 2.高可用

1、在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof的功能。

2、同时当主节点宕机,实现类似于sentinel的自动failover功能,所有分片节点参与投票选举。

3、redis会有多组分片构成(一般至少3组)。

4、redis cluster使用固定个数slot存储数据(一共16384slot)

5、每组分片节点分得1/3槽位,slot个数分别(0-5460/5461-10922/10923-16383)

6、基于CRC16(key)%16384计算的值,到对应相应的槽位号存取数据。

## 13.2 规划、搭建过程:
### 1.规划

1.6个redis实例,放到3台硬件服务器。
注:一组redis分片的主从节点要分到不同物理机,防止硬件主机宕机造成的整个分片数据丢失。


2.端口号:7000-7005共6个节点


### 2.安装集群插件
#EPEL源安装ruby支持
yum install ruby rubygems -y

#使用国内源
gem sources -l
gem sources -a http://mirrors.aliyun.com/rubygems/ 
gem sources  --remove https://rubygems.org/
gem sources -l
gem install redis -v 3.3.3
##1 gem installed表示成功

### 3.搭建6个redis集群节点
====redis集群节点特殊配置============
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
================================

mkdir /data/700{0..5}
cat > /data/7000/redis.conf <<EOF
port 7000
daemonize yes
pidfile /data/7000/redis.pid
loglevel notice
logfile "/data/7000/redis.log"
dbfilename dump.rdb
dir /data/7000
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF

cat >> /data/7001/redis.conf <<EOF
port 7001
daemonize yes
pidfile /data/7001/redis.pid
loglevel notice
logfile "/data/7001/redis.log"
dbfilename dump.rdb
dir /data/7001
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF

cat >> /data/7002/redis.conf <<EOF
port 7002
daemonize yes
pidfile /data/7002/redis.pid
loglevel notice
logfile "/data/7002/redis.log"
dbfilename dump.rdb
dir /data/7002
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF


cat >>  /data/7003/redis.conf <<EOF
port 7003
daemonize yes
pidfile /data/7003/redis.pid
loglevel notice
logfile "/data/7003/redis.log"
dbfilename dump.rdb
dir /data/7003
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF


cat >> /data/7004/redis.conf <<EOF
port 7004
daemonize yes
pidfile /data/7004/redis.pid
loglevel notice
logfile "/data/7004/redis.log"
dbfilename dump.rdb
dir /data/7004
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF

cat >> /data/7005/redis.conf <<EOF
port 7005
daemonize yes
pidfile /data/7005/redis.pid
loglevel notice
logfile "/data/7005/redis.log"
dbfilename dump.rdb
dir /data/7005
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF

### 4.启动各节点:

redis-server /data/7000/redis.conf 
redis-server /data/7001/redis.conf 
redis-server /data/7002/redis.conf 
redis-server /data/7003/redis.conf 
redis-server /data/7004/redis.conf 
redis-server /data/7005/redis.conf 

[root@db01 ~]# ps -ef|grep redis|grep 700
root       1943      1  0 20:43 ?        00:00:00 redis-server *:7000 [cluster]
root       1945      1  0 20:43 ?        00:00:00 redis-server *:7001 [cluster]
root       1949      1  0 20:43 ?        00:00:00 redis-server *:7002 [cluster]
root       1953      1  0 20:43 ?        00:00:00 redis-server *:7003 [cluster]
root       1959      1  0 20:43 ?        00:00:00 redis-server *:7004 [cluster]
root       1963      1  0 20:43 ?        00:00:00 redis-server *:7005 [cluster]
 

###5. 将节点加入集群管理

redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005


#--replicas 1 是每个分片从节点的个数
#4.0以上有内部命令支持

###6. 集群状态查看

#集群主节点状态
redis-cli -p 7000 cluster nodes | grep master

[root@db01 ~]# redis-cli -p 7000 cluster nodes | grep master
c51a10072025d6435e78cdf688384361400a2079 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
e98ffc05aa00b33db727a099d28929f1f6faf981 127.0.0.1:7001 master - 0 1652015336664 2 connected 5461-10922
239f13a9ad57ade3945a35da501d2defcb99cfcf 127.0.0.1:7002 master - 0 1652015336664 3 connected 10923-16383
                节点ID                                                                        槽位


#集群从节点状态
[root@db01 ~]# redis-cli -p 7000 cluster nodes | grep slave
60b40045d67ca9b842eee36c8a7790c95a86831e 127.0.0.1:7003 slave c51a10072025d6435e78cdf688384361400a2079 0 1652015424368 4 connected
2303048abba7c02ea1bcc289dc2963e85d4a1e66 127.0.0.1:7005 slave 239f13a9ad57ade3945a35da501d2defcb99cfcf 0 1652015424874 6 connected
4a1b2e7f9b9c4301c6d8a260af0d9f38f2b854ce 127.0.0.1:7004 slave e98ffc05aa00b33db727a099d28929f1f6faf981 0 1652015426400 5 connected

##  13.3 集群节点管理
###  增加新的节点
mkdir /data/7006
mkdir /data/7007

cat > /data/7006/redis.conf <<EOF
port 7006
daemonize yes
pidfile /data/7006/redis.pid
loglevel notice
logfile "/data/7006/redis.log"
dbfilename dump.rdb
dir /data/7006
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF

cat >  /data/7007/redis.conf <<EOF
port 7007
daemonize yes
pidfile /data/7007/redis.pid
loglevel notice
logfile "/data/7007/redis.log"
dbfilename dump.rdb
dir /data/7007
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF

redis-server /data/7006/redis.conf 
redis-server /data/7007/redis.conf 

### 添加主节点到集群里:
redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

[root@db01 ~]# redis-cli -p 7000 cluster nodes | grep master
c51a10072025d6435e78cdf688384361400a2079 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
e98ffc05aa00b33db727a099d28929f1f6faf981 127.0.0.1:7001 master - 0 1652015711060 2 connected 5461-10922
239f13a9ad57ade3945a35da501d2defcb99cfcf 127.0.0.1:7002 master - 0 1652015710757 3 connected 10923-16383
57207d0a94a68eedb53dea1196065ecd5fe345ea 127.0.0.1:7006 master - 0 1652015710655 0 connected ##注意这里没有槽位


###  转移slot(重新分片)
redis-trib.rb reshard 127.0.0.1:7000

[root@db01 ~]# redis-trib.rb reshard 127.0.0.1:7000
How many slots do you want to move (from 1 to 16384)? 4096 ##一共转移多少个槽位16384/分片个数
What is the receiving node ID?   ff21d336dff907d513377869dcfbd2ebd6ea95fc   #新加的主 7006
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1:5801a778c8ec731b49a98e197e66e6dc4a563913  ##从哪些分片获取槽位
Source node #2:ffb76fd9066bd3a61ea1606b096a82394f2a1e97
Source node #3:f05aad8617d0e91abd3ddf990ededfceeaa52237
Source node #4:done
Do you want to proceed with the proposed reshard plan (yes/no)? yes

[root@db01 ~]# redis-cli -p 7000 cluster nodes | grep master
b0f38becda2c28cbcf6d29837212f746bfe7f408 127.0.0.1:7002 master - 0 1652068299919 3 connected 12288-16383
ff21d336dff907d513377869dcfbd2ebd6ea95fc 127.0.0.1:7006 master - 0 1652068299410 7 connected 0-1364 5461-6826 10923-12287
e6438abbd9bb93af86d0add3b97ccc79b335cfc5 127.0.0.1:7001 master - 0 1652068298890 2 connected 6827-10922
d144834ea931ca5733c70dfb386c0b5d13ebf7ae 127.0.0.1:7000 myself,master - 0 0 1 connected 1365-5460


### 添加一个从节点
redis-trib.rb add-node --slave --master-id ff21d336dff907d513377869dcfbd2ebd6ea95fc 127.0.0.1:7007 127.0.0.1:7000

[root@db01 ~]# redis-cli -p 7000 cluster nodes | grep slave
de86473511afb0c0fe2a98f64eb45d71eba91b3c 127.0.0.1:7004 slave e6438abbd9bb93af86d0add3b97ccc79b335cfc5 0 1652068451175 5 connected
9c05f679043412900ff9ad640c45ab67f52a27c2 127.0.0.1:7003 slave d144834ea931ca5733c70dfb386c0b5d13ebf7ae 0 1652068452189 4 connected
32abd927e971188681c3202c7681b6baf63b67fa 127.0.0.1:7007 slave ff21d336dff907d513377869dcfbd2ebd6ea95fc 0 1652068452189 7 connected
968b32cc11e1597dc4d7a2832ce25b4562987cfb 127.0.0.1:7005 slave b0f38becda2c28cbcf6d29837212f746bfe7f408 0 1652068451682 6 connected


## 11.4 删除节点
###  1.删除节点前将已有slot移动走


7006节点的槽位号:
0-1364   5461-6826    10923-12287
1365个      1366个     1365个

redis-trib.rb reshard 127.0.0.1:7000
How many slots do you want to move (from 1 to 16384)? 1365  ###要转移的个数
What is the receiving node ID? d144834ea931ca5733c70dfb386c0b5d13ebf7ae ##谁接收
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1:ff21d336dff907d513377869dcfbd2ebd6ea95fc  #谁发送
Source node #2:done #执行
Do you want to proceed with the proposed reshard plan (yes/no)? yes #确认

[root@db01 ~]# redis-cli -p 7000 cluster nodes | grep master
b0f38becda2c28cbcf6d29837212f746bfe7f408 127.0.0.1:7002 master - 0 1652068842387 3 connected 12288-16383
ff21d336dff907d513377869dcfbd2ebd6ea95fc 127.0.0.1:7006 master - 0 1652068842898 7 connected 5461-6826 10923-12287
e6438abbd9bb93af86d0add3b97ccc79b335cfc5 127.0.0.1:7001 master - 0 1652068843311 2 connected 6827-10922
d144834ea931ca5733c70dfb386c0b5d13ebf7ae 127.0.0.1:7000 myself,master - 0 0 8 connected 0-5460
同理继续。。。

### 2.再删除节点

### 转移slot(重新分片)
删除master节点之前首先要使用reshard移除master的全部slot,然后再删除当前节点
redis-trib.rb reshard 127.0.0.1:7000


redis-trib.rb del-node 127.0.0.1:7006 ff21d336dff907d513377869dcfbd2ebd6ea95fc
redis-trib.rb del-node 127.0.0.1:7007 2cbf345c9c529de516d2ccc566a2e228981cc362


### 3.设置redis最大内存和最大连接数
config set maxmemory 102400000
---------------------
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "0"   ###默认使用物理内存,用多大就占多大。

config set maxclients 16384 #最大连接数
10.0.0.51:6379> CONFIG GET maxclients
1) "maxclients"
2) "4064"#默认4096

###4. python连接redis cluster集群测试

python3
>>> from rediscluster import RedisCluster  
>>> startup_nodes = [{"host":"127.0.0.1", "port": "7000"},{"host":"127.0.0.1", "port": "7001"},{"host":"127.0.0.1", "port": "7002"}]  
### Note: decode_responses must be set to True when used with python3 
 
>>> rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)  

>>> rc.set("foo", "bar")  
True  
>>> print(rc.get("foo"))  
'bar'


检查刚刚的key存入了哪个分片节点:

[root@db01 ~]# redis-cli -a 123 -p 7000 -h 127.0.0.1
127.0.0.1:7000> get littleboy
(error) MOVED 10719 127.0.0.1:7001  ###提示数据在7001上
127.0.0.1:7000> quit
[root@db01 ~]# redis-cli -a 123 -p 7001 -h 127.0.0.1
127.0.0.1:7001> get littleboy
"10"    ###数据真在7001上啊
127.0.0.1:7001> quit
[root@db01 ~]# redis-cli -a 123 -p 7002 -h 127.0.0.1
127.0.0.1:7002> get littleboy
(error) MOVED 10719 127.0.0.1:7001 ###提示数据在7001上

#提示无法访问从节点:从节点是备用节点
[root@db01 ~]# redis-cli -a 123 -p 7003 -h 127.0.0.1
127.0.0.1:7003> get littleboy
(error) MOVED 10719 127.0.0.1:7001
127.0.0.1:7003> quit
[root@db01 ~]# redis-cli -a 123 -p 7004 -h 127.0.0.1
127.0.0.1:7004> get littleboy
(error) MOVED 10719 127.0.0.1:7001  ###7001的从节点没数据.

挡掉7001节点,看他的从节点是否能访问,并且有数据.
[root@db01 ~]# redis-cli -a 123 -p 7004 -h 127.0.0.1
127.0.0.1:7004> get littleboy
"10"


#提示7001宕机,7004提升为主.
[root@db01 ~]# redis-cli -p 7000 cluster nodes|grep master
bf0a733332df6dd88a9f54c358bcdc14a099f938 127.0.0.1:7004 master - 0 1658571243309 11 connected 5461-10922
e1a43918d91ac4874bb4307ed771cbff584321e5 127.0.0.1:7002 master - 0 1658571244330 10 connected 10923-16383
1b6b848b5d3f7eb49769409ce7320fe844ef4e43 127.0.0.1:7001 master,fail - 1658571176370 1658571175861 9 disconnected
4bb4e8df564037dba979d349e8e6ff9658de2c82 127.0.0.1:7000 myself,master - 0 0 8 connected 0-5460

[root@db01 ~]# redis-cli -p 7000 cluster nodes|grep slave
9927e7f202501046348cb74d30c38eb2afda8800 127.0.0.1:7003 slave 4bb4e8df564037dba979d349e8e6ff9658de2c82 0 1658571253067 8 connected
4180a2fc708aff898abc2969e4baad8f344e10f9 127.0.0.1:7005 slave e1a43918d91ac4874bb4307ed771cbff584321e5 0 1658571252050 10 connected

#启动7001
[root@db01 ~]# redis-server /data/7001/redis.conf 

#7001修复后处于从节点位置
[root@db01 ~]# redis-cli -p 7000 cluster nodes|grep master
bf0a733332df6dd88a9f54c358bcdc14a099f938 127.0.0.1:7004 master - 0 1658571326079 11 connected 5461-10922
e1a43918d91ac4874bb4307ed771cbff584321e5 127.0.0.1:7002 master - 0 1658571326079 10 connected 10923-16383
4bb4e8df564037dba979d349e8e6ff9658de2c82 127.0.0.1:7000 myself,master - 0 0 8 connected 0-5460
[root@db01 ~]# redis-cli -p 7000 cluster nodes|grep slave
9927e7f202501046348cb74d30c38eb2afda8800 127.0.0.1:7003 slave 4bb4e8df564037dba979d349e8e6ff9658de2c82 0 1658571330672 8 connected
1b6b848b5d3f7eb49769409ce7320fe844ef4e43 127.0.0.1:7001 slave bf0a733332df6dd88a9f54c358bcdc14a099f938 0 1658571332202 11 connected
4180a2fc708aff898abc2969e4baad8f344e10f9 127.0.0.1:7005 slave e1a43918d91ac4874bb4307ed771cbff584321e5 0 1658571332202 10 connected


Redis读写分离 原创

Redis要搞高并发,就要把底层的缓存搞得很好。MySQL高并发也是通过一系列复杂分库分表。
一些电商的商品详情页,真正的超高并发,QPS上十万,甚至是百万,一秒钟百万的请求量。
光Redis是不够的,但是Redis是整个大型的缓存架构中,支撑高并发的架构里面,非常重要的一个环节:

首先,缓存中间件,缓存系统,必须能够支撑高并发
再经过良好的整体的缓存架构的设计(多级缓存架构、热点缓存),支撑真正的上十万,甚至上百万的高并发
Redis不能支撑高并发的瓶颈
单机redis能够承载的QPS大概就在上万到几万不等。
根据你的业务操作复杂性,redis提供很多复杂操作。
redis打死了,系统的瓶颈,不能支撑高并发的瓶颈。就卡死在redis单机这个问题。

如果redis要支撑超过10万+并发,何如?
单机的Redis几乎不太可能说QPS超过10万+,除非一些特殊情况,比如你的机器性能特别好,
配置特别高,物理机,维护做的特别好,而且你的整体的操作不是太复杂。

单机在几万。
读写分离,一般来说,对缓存,一般都是用来支撑读高并发的,写的请求是比较少的,可能写请求也就一秒钟几千,一两千
大量的请求都是读,一秒钟二十万次读

读写分离
主从架构 -> 读写分离 -> 支撑10万+读QPS的架构
水平扩容:如果你的读QPS再增加,也很简单,继续增加redis slave即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值