Redis 集群


Redis 集群 Redis Cluster

Docker搭建redis集群

配置6个redis docker容器实例,端口分别为6379,6380,6381,6389,6390,6391

我们依次创建六个redis配置文件

修改配置文件选项

port 6379 #端口号
requirepass 123456 #设置redis密码
masterauth 123456 #如果设置了requirepass 这个也要设置
dbfilename dump6379.rdb
cluster-enabled yes #开启redis集群模式
cluster-config-file nodes-6379.conf #设定节点配置文件名
cluster-node-timeout 15000 设置节点失联时间

然后复制到其他配置文件将6379替换为响应端口号

image-20220302193229727

启动6个容器

docker run -p 6379:6379 --name redis-6379 -v /mydata/redis/conf/redis6379.conf:/etc/redis/redis.conf -v /mydata/redis/data/6379:/data -d redis redis-server /etc/redis/redis.conf

docker run -p 6380:6380 --name redis-6380 -v /mydata/redis/conf/redis6380.conf:/etc/redis/redis.conf -v /mydata/redis/data/6380:/data -d redis redis-server /etc/redis/redis.conf

docker run -p 6381:6381 --name redis-6381 -v /mydata/redis/conf/redis6381.conf:/etc/redis/redis.conf -v /mydata/redis/data/6381:/data -d redis redis-server /etc/redis/redis.conf

docker run -p 6389:6389 --name redis-6389 -v /mydata/redis/conf/redis6389.conf:/etc/redis/redis.conf -v /mydata/redis/data/6389:/data -d redis redis-server /etc/redis/redis.conf

docker run -p 6390:6390 --name redis-6390 -v /mydata/redis/conf/redis6390.conf:/etc/redis/redis.conf -v /mydata/redis/data/6390:/data -d redis redis-server /etc/redis/redis.conf

docker run -p 6391:6391 --name redis-6391 -v /mydata/redis/conf/redis6391.conf:/etc/redis/redis.conf -v /mydata/redis/data/6391:/data -d redis redis-server /etc/redis/redis.conf

当然如果你不想写配置文件和设置密码的话,可以按照尚硅谷的方法https://www.bilibili.com/video/BV1gr4y1U7CY?p=45

更简便

docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386   

--net host 使用宿主机的ip和端口

--priviliged=true 获得宿主机root用户权限

-v /data/redis/share/redis-node-3:/data 容器卷 宿主机地址:docker内部地址

cluster-enabled yes 开机redis集群

--appendonly yes 开启AOF持久化

--port 6386 redis端口号

查看6个容器的内网ip地址

docker network inspect bridge

image-20220302202905609

redis-6379 172.17.0.3
redis-6380 172.17.0.4
redis-6381 172.17.0.5
redis-6389 172.17.0.6
redis-6390 172.17.0.7
redis-6391 172.17.0.8

将6个节点合成一个集群

进入redis-6379容器,如果使用第二种方法启动redis容器,那么请使用外网ip地址

redis-cli --cluster create --cluster-replicas 1 172.17.0.3:6379 172.17.0.4:6380 172.17.0.5:6381 172.17.0.6:6389 172.17.0.7:6390 172.17.0.8:6391 -a in12JS

使用第二种方法的

redis-cli --cluster create --cluster-replicas 1 192.168.56.10:6381 192.168.56.10:6382 192.168.56.10:6383 192.168.56.10:6384 192.168.56.10:6385 192.168.56.10:6386

如果配置文件加了密码一定要加 -a <密码>

查看集群信息,连接redis节点,参数一定要带-c 否则读取或写入数值会报错(error)moved

docker exec -it redis-xxxx redis-cli -p <port> -a <requirepass> -c
127.0.0.1:6379> cluster nodes 

image-20220303000449493

[OK] All 16384 slots covered.

redis集群搭建成功后,控制台会显示

image-20220303102348787

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

集群操作

插入值

image-20220303103637929

插入多个值

分到user组,集群就会根据”user”来计算插槽

mset name{user} lucy age{user} 20

查询集群的值

cluster getkeysinslot 返回count个slot槽中的键

image-20220303105116512

只能看当前节点插槽范围内的值 所以12706 的值为0

故障恢复

如果主节点下线,从节点会自动升为主节点,主节点回复后,主节点变为从机。

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

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

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

redis.conf中的参数cluster-require-full-coverage 默认是yes

集群的jedis开发

即使连接的不是主机,集群也会自动切换为主机存储。主机写,从机读。

无中心化主从集群,无论从哪台主机写的数据,其他主机上都能读到数据。

public class JedisClusterTest {
    public static void main(String[] args) {

        HashSet<HostAndPort> nodes = new HashSet<>();

        nodes.add(new HostAndPort("192.168.56.10",6381));

        JedisCluster jedisCluster = new JedisCluster(nodes);
        jedisCluster.set("k5","v5");
        System.out.println(jedisCluster.get("k5"));
        jedisCluster.close();
    }
}

带密码的还不会,卡在这里,以后再解决


Author: qwq小小舒
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source qwq小小舒 !
  TOC