Redis——集群

集群

1、问题

  • 容量不够,redis如何进行扩容?
  • 并发写操作, redis如何分摊?

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

之前通过代理主机来解决,但是redis3.0中提供了解决方案。就是无中心化集群配置

在这里插入图片描述


2、什么是集群?

Redis集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。

Redis集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。


3、案例

3.1、删除持久化数据

将rdb,aof文件都删除掉

3.2、制作6个实例,6379,6380,6381,6389,6390,6391

  1. 配置基本信息

    开启daemonize yes

    Pid文件名字

    指定端口

    Log文件名字

    Dump.rdb名字

    Appendonly 关掉或者换名字

  2. redis cluster配置修改

    cluster-enabled yes 打开集群模式

    cluster-config-file nodes-6379.conf 设定节点配置文件名

    cluster-node-timeout 15000 设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换。

    include /home/bigdata/redis.conf
    port 6379
    pidfile "/var/run/redis_6379.pid"
    dbfilename "dump6379.rdb"
    dir "/home/bigdata/redis_cluster"
    logfile "/home/bigdata/redis_cluster/redis_err_6379.log"
    cluster-enabled yes
    cluster-config-file nodes-6379.conf
    cluster-node-timeout 15000
    
  3. 修改好redis6379.conf文件,拷贝多个redis.conf文件

    [root@sunlight myredis]# cp redis6379.conf redis6380.conf
    [root@sunlight myredis]# cp redis6379.conf redis6381.conf
    [root@sunlight myredis]# cp redis6379.conf redis6389.conf
    [root@sunlight myredis]# cp redis6379.conf redis6390.conf
    [root@sunlight myredis]# cp redis6379.conf redis6391.conf
    
    [root@sunlight myredis]# ll
    总用量 120
    -rw-r--r--. 1 root root   181 3月  13 19:27 redis6379.conf
    -rw-r--r--. 1 root root   181 3月  13 19:27 redis6380.conf
    -rw-r--r--. 1 root root   181 3月  13 19:27 redis6381.conf
    -rw-r--r--. 1 root root   181 3月  13 19:27 redis6389.conf
    -rw-r--r--. 1 root root   181 3月  13 19:28 redis6390.conf
    -rw-r--r--. 1 root root   181 3月  13 19:28 redis6391.conf
    -rw-r--r--. 1 root root 93687 3月  13 17:50 redis.conf
    -rw-r--r--. 1 root root    43 3月  13 18:53 sentinel.conf
    
  4. 使用查找替换修改另外5个文件

    例如:

    :%s/6379/6380
    
  5. 启动6个redis

    [root@sunlight myredis]# redis-server redis6379.conf
    [root@sunlight myredis]# redis-server redis6380.conf
    [root@sunlight myredis]# redis-server redis6381.conf
    [root@sunlight myredis]# redis-server redis6389.conf
    [root@sunlight myredis]# redis-server redis6390.conf
    [root@sunlight myredis]# redis-server redis6391.conf
    
    [root@sunlight myredis]# ps -ef | grep redis
    root      99196      1  0 19:37 ?        00:00:00 redis-server *:6379 [cluster]
    root      99250      1  0 19:37 ?        00:00:00 redis-server *:6380 [cluster]
    root      99288      1  0 19:37 ?        00:00:00 redis-server *:6381 [cluster]
    root      99743      1  0 19:38 ?        00:00:00 redis-server *:6389 [cluster]
    root      99319      1  0 19:37 ?        00:00:00 redis-server *:6390 [cluster]
    root      99503      1  0 19:38 ?        00:00:00 redis-server *:6391 [cluster]
    root      99765  76692  0 19:38 pts/0    00:00:00 grep --color=auto redis
    
    [root@sunlight myredis]# ll
    总用量 144
    -rw-r--r--. 1 root root   114 3月  13 19:37 nodes-6379.conf
    -rw-r--r--. 1 root root   114 3月  13 19:37 nodes-6380.conf
    -rw-r--r--. 1 root root   114 3月  13 19:37 nodes-6381.conf
    -rw-r--r--. 1 root root   114 3月  13 19:38 nodes-6389.conf
    -rw-r--r--. 1 root root   114 3月  13 19:37 nodes-6390.conf
    -rw-r--r--. 1 root root   114 3月  13 19:38 nodes-6391.conf
    -rw-r--r--. 1 root root   183 3月  13 19:36 redis6379.conf
    -rw-r--r--. 1 root root   183 3月  13 19:36 redis6380.conf
    -rw-r--r--. 1 root root   183 3月  13 19:36 redis6381.conf
    -rw-r--r--. 1 root root   183 3月  13 19:37 redis6389.conf
    -rw-r--r--. 1 root root   183 3月  13 19:37 redis6390.conf
    -rw-r--r--. 1 root root   183 3月  13 19:38 redis6391.conf
    -rw-r--r--. 1 root root 93687 3月  13 17:50 redis.conf
    -rw-r--r--. 1 root root    43 3月  13 18:53 sentinel.conf
    

3.3、将六个节点合成一个集群

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

  • 合并

    必须进入到 redis 的安装目录的 src 目录下:

    /usr/local/redis/redis-6.2.6/src
    

    redis-cli --cluster create --cluster-replicas 1 192.168.196.128:6379 192.168.196.128:6380 192.168.196.128:6381 192.168.196.128:6389 192.168.196.128:6390 192.168.196.128:6391

    • 此处不要用127.0.0.1, 请用真实IP地址

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

    [root@sunlight src]# redis-cli --cluster create --cluster-replicas 1 192.168.196.128:6379 192.168.196.128:6380 192.168.196.128:6381 192.168.196.128:6389 192.168.196.128:6390 192.168.196.128:6391
    >>> Performing hash slots allocation on 6 nodes...
    Master[0] -> Slots 0 - 5460
    Master[1] -> Slots 5461 - 10922
    Master[2] -> Slots 10923 - 16383
    Adding replica 192.168.196.128:6390 to 192.168.196.128:6379
    Adding replica 192.168.196.128:6391 to 192.168.196.128:6380
    Adding replica 192.168.196.128:6389 to 192.168.196.128:6381
    >>> Trying to optimize slaves allocation for anti-affinity
    [WARNING] Some slaves are in the same host as their master
    M: 4e77b4e2b820417129d967571e3a9260a6eaf2f8 192.168.196.128:6379
       slots:[0-5460] (5461 slots) master
    M: 4c0a73ed25e5984d3a668d51cf17f4022e6dda21 192.168.196.128:6380
       slots:[5461-10922] (5462 slots) master
    M: a3d0654f40e1095d5fe98241a1cad98044fa7973 192.168.196.128:6381
       slots:[10923-16383] (5461 slots) master
    S: e84acee8cd4706ffee061e7adce04901d27afa7a 192.168.196.128:6389
       replicates 4c0a73ed25e5984d3a668d51cf17f4022e6dda21
    S: 9d454442349c639d91853835d6d9ad140df8daef 192.168.196.128:6390
       replicates a3d0654f40e1095d5fe98241a1cad98044fa7973
    S: fd3f387e47a04b5b40370f8ad2feabff849ac4e5 192.168.196.128:6391
       replicates 4e77b4e2b820417129d967571e3a9260a6eaf2f8
    Can I set the above configuration? (type 'yes' to accept): yes
    >>> Nodes configuration updated
    >>> Assign a different config epoch to each node
    >>> Sending CLUSTER MEET messages to join the cluster
    Waiting for the cluster to join
    .
    >>> Performing Cluster Check (using node 192.168.196.128:6379)
    M: 4e77b4e2b820417129d967571e3a9260a6eaf2f8 192.168.196.128:6379
       slots:[0-5460] (5461 slots) master
       1 additional replica(s)
    S: fd3f387e47a04b5b40370f8ad2feabff849ac4e5 192.168.196.128:6391
       slots: (0 slots) slave
       replicates 4e77b4e2b820417129d967571e3a9260a6eaf2f8
    M: 4c0a73ed25e5984d3a668d51cf17f4022e6dda21 192.168.196.128:6380
       slots:[5461-10922] (5462 slots) master
       1 additional replica(s)
    S: e84acee8cd4706ffee061e7adce04901d27afa7a 192.168.196.128:6389
       slots: (0 slots) slave
       replicates 4c0a73ed25e5984d3a668d51cf17f4022e6dda21
    M: a3d0654f40e1095d5fe98241a1cad98044fa7973 192.168.196.128:6381
       slots:[10923-16383] (5461 slots) master
       1 additional replica(s)
    S: 9d454442349c639d91853835d6d9ad140df8daef 192.168.196.128:6390
       slots: (0 slots) slave
       replicates a3d0654f40e1095d5fe98241a1cad98044fa7973
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    

3.4、-c 采用集群策略连接,设置数据会自动切换到相应的写主机

[root@sunlight src]# redis-cli -c -p 6379
127.0.0.1:6379> CLUSTER NODES
4e77b4e2b820417129d967571e3a9260a6eaf2f8 192.168.196.128:6379@16379 myself,master - 0 1647172500000 1 connected 0-5460
fd3f387e47a04b5b40370f8ad2feabff849ac4e5 192.168.196.128:6391@16391 slave 4e77b4e2b820417129d967571e3a9260a6eaf2f8 0 1647172502000 1 connected
4c0a73ed25e5984d3a668d51cf17f4022e6dda21 192.168.196.128:6380@16380 master - 0 1647172503432 2 connected 5461-10922
e84acee8cd4706ffee061e7adce04901d27afa7a 192.168.196.128:6389@16389 slave 4c0a73ed25e5984d3a668d51cf17f4022e6dda21 0 1647172504459 2 connected
a3d0654f40e1095d5fe98241a1cad98044fa7973 192.168.196.128:6381@16381 master - 0 1647172503000 3 connected 10923-16383
9d454442349c639d91853835d6d9ad140df8daef 192.168.196.128:6390@16390 slave a3d0654f40e1095d5fe98241a1cad98044fa7973 0 1647172502385 3 connected
  • 通过 cluster nodes 命令查看集群信息

3.5、redis cluster 如何分配这六个节点?

一个集群至少要有三个主节点。

选项 --cluster-replicas 1 表示我们希望为集群中的每个主节点创建一个从节点

分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上

3.6、什么是slot?

[OK] All 16384 slots covered.

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

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

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

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

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

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

3.7、在集群中键入值

在redis-cli每次录入、查询键值,redis都会计算出该key应该送往的插槽,如果不是该客户端对应服务器的插槽,redis会报错,并告知应前往的redis实例地址和端口。

redis-cli客户端提供了 –c 参数实现自动重定向。

如 redis-cli -c –p 6379 登入后,再录入、查询键值对可以自动重定向。

不在一个slot下的键值,是不能使用mget,mset等多键操作

127.0.0.1:6379> mset name lucy age 20 address china
(error) CROSSSLOT Keys in request don't hash to the same slot

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

127.0.0.1:6379> mset name{user} lucy age{user} 20
-> Redirected to slot [5474] located at 192.168.196.128:6380
OK

3.8、查询集群中的值

192.168.196.128:6380> cluster keyslot user
(integer) 5474
192.168.196.128:6380> cluster countkeysinslot 5474
(integer) 2
192.168.196.128:6380> cluster getkeysinslot 5474 10
1) "age{user}"
2) "name{user}"

3.9、故障恢复

如果主节点下线?从节点能否自动升为主节点?注意:15秒超时

[root@sunlight src]# redis-cli -c -p 6379
127.0.0.1:6379> shutdown
not connected> exit
[root@sunlight src]# redis-cli -c -p 6380
127.0.0.1:6380> cluster nodes
9d454442349c639d91853835d6d9ad140df8daef 192.168.196.128:6390@16390 slave a3d0654f40e1095d5fe98241a1cad98044fa7973 0 1647173840000 3 connected
a3d0654f40e1095d5fe98241a1cad98044fa7973 192.168.196.128:6381@16381 master - 0 1647173841147 3 connected 10923-16383
fd3f387e47a04b5b40370f8ad2feabff849ac4e5 192.168.196.128:6391@16391 master - 0 1647173842176 7 connected 0-5460
4e77b4e2b820417129d967571e3a9260a6eaf2f8 192.168.196.128:6379@16379 master,fail - 1647173796038 1647173792000 1 disconnected
e84acee8cd4706ffee061e7adce04901d27afa7a 192.168.196.128:6389@16389 slave 4c0a73ed25e5984d3a668d51cf17f4022e6dda21 0 1647173840110 2 connected
4c0a73ed25e5984d3a668d51cf17f4022e6dda21 192.168.196.128:6380@16380 myself,master - 0 1647173841000 2 connected 5461-10922

主节点恢复后,主从关系会如何?主节点回来变成从机。

[root@sunlight myredis]# redis-server redis6379.conf
127.0.0.1:6380> cluster nodes
9d454442349c639d91853835d6d9ad140df8daef 192.168.196.128:6390@16390 slave a3d0654f40e1095d5fe98241a1cad98044fa7973 0 1647173916000 3 connected
a3d0654f40e1095d5fe98241a1cad98044fa7973 192.168.196.128:6381@16381 master - 0 1647173917944 3 connected 10923-16383
fd3f387e47a04b5b40370f8ad2feabff849ac4e5 192.168.196.128:6391@16391 master - 0 1647173917000 7 connected 0-5460
4e77b4e2b820417129d967571e3a9260a6eaf2f8 192.168.196.128:6379@16379 slave fd3f387e47a04b5b40370f8ad2feabff849ac4e5 0 1647173914322 7 connected
e84acee8cd4706ffee061e7adce04901d27afa7a 192.168.196.128:6389@16389 slave 4c0a73ed25e5984d3a668d51cf17f4022e6dda21 0 1647173916910 2 connected
4c0a73ed25e5984d3a668d51cf17f4022e6dda21 192.168.196.128:6380@16380 myself,master - 0 1647173915000 2 connected 5461-10922

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

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

3.10、集群的Jedis开发

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

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

@Test
public void Test(){
    Set<HostAndPort>set =new HashSet<HostAndPort>();
    set.add(new HostAndPort("192.168.196.128",6379));
    JedisCluster jedisCluster=new JedisCluster(set);
    jedisCluster.set("k1", "v1");
    System.out.println(jedisCluster.get("k1"));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值