介绍
redis集群就是将多个redis服务放在一起,通过某种策略让他们各司其职。当用户访问redis时通过某种算法将请求发送到不同的redis服务。
主从复制减少了读写压力的问题,那么集群有效缓解了内存压力的问题。
redis集群实现了对redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。
redis集群通过分区(Partition)来提供一定程度的可用性(Availability),即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。
强一致性(Consistency)、高可用(Availability)和分区容错性(Partition)的CAP理论,可以参考:1.redis前言
环境准备
从redis安装目录拷贝6份redis.conf
到/usr/local/redis-cluster
路径,并使用启动端口作为标识重命名配置文件。
cp 你的redis安装目录/redis.conf /usr/local/redis-cluster/redis6379.conf
cp 你的redis安装目录/redis.conf /usr/local/redis-cluster/redis6380.conf
cp 你的redis安装目录/redis.conf /usr/local/redis-cluster/redis6381.conf
cp 你的redis安装目录/redis.conf /usr/local/redis-cluster/redis6389.conf
cp 你的redis安装目录/redis.conf /usr/local/redis-cluster/redis6390.conf
cp 你的redis安装目录/redis.conf /usr/local/redis-cluster/redis6391.conf
使用vim编辑器依次修改这6个配置文件,以redis6379.conf
为例。
- 开启daemonize
daemonize yes
- 修改pid文件名称
pidfile /var/run/redis_6379.pid
- 修改log文件名称
logfile "6379.log"
- 修改端口
port 6379
- 修改dbfilename文件名称
dbfilename dump6379.rdb
- 关闭AOF持久化
appendonly no
或者修改appendfilename文件名称
appendfilename "appendonly6379.aof"
- 开启集群模式
cluster-enabled yes
- 设置节点配置文件
cluster-config-file nodes-6379.conf
- 设置节点失联时间,超过该时间(毫秒),集群自动进行主从切换
cluster-node-timeout 15000
修改完redis6379.conf文件,其他5个文件依照此方式修改,只是将上面出现6379改成各自启动端口号即可。
启动
分别启动6个redis实例。
redis-server redis6379.conf
redis-server redis6380.conf
redis-server redis6381.conf
redis-server redis6389.conf
redis-server redis6390.conf
redis-server redis6391.conf
查看ps -ef|grep redis
是否启动成功。
启动成功后将生成nodes-xxxx.conf
文件。
合体
将多个redis实例放在一个集群中就叫合体。
在redis安装路径的src目录下执行合体命令:
refdis5.0之前的版本执行:
./redis-trib.rb create --replicas 1 your ip:6379 your ip:6380 your ip:6381 your ip:6389 your ip:6390 your ip:6391
redis5.0之后的版本执行:
redis-cli --cluster create your ip:6379 your ip:6380 your ip:6381 your ip:6389 your ip:6390 127.0.0.1:6391 --cluster-replicas 1
your ip可以用ifconfig
查看,或者用127.0.0.1
替代。
询问can I set the above configuration? (type ‘yes’ to accept):表示对于集群分配的主从服务器分配和插槽分配是否满意,键入yes表示满意即可。
参数--replicas 1
或者-cluster-replicas 1
表示为每个主节点创建一个从节点。
一个集群至少要有三个主节点。分配原则尽量保证每个主数据库运行在不同的ip地址,每个从库和主库不在一个ip地址上。
由启动信息可知:
主机6379插槽值:c1a9f0179ab1737ce167f0c14f0129f3ba9d2f9a,插槽索引范围:[0-5460],6389从属于6379。
主机6380插槽值:58e4ac4f4299b79e9cb9a24c018bc566885cff76,插槽索引范围:[5461-10922],6390从属于6380。
主机6381插槽值:4cdaa7eb6dcc18865b0726147d6be72a4d2fe374,插槽索引范围:[10923-16383],6391从属于6381。
什么是插槽(slots):一个redis集群包含16384个插槽(hash slot),每个库中的每个键多属于这16384个插槽的其中一个,公式:CRC16(key)%16384 来计算键key属于哪个插槽,其中 CRC16(key) 用于计算键key的 CRC16 校验和。
用客户端以集群方式连接6379端口redis服务。
redis-cli -c -p 6379
-c表示实现数据自动重定向。并执行set k1 v1
保存数据。
通过算法计算键k1应该送往12706号插槽,在主机6381插槽索引范围内,然后自动重定向切换到6381,k1保存了6381数据库中。
可以通过{组名}来定义组的概念,从而使同一组的所有key都在同一个数据库服务中。
键name、age和sex都属于user组,都在6380服务中。
问题1:如果主节点宕机后,对应的从节点能否自动升为主节点?
以6379服务为例,关闭6379服务。
redis-cli -p 6379 shutdown
6379宕机后,使用客户端连接6380服务,查看集群信息。
redis-cli -c -p 6380
查看集群信息
cluster nodes
结论:原本6389为6379的从库,6379宕机后,6389自动升级为主库。
问题2:主机恢复后,主从关系会如何?
重新启动6379服务
redis-server redis6379.conf
配置项:cluster-require-full-coverage yes表示只有全部插槽(16379)都正常的时候才能对外提供服务,默认yes。如果某台主机宕机后,则对应的插槽就使用不了了,也就不能对外提供服务了
集群命令
CLUSTER INFO
打印集群的信息 。
CLUSTER NODES
列出集群当前已知的所有节点(node),以及这些节点的相关信息。
//节点(node)
CLUSTER MEET
将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
CLUSTER FORGET
从集群中移除 node_id 指定的节点。
CLUSTER REPLICATE
将当前节点设置为 node_id 指定的节点的从节点。
CLUSTER SAVECONFIG
将节点的配置文件保存到硬盘里面。
//槽(slot)
CLUSTER ADDSLOTS [slot ...]
将一个或多个槽(slot)指派(assign)给当前节点。
CLUSTER DELSLOTS [slot ...]
移除一个或多个槽对当前节点的指派。
CLUSTER FLUSHSLOTS
移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
CLUSTER SETSLOT NODE
将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派。
CLUSTER SETSLOT MIGRATING
将本节点的槽 slot 迁移到 node_id 指定的节点中。
CLUSTER SETSLOT IMPORTING
从 node_id 指定的节点中导入槽 slot 到本节点。
CLUSTER SETSLOT
STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。
//键 (key)
CLUSTER KEYSLOT
计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT
返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT
返回 count 个 slot 槽中的键。
此处参考:https://codekiller.top/2020/03/30/redis2/#toc-heading-65
集群优点
- 实现扩容
- 分摊压力
- 无中心配置相对简单
集群缺点
- 类似mset、mget等多键操作不被支持。
- 多键的redis事务是不被支持的。