• Redis集群|集群搭建|集群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中还没有出现去中心化的集群方式,使用的还是代理主机的方式,通过代理主机将对应业务的消息转发到对应的业务主机进行处理。
    在这里插入图片描述

    4. 去中心化方式

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

    二. 搭建集群

    1. 环境准备

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

    // 创建文件夹
    mkdir /myredis
    // 进入文件夹
    cd /myredis
    
    • 1
    • 2
    • 3
    • 4

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

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

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

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

    紧接着我们创建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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    创建完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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    修改完配置文件后记得保存
    在这里插入图片描述
    相关配置内容作用如下

    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 // 设置集群节点间访问密码 没有设置密码的话就不需要设置
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2. 服务启动

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

    redis-cli -p 6379
    auth 331213 // Redis密码
    shutdown
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    然后我们再使用下面的命令启动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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    ps -ef | grep redis
    
    • 1

    在这里插入图片描述

    3. 合并为集群

    组合之前,请确保所有redis实例启动后,nodes-xxxx.conf文件都生成正常。
    正常启动后都会在启动目录生成一个nodes-xxxx.conf 文件
    在这里插入图片描述
    在合并集群之前我们首先要进入到Redis安装目录下的 src 目录下
    注:如果是比较老的Redis版本还需要安装一个环境。

    cd /usr/src/redis-6.2.6/src
    
    • 1

    这个命令集成了那个环境,所以我们需要使用到它,所以我们得在src目录下执行后续的命令。
    在这里插入图片描述
    紧接着我们执行以下命令合并启动的服务成为一个集群

    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
    
    • 1

    –replicas 1 采用最简单的方式配置集群,一台主机,一台从机,正好三组。
    注意:此处不要用127.0.0.1, 请用真实IP地址
    -a 331213 Redis服务密码 (设置了密码就要指定否则报错)
    然后会出现下面的页面
    在这里插入图片描述输入 yes 然后回车即可,这是询问是否同意它的分配,可以看到 6379 6380 6381 被分配为主服务器,下面是分配的从服务器,输入yes回车后可以看到以下界面,证明集群已经完成搭建了。
    在这里插入图片描述
    All 16384 slots covered. 这个的意思是请参考下文

    4. 连接集群

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

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

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

    auth 331213 // Redis密码
    cluster nodes
    
    • 1
    • 2

    在这里插入图片描述
    myself,master 是当前连接的Redsi服务

    三. 其他

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

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

    2. 什么是slots?

    在这里插入图片描述
    一个 Redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个,
    集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
    集群中的每个节点负责处理一部分插槽。 举个例子, 如果一个集群可以有主节点, 其中:
    节点 A 负责处理 0 号至 5460 号插槽。
    节点 B 负责处理 5461 号至 10922 号插槽。
    节点 C 负责处理 10923 号至 16383 号插槽。
    也可以使用上面的 cluster nodes 命令查看服务占用的插槽范围
    在这里插入图片描述

    3. 插入数据

    当我们插入一条数据时,首先会计算键的插槽值所在范围,再将其存入对应范围的Redis服务,如果插入的值不在当前服务的插槽范围内,则会自动跳转到对应范围的插槽服务器进行存储。
    但是注意 集群不能同时直接加入多个值。会出现 (error)CROSSSLOT Keysin requestdon’t hashto thesameslot的错误
    可以通过{}来定义组的概念,从而使key中{}内相同内容的键值对放到一个slot中去。{}中是组的名字
    在这里插入图片描述

    4. 故障恢复

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

    shutdown
    
    • 1

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

    redis-cli  -c -p 6380
    
    • 1

    再使用命令查看集群状态

    auth 331213 // Redis密码
    cluster nodes
    
    • 1
    • 2

    可以看到6381已经挂掉了,但是还是有3台主机证明有从机上位了
    在这里插入图片描述
    这时如果再启动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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    【JavaSE】初识泛型
    基于SSH的酒店管理系统
    新学期,新Java
    算法模块如何保证依赖数据的同步
    iOS黑(灰)白化实现方案
    银行笔试题 java笔试题
    linux C MD5计算
    五年制专转本备考中如何进行有效的自我管理
    Linux 批量杀死进程(详细版本)
    Java 类之 java.lang.System
  • 原文地址:https://blog.csdn.net/Siebert_Angers/article/details/127718270