Redis Cluster
集群
我们要使用集群
- redis 并发量 10万 / 每秒 ,但是有些业务需要 100万的 QPS
- 数据量,我们普通机器 16~256g,而我们的业务需要500g
解决方案
- 分布式 :加机器,方便以后需求扩容
Redis Cluster
Redis Cluster是Redis的分布式解决方案,在3.0版本正式推出,有效地解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用Cluster架构方案达到负载均衡的目的。
在Redis Cluster,它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点,对其进行存取和其它操作。
Redis Cluster提供的好处:
- 将数据自动切分到多个节点的能力
- 当集群中的一部分节点失效或者无法进行通讯时,仍然可以继续处理命令请求的能力,拥有自动故障转移的能力。
Redis Cluster 和 replication + sentinel 如何选择:
如果数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就几个G,单机就够了。
- Replication:一个master,多个slave,要几个slave跟你的要求的读吞吐量有关系,结合sentinel集群,去保证redis主从架构的高可用就行了。
- Redis Cluster:主要是针对海量数据+高并发+高可用的场景,海量数据,如果数据量很大,建议用Redis Cluster
数据分布
数据分区
顺序分布和哈希分布
- 顺序分布
- 哈希分步
哈希分布
-
节点取余分布 : ( hash (key) % nodes )
- 使用特点的数据(包括redis的键或用户ID),再根据节点数量N,使用公式:hash(key)%N计算出一个0~(N-1)值,来决定数据映射到哪一个节点上。即哈希值对节点总数取余。
- 客户端分片 :哈希 + 取余
- 节点伸缩 : 数据节点关系变化,导致数据迁移
- 迁移数量和添加节点数量有关 :建议翻倍扩容
-
一致性哈希分区
- 一致性哈希分区(Distributed Hash Table)实现思路是为系统中每个节点分配一个token,范围一般在0~232,这些token构成一个哈希环。数据读写执行节点查找操作时,先根据key计算hash值,然后顺时针找到第一个大于等于该哈希值的token节点。
- 一致性哈希分区(Distributed Hash Table)实现思路是为系统中每个节点分配一个token,范围一般在0~232,这些token构成一个哈希环。数据读写执行节点查找操作时,先根据key计算hash值,然后顺时针找到第一个大于等于该哈希值的token节点。
上图就是一个一致性hash的原理解析。
假设有n1~n4这四台机器,我们对每一台机器分配一个唯一token,每次有数据(黄色代表数据),一致性哈希算法规则每次都顺时针漂移数据,也就是图中黄色的数据都指向n3。
这个时候我们需要增加一个节点n5,在n2和n3之间,数据还是会发生漂移(会偏移到大于等于的节点),但是这个时候你是否注意到,其实只有n2~n3这部分的数据被漂移,其它的数据都是不会变的,这种方式相比节点取余最大的好处在于加入和删除节点只影响哈希环中相邻的节点,对其它节点无影响。
- 客户端分片: 哈希 + 顺时针 (优化取余)
- 节点伸缩 : 只影响临近节点,但是还是有数据迁移
- 翻倍伸缩 :保证最小迁移数据和负载均衡
-
虚拟槽分区
- 虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中,整数定义为槽(slot)。这个范围一般远远大于节点数,比如Redis Cluster槽范围是0~16383(也就是说有16383个槽)。槽是集群内数据管理和迁移的基本单位。采用大范围槽的主要目的是为了方便数据拆分和集群扩展。每个节点会负责一定数量的槽。
- 虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中,整数定义为槽(slot)。这个范围一般远远大于节点数,比如Redis Cluster槽范围是0~16383(也就是说有16383个槽)。槽是集群内数据管理和迁移的基本单位。采用大范围槽的主要目的是为了方便数据拆分和集群扩展。每个节点会负责一定数量的槽。
- 预设虚拟槽映射一个数据子集,一半节点数大
- 良好的哈希函数 : 例如CRC16
- 服务端管理节点、槽、数据:例如 Redis Cluster
- 对比
分布方式 | 特点 | 典型产品 |
---|---|---|
哈希分布 | 数据分散度高 , 键值分布业务无关 ,无法顺序访问 ,支持批量操作 | 一致性哈希Memcache ,Redis Cluster , 其他缓存产品 |
顺序分布 | 数据分散度易倾斜 , 键值业务相关 ,可顺序访问 , 支持批量操作 | BigTable ,HBase |
搭建集群
一、基本架构
- 节点
- meet
- 指配槽
-
Redis Cluster特性
- 复制
- 高可用
- 分片
二、两种安装
- 原生命令安装
- 配置开启节点 redis.conf
port ${port} //端口
daemonize yes
dir "/opt/redis/redis/data/"
dbfilename "dump-${port}.rdb" //rdb文件
logfile "${port}.log" //log 文件
cluster-enabled yes
cluster-config-file nodes-${port}.conf //给 cluster添加自己的配置文件
开启节点
redis-server redis-7000.conf
redis-server redis-7001.conf
redis-server redis-7002.conf
redis-server redis-7003.conf
redis-server redis-7004.conf
redis-server redis-7005.conf
redis-server redis-7006.conf
- meet
cluster meet ip port // 彼此之间相互感知
redis-cli -h 1270.0.1 -p 7000 cluster meet 127.0.0.1 7001
redis-cli -h 1270.0.1 -p 7000 cluster meet 127.0.0.1 7002
redis-cli -h 1270.0.1 -p 7000 cluster meet 127.0.0.1 7003
redis-cli -h 1270.0.1 -p 7000 cluster meet 127.0.0.1 7004
redis-cli -h 1270.0.1 -p 7000 cluster meet 127.0.0.1 7005
redis-cli -h 1270.0.1 -p 7000 cluster meet 127.0.0.1 7006
- 指配槽
cluster addslots slot[slot .....]
redis-cli -h 127.0.0.1 -p 7000 cluster addslots {0...5461}
redis-cli -h 127.0.0.1 -p 7001 cluster addslots {5462...10922}
redis-cli -h 127.0.0.1 -p 7002 cluster addslots {10923...16383}
- 主从
cluster replicate node-id
redis-cli -h 127.0.0.1 -p 7003 cluster replicate ${node-id-7000}
redis-cli -h 127.0.0.1 -p 7004 cluster replicate ${node-id-7001}
redis-cli -h 127.0.0.1 -p 7005 cluster replicate ${node-id-7002}
- 具体安装
创建文件
端口以及文件依次后排 7001 ,7002
port 7000
daemonize yes
dir "/opt/software/redis-4.0.9/cluster-test/data"
logfile "/opt/software/redis-4.0.9/cluster-test/logs/7000.log"
#dbfilename不能配置为路径
dbfilename "dump-7000.rdb"
cluster-enabled yes
cluster-config-file nodes-7000.conf
#是否需要每个节点都可用,集群才算可用,关闭
cluster-require-full-coverage no
一次通过配置文件启动集群,我还在conf目录下,所以这样启动
有不懂的推荐Redis Cluster 安装文章 https://blog.csdn.net/fst438060684/article/details/80712433
- 官方工具安装
Ruby 环境准备
- 下载ruby
wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz
- 安装 ruby
tar -xvf ruby-2.3.1.tar.gz
./configure -prefix=/usr/local/ruby
make
make install
cd /usr/loacl/ruby
cp bin/ruby /usr/local/bin
cp bin/gem /usr/local/bin
- 安装rubygem redis
wget http://rubygems.ory/downloads/redis-3.3.0.gem
gem install -| redis-3.3.0.gem
gem list --check redis gem
启动所有节点
redis-server redis-7000.conf
redis-server redis-7001.conf
redis-server redis-7002.conf
redis-server redis-7003.conf
redis-trib.rb支持的操作
复制代码
# redis-trib.rb help
Usage: redis-trib <command> <options> <arguments ...>
create host1:port1 ... hostN:portN
--replicas <arg>
check host:port
info host:port
fix host:port
--timeout <arg>
reshard host:port
--from <arg>
--to <arg>
--slots <arg>
--yes
--timeout <arg>
--pipeline <arg>
rebalance host:port
--weight <arg>
--auto-weights
--use-empty-masters
--timeout <arg>
--simulate
--pipeline <arg>
--threshold <arg>
add-node new_host:new_port existing_host:existing_port
--slave
--master-id <arg>
del-node host:port node_id
set-timeout host:port milliseconds
call host:port command arg arg .. arg
import host:port
--from <arg>
--copy
--replace
help (show this help)
For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
支持的操作如下:
- create:创建集群
- check:检查集群
- info:查看集群信息
- fix:修复集群
- reshard:在线迁移slot
- rebalance:平衡集群节点slot数量
- add-node:添加新节点
- del-node:删除节点
- set-timeout:设置节点的超时时间
- call:在集群所有节点上执行命令
- import:将外部redis数据导入集群
创建集群
./redis-trib.rb create --replicas 1 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 127.0.0.1:7000
--replicas参数指定集群中每个主节点配备几个从节点,这里设置为1。
[root@localhost redis]# ./src/redis-trib.rb create --replicas 1 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 127.0.0.1:7000
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:7001
127.0.0.1:7002
127.0.0.1:7003
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
Adding replica 127.0.0.1:7000 to 127.0.0.1:7003
M: f4ee0a501f9aaf11351787a46ffb4659d45b7bd7 127.0.0.1:7001
slots:0-5460 (5461 slots) master
M: 671a0524a616da8b2f50f3d11a74aaf563578e41 127.0.0.1:7002
slots:5461-10922 (5462 slots) master
M: 18948dab5b07e3726afd1b6a42d5bf6e2f411ba1 127.0.0.1:7003
slots:10923-16383 (5461 slots) master
S: 34e322ca50a2842e9f3664442cb11c897defba06 127.0.0.1:7004
replicates f4ee0a501f9aaf11351787a46ffb4659d45b7bd7
S: 62a00566233fbff4467c4031345b1db13cf12b46 127.0.0.1:7005
replicates 671a0524a616da8b2f50f3d11a74aaf563578e41
S: 2cb649ad3584370c960e2036fb01db834a546114 127.0.0.1:7000
replicates 18948dab5b07e3726afd1b6a42d5bf6e2f411ba1
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 127.0.0.1:7001)
M: f4ee0a501f9aaf11351787a46ffb4659d45b7bd7 127.0.0.1:7001
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: 671a0524a616da8b2f50f3d11a74aaf563578e41 127.0.0.1:7002
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: 2cb649ad3584370c960e2036fb01db834a546114 127.0.0.1:7000
slots: (0 slots) slave
replicates 18948dab5b07e3726afd1b6a42d5bf6e2f411ba1
S: 34e322ca50a2842e9f3664442cb11c897defba06 127.0.0.1:7004
slots: (0 slots) slave
replicates f4ee0a501f9aaf11351787a46ffb4659d45b7bd7
M: 18948dab5b07e3726afd1b6a42d5bf6e2f411ba1 127.0.0.1:7003
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: 62a00566233fbff4467c4031345b1db13cf12b46 127.0.0.1:7005
slots: (0 slots) slave
replicates 671a0524a616da8b2f50f3d11a74aaf563578e41
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
上面显示创建成功,有3个主节点,3个从节点,每个节点都是成功连接状态。