Redis 搭建集群

Redis 搭建集群

我在这里只记录点基本内容,不会写太深入的内容

问题

容量不够,redis 如何进行扩容?

增加 redis 服务器,通过集群解决容量不够的问题

并发写操作,redis 如何分摊?

使用集群负担写操作的压力

主从模式、薪火相传、主机宕机,都可能导致 ip 地址发生变化,应用程序中配置需要修改对应的主机地址、端口等信息?

redis 3.0 之前使用代理主机来解决,redis 3.0 中提供了解决方案,就是无中心化集群配置

代理主机方式:
客户端通过代理服务器去访问服务,比如用户、商品、订单等服务,每个服务都有从服务器,代理主机也有从服务器

无中心化集群:
每个服务都有从服务器,但是任何服务器都可以作为集群的入口,将服务直接转移给另外的服务

概念

redis 集群实现了对 redis 的水平扩容,即启动 N 个 redis 节点,将整个数据库分布存储在这 N 个节点中,每个节点存储总数据的 1/N
redis 集群通过分区(partition)来提供一定长度的可用性(availability),即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求

搭建 redis 集群

我们使用六台服务器搭建 redis 集群,当然,肯定是用一台机器的不同端口来模拟

步骤:

  1. 在 redis/bin 目录创建一个文件夹,例如 cluster
  2. 我们需要六个 redis 配置,端口号分别为:6379、6380、6381、6389、6390、6391,6379、6380、6381是主服务器,6389、6390、6391是从服务器
  3. 配置基本信息,配置文件名都是 redis_端口号.conf
  • include cluster/redis.conf:这是基本的redis配置文件
  • pidfile /var/run/redis_端口号.pid
  • port 端口号
  • dbfilename "dump_端口号.rdb"
  • cluster-enabled yes:打开集群模式
  • cluster-config-file nodes_端口号.conf:设定节点配置文件名
  • cluster-node-timeout 15000:设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换
  1. 启动六个 redis 服务:打开三个终端,到 redis/bin 目录,启动三台 redis 服务器(你也可以给这个命令配置一个环境变量)
  • ./redis-server cluster/redis_6379.conf
  • ./redis-server cluster/redis_6380.conf
  • ./redis-server cluster/redis_6381.conf
  • ./redis-server cluster/redis_6389.conf
  • ./redis-server cluster/redis_6390.conf
  • ./redis-server cluster/redis_6391.conf
  1. 将六个节点合成一个集群,组合之前,确保所有 redis 实例启动后,nodes_端口号.conf 文件都生成正常(这个 node 文件在 redis 的 data 目录下)
  • 旧版本的 redis 版本中,需要 ruby 环境
  • 比较新的 redis 版本中,不需要额外工具,控制台进入 redis 源码的 src 目录下,执行命令redis-cli --cluster create --cluster-replicas 1 ip地址:端口号 ip地址:端口号 ...--replicas 1表示采用最简单的方式配置集群,一台主服务器,一台从服务器。如果有密码,在后面加-a 密码,或者写配置文件masterauth 密码
  1. 连接要采用集群策略连接,命令是./redis-cli -c -h ip地址 -p 端口号,设置数据会自动切换到相应的主服务器,连接任意一个服务器都可以
  2. 通过 cluster nodes 命令查看集群信息

启动六个 redis 服务器
Redis 搭建集群

配置集群,这里显示了集群策略,显示了哪些服务器被分配到主服务器,哪些被分配到从服务器
Redis 搭建集群

输入 yes 之后就开始创建集群了,注意,我这里分配的主从没有对齐,变成了 6379--6390、6380--6391、6381--6389,不过这都无所谓,我们继续
Redis 搭建集群

集群操作

redis cluster 如何分配这六个节点?
一个集群至少要有三个主节点
选项 --cluster-replicas 1 表示我们希望为集群中的每个主节点创建一个从节点
分配原则尽量保证每个主数据库运行在不同的ip地址,每个从数据库和主数据库不在一个ip地址上

再看一下 slots
Redis 搭建集群

[OK] All 16384 slots covered,什么是 slots?

一个 redis 集群包含 16384 个插槽(hash slot),数据库中的每个键都属于这 16384 个插槽的其中一个
集群使用公式 CRC16(key) % 16384 来计算键key属于哪个槽,其中 CRC16(key) 语句用于计算键key的 CRC16 校验和
集群中的每个节点负责处理一部分插槽,举个例子,如果一个集群可以有主节点,其中:

  • 节点 A 负责处理 0 号至 5460 号插槽
  • 节点 B 负责处理 5461 号至 10922 号插槽
  • 节点 C 负责处理 10923 号至 16383 号插槽
    但是集群中任意一台服务器都可以作为集群的入口,所以能互相访问到自己负责的插槽之外的数据,会直接切换到插槽对应的服务器

首先我们先用六个 redis-cli 连接对应端口的 redis 服务,一定要用集群模式连接
三个主服务器
Redis 搭建集群

三个从服务器
Redis 搭建集群

插入数据示例

set name zhangsan

插入数据会自动切换到数据插槽对应的服务器
Redis 搭建集群

查询数据也会切换到对应的服务器
Redis 搭建集群

从服务器读取或写入数据也会切换过去
Redis 搭建集群

Redis 搭建集群

但是不能同时使用多条 set 命令,因为插槽算不出来,比如底下这条命令

mset name zhangsan age 20 id 0001

结果会报错
Redis 搭建集群

需要分组,这样就根据了组的名字去计算插槽的值

mset name{user} zhangsan age{user} 20 id{user} 0001

结果正确
Redis 搭建集群

查询集群中的值

  • cluster keyslot <key>:查询 key 对应的插槽值
  • cluster countkeysinslot <slot>:查询 slot 的值的数量,没有就是 0 ,只能查询当前服务器负责的插槽
  • cluster getkeysinslot <slot> <count>:返回 count 个 slot 中的 key

故障恢复

如果主节点宕机,从节点自动升为主节点
宕机的主节点重启之后,这个宕机的主节点会自动变成从节点
如果主从节点都宕机了,根据 redis.conf 的配置,cluster-require-full-coverage 为 yes ,这是默认值,那么,整个集群都宕机;而cluster-require-full-coverage 为 no ,那么该插槽的数据全部都不能使用,也无法存储

比如我们 shutdown 一个主服务器,6380 对应的从服务器是 6391
Redis 搭建集群

再去查看它的从服务器 6391,变成了主服务器,没有问题
Redis 搭建集群

再启动 6380,变成了从服务器
Redis 搭建集群

集群的优势

  • 实现扩容
  • 分摊压力
  • 无中心配置相对简单

集群的缺陷

  • 多键操作是不被支持的
  • 多键的 redis 事务是不被支持的,lua 脚本不被支持
  • 由于集群方案出现较晚,很多公司已经采用了其它的集群方案,而代理或者客户端分片的方案想要迁移至 redis cluster,需要整体迁移而不是逐步过渡,复杂度较大

Redis 搭建集群 结束

Redis 搭建集群

上一篇:windows go amd64 libiconv 缺失报错问题


下一篇:jdk源码+hashmap