文章目录

  • 一. Redis集群
  • 1. 什么是集群
  • 2. Redis集群
  • 3. 传统代理主机方式
  • 4. 去中心化方式
  • 二. 搭建集群
  • 1. 环境准备
  • 2. 服务启动
  • 3. 合并为集群
  • 4. 连接集群
  • 三. 其他
  • 1. redis cluster 如何分配这六个节点?
  • 2. 什么是slots?
  • 3. 插入数据
  • 4. 故障恢复
  • 5. 集群Jedis开发



一. Redis集群

1. 什么是集群

什么是集群? 其实多台主机提供相同的服务的一组序列就叫集群,简单的来说集群就是一组或者若干组相互独立的计算机,利用高速通信网络组成的一个较大的计算机服务系统,每个集群节点(下面会介绍到)都是运行各自服务的独立服务器。在某种意义上,他们可以被看作是一台计算机。这些服务器之间可以彼此通信,协同向用户提供应用程序,系统资源和数据。用通俗一点的话来讲就是很多个人做同一件事(这里的“事”是一个代指,也可细分)。

2. Redis集群

而Redis中的集群主要是用来解决一个Redis水平扩容的问题, Redis3.0加入了Redis的集群模式,实现了数据的分布式存储,对数据进行分片,将不同的数据存储在不同的master节点上面,从而解决了海量数据的存储问题。
采用了去中心化的思想,没有中心节点的说法,对于客户端来说整个集群可以看成一个整体,可以连接任意一个节点进行操作,就像操作单一Redis实例一样,不需要任何代理中间件,当客户端操作的key没有分配到该node上时,Redis会返回转向指令,指向正确的node。
Redis也内置了高可用机制,支持N个master节点,每个master节点都可以挂载多个slave节点,当master节点挂掉时,集群会提升它的某个slave节点作为新的master节点。
当然也可以配合上一篇文章中的模式进行配置使用如,主从模式薪火相传模式等。
而在Redis3.0之前,一直在使用代理主机的方式实现Redis。

3. 传统代理主机方式

假设现在一个服务需要一个Redis集群的支撑,用户的用户功能对应Redis集群中特定处理用户业务缓存的主机,订单功能对应Redis集群中特定处理订单业务缓存的主机,商品功能对应Redis集群中特定处理商品功能的业务缓存主机。但是此时Redis中还没有出现去中心化的集群方式,使用的还是代理主机的方式,通过代理主机将对应业务的消息转发到对应的业务主机进行处理。

redis cluster cluster nodes命令 redis cluster jedis_数据库

4. 去中心化方式

而在Redis3.0时Redis推出了去中心化的Redis集群搭建方式,对于客户端来说整个集群可以看成一个整体,可以连接任意一个节点进行操作,就像操作单一Redis实例一样,不需要任何代理中间件,当客户端操作的key没有分配到该node上时,Redis会返回转向指令,指向正确的node。

redis cluster cluster nodes命令 redis cluster jedis_缓存_02

二. 搭建集群

1. 环境准备

首先在根目录下创建一个名为myredis的文件夹用来存放我们演示的配置信息

// 创建文件夹
mkdir /myredis
// 进入文件夹
cd /myredis

然后将本机中的Redis配置文件redis.conf复制到我们的配置目录

cp /usr/src/redis-6.2.6/redis.conf /myredis

将复制过来的配置文件中的以下选项修改为对应的值

appendonly no // appendonly修改为no 默认就是no

紧接着我们创建6个配置文件,分别对应每一台Redis服务,本次的搭建演示需要创建6个Redsi实例,6个Redsi实例分别占用,6379、6380、6381、6382、6383、6384端口,为了方便识别我们的配置文件名后缀使用端口命名方便识别,然后使用include /myredis/redis.conf是引入redis.conf配置文件的公共部分,6份配置文件的文件名分别为redis6379.confredis6380.confredis6381.confredis6382.confredis6383.confredis6384.conf,分别是三台主机,和与之对应的三台从机。
可以使用以下命令进行创建。

touch redis6379.conf
touch redis6380.conf
touch redis6381.conf
touch redis6382.conf
touch redis6383.conf
touch redis6384.conf

创建完6个配置文件后,分别将以下内容添加到对应的配置文件中。

//redis6379.conf文件内容
include /myredis/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb
cluster-enabled yes 
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
protected-mode no
masterauth 331213

//redis6380.conf文件内容
include /myredis/redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump6380.rdb
cluster-enabled yes 
cluster-config-file nodes-6380.conf
cluster-node-timeout 15000
protected-mode no
masterauth 331213

//redis6381.conf文件内容
include /myredis/redis.conf
pidfile /var/run/redis_6381.pid
port 6381
dbfilename dump6381.rdb
cluster-enabled yes 
cluster-config-file nodes-6381.conf
cluster-node-timeout 15000
protected-mode no
masterauth 331213

//redis6382.conf文件内容
include /myredis/redis.conf
pidfile /var/run/redis_6382.pid
port 6382
dbfilename dump6382.rdb
cluster-enabled yes 
cluster-config-file nodes-6382.conf
cluster-node-timeout 15000
protected-mode no
masterauth 331213

//redis6383.conf文件内容
include /myredis/redis.conf
pidfile /var/run/redis_6383.pid
port 6383
dbfilename dump6383.rdb
cluster-enabled yes 
cluster-config-file nodes-6383.conf
cluster-node-timeout 15000
protected-mode no
masterauth 331213

//redis6384.conf文件内容
include /myredis/redis.conf
pidfile /var/run/redis_6384.pid
port 6384
dbfilename dump6383.rdb
cluster-enabled yes 
cluster-config-file nodes-6384.conf
cluster-node-timeout 15000
protected-mode no
masterauth 331213

修改完配置文件后记得保存

redis cluster cluster nodes命令 redis cluster jedis_缓存_03


相关配置内容作用如下

include /myredis/redis.conf// 引入配置文件的公共部分
pidfile /var/run/redis_6379.pid // Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件
port 6379 // 服务占用端口
dbfilename dump6379.rdb //持久化文件名
cluster-enabled yes   // 打开集群模式
cluster-config-file nodes-6379.conf  //设定节点配置文件名
cluster-node-timeout 15000   //设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换。
protected-mode no // 关闭保护模式 可以免密码登陆 可选
masterauth 111111 // 设置集群节点间访问密码 没有设置密码的话就不需要设置

2. 服务启动

修改完配置文件后,我们需要指定刚刚修改好的配置文件启动6个Redis服务,可以执行以下命令将6个服务启动起来。
注意:如果原本系统中就有一个占用6379服务的Redsi实例需要先执行下面的命令关闭再使用后面的命令启动

redis-cli -p 6379
auth 331213 // Redis密码
shutdown

redis cluster cluster nodes命令 redis cluster jedis_Redis_04


然后我们再使用下面的命令启动Redis服务

redis-server /myredis/redis6379.conf
redis-server /myredis/redis6380.conf
redis-server /myredis/redis6381.conf
redis-server /myredis/redis6382.conf
redis-server /myredis/redis6383.conf
redis-server /myredis/redis6384.conf

执行完后可以执行以下命令查看服务启动是否成功

ps -ef | grep redis

redis cluster cluster nodes命令 redis cluster jedis_Redis_05

3. 合并为集群

组合之前,请确保所有redis实例启动后,nodes-xxxx.conf文件都生成正常。

正常启动后都会在启动目录生成一个nodes-xxxx.conf 文件

redis cluster cluster nodes命令 redis cluster jedis_缓存_06


在合并集群之前我们首先要进入到Redis安装目录下的 src 目录下

注:如果是比较老的Redis版本还需要安装一个环境。

cd /usr/src/redis-6.2.6/src

这个命令集成了那个环境,所以我们需要使用到它,所以我们得在src目录下执行后续的命令。

redis cluster cluster nodes命令 redis cluster jedis_Redis_07


紧接着我们执行以下命令合并启动的服务成为一个集群

redis-cli --cluster create --cluster-replicas 1 192.168.43.42:6379 192.168.43.42:6380 192.168.43.42:6381 192.168.43.42:6382 192.168.43.42:6383 192.168.43.42:6384 -a 331213

–replicas 1 采用最简单的方式配置集群,一台主机,一台从机,正好三组。

注意:此处不要用127.0.0.1, 请用真实IP地址

-a 331213 Redis服务密码 (设置了密码就要指定否则报错)

然后会出现下面的页面

redis cluster cluster nodes命令 redis cluster jedis_数据库_08

输入 yes 然后回车即可,这是询问是否同意它的分配,可以看到 6379 6380 6381 被分配为主服务器,下面是分配的从服务器,输入yes回车后可以看到以下界面,证明集群已经完成搭建了。

redis cluster cluster nodes命令 redis cluster jedis_缓存_09


All 16384 slots covered. 这个的意思是请参考下文

4. 连接集群

集群的连接和普通Redis服务的连接方式不同,集群要使用 -c 参数,示例如下

redis-cli  -c -p 6379  // 连接6379端口Redis服务

用任何一个节点连接都是可以的,然后我们可以使用以下命令查看集群的信息,使用前需要权限验证一下。

auth 331213 // Redis密码
cluster nodes

redis cluster cluster nodes命令 redis cluster jedis_数据库_10


myself,master 是当前连接的Redsi服务

三. 其他

1. redis cluster 如何分配这六个节点?

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

2. 什么是slots?

redis cluster cluster nodes命令 redis cluster jedis_缓存_09


一个 Redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个,

集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。

集群中的每个节点负责处理一部分插槽。 举个例子, 如果一个集群可以有主节点, 其中:

节点 A 负责处理 0 号至 5460 号插槽。

节点 B 负责处理 5461 号至 10922 号插槽。

节点 C 负责处理 10923 号至 16383 号插槽。

也可以使用上面的 cluster nodes 命令查看服务占用的插槽范围

redis cluster cluster nodes命令 redis cluster jedis_数据库_12

3. 插入数据

当我们插入一条数据时,首先会计算键的插槽值所在范围,再将其存入对应范围的Redis服务,如果插入的值不在当前服务的插槽范围内,则会自动跳转到对应范围的插槽服务器进行存储。

但是注意 集群不能同时直接加入多个值。会出现 (error)CROSSSLOT Keysin requestdon’t hashto thesameslot的错误

可以通过{}来定义组的概念,从而使key中{}内相同内容的键值对放到一个slot中去。{}中是组的名字

redis cluster cluster nodes命令 redis cluster jedis_数据库_13

4. 故障恢复

如果主节点下线?从节点能否自动升为主节点?注意:15秒超时
比如在6381中执行以下的命令停止当前占用6381的主节点

shutdown

然后我们连接6380端口的Redis服务

redis-cli  -c -p 6380

再使用命令查看集群状态

auth 331213 // Redis密码
cluster nodes

可以看到6381已经挂掉了,但是还是有3台主机证明有从机上位了

redis cluster cluster nodes命令 redis cluster jedis_Redis_14


这时如果再启动6381 那么6381会成为新晋主机的从机,这就是集群故障恢复的特点

如果所有某一段插槽的主从节点都宕掉,redis服务是否还能继续?

如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为yes ,那么 ,整个集群都挂掉

如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为no ,那么,该插槽数据全都不能使用,也无法存储。

redis.conf中的参数 cluster-require-full-coverage

5. 集群Jedis开发

/**
 * 演示redis集群操作
 */
public class RedisClusterDemo {

    public static void main(String[] args) {
        //创建对象
        HostAndPort hostAndPort = new HostAndPort("192.168.44.168", 6379);
        JedisCluster jedisCluster = new JedisCluster(hostAndPort);

        //进行操作
        jedisCluster.set("b1","value1");

        String value = jedisCluster.get("b1");
        System.out.println("value: "+value);

        jedisCluster.close();
    }
}