Redis系列~集群(二十三)


redis集群


简介

redis集群是一个无中心的分布式Redis存储架构,可以在多个节点之间进行数据共享,解决了Redis高可用、可扩展等问题。redis集群提供了以下两个好处

1、将数据自动切分(split)到多个节点

2、当集群中的某一个节点故障时,redis还可以继续处理客户端的请求。

 

一个 Redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。

 

集群中的主从复制

集群中的每个节点都有1个至N个复制品,其中一个为主节点,其余的为从节点,如果主节点下线了,集群就会把这个主节点的一个从节点设置为新的主节点,继续工作。这样集群就不会因为一个主节点的下线而无法正常工作。

 

注意:

1、如果某一个主节点和他所有的从节点都下线的话,redis集群就会停止工作了。redis集群不保证数据的强一致性,在特定的情况下,redis集群会丢失已经被执行过的写命令

2、使用异步复制(asynchronous replication)是 Redis 集群可能会丢失写命令的其中一个原因,有时候由于网络原因,如果网络断开时间太长,redis集群就会启用新的主节点,之前发给主节点的数据就会丢失。

Redis系列~集群(二十三)_第1张图片

 

 

安装配置

修改配置文件redis.conf

[python]  view plain  copy
 
  1. daemonize yes  
  2. port 6379  
  3. cluster-enabled yes  
  4. cluster-config-file nodes.conf  
  5. cluster-node-timeout 5000  

 

要让集群正常运作至少需要三个主节点

我们这里就简单在一台主机上创建6个redis节点来演示集群配置,实际生产环境中需要每个节点一台主机。

 

我们要创建的6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下:

[python]  view plain  copy
 
  1. 192.168.33.130:7000  
  2. 192.168.33.130:7001  
  3. 192.168.33.130:7002  
  4. 192.168.33.130:7003  
  5. 192.168.33.130:7004  
  6. 192.168.33.130:7005  


1、首先我们创建6个以端口为名称的文件夹(由于每个redis节点启动的时候,都会在当前文件夹下创建快照文件,所以我们需要创建每个节点的启动目录)

[python]  view plain  copy
 
  1. mkdir 7000  
  2. mkdir 7001  
  3. mkdir 7002  
  4. mkdir 7003  
  5. mkdir 7004  
  6. mkdir 7005  

 

2、接下来把每个节点启动所需要的配置文件拷贝到相应的启动目录:

[python]  view plain  copy
 
  1. cp redis.conf  7000  
  2. cp redis.conf  7001  
  3. cp redis.conf  7002  
  4. cp redis.conf  7003  
  5. cp redis.conf  7004  
  6. cp redis.conf  7005  

3、然后我们进入每个启动目录,修改之前拷贝的redis.conf文件中的端口port 为上面列出的对应端口。

最终每个节点的配置类似于:

[python]  view plain  copy
 
  1. daemonize yes  
  2. port 6379     #只有端口不同,其他相同  
  3. cluster-enabled yes  
  4. cluster-config-file nodes.conf  
  5. cluster-node-timeout 5000  
 

4、进入每个启动目录,以每个目录下的redis.conf文件启动

 Redis系列~集群(二十三)_第2张图片

 

使用命令查看redis节点是否启动

[python]  view plain  copy
 
  1. ps -ef | grep redis  

Redis系列~集群(二十三)_第3张图片



5、创建集群命令

[python]  view plain  copy
 
  1. redis-trib.rb  create --replicas 1 192.168.33.130:7000 192.168.33.130:7001 192.168.33.130:7002 192.168.33.130:7003 192.168.33.130:7004 192.168.33.130:7005  

注意:

5.1、执行上面的命令的时候可能会报错,因为是执行的ruby的脚本,需要ruby的环境

错误内容:

 

所以我们需要安装ruby的环境,这里推荐使用yum安装:

[python]  view plain  copy
 
  1. yum install ruby  

 

5.2、安装ruby后,执行命令可能还会报错,提示缺少rubygems组件,使用yum安装

 Redis系列~集群(二十三)_第4张图片

解决方法:

[python]  view plain  copy
 
  1. yum install rubygems  


5.3、上面两个步骤后,执行创建集群目录可能还会报错,提示不能加载redis,是因为缺少redis和ruby的接口,使用gem 安装。

 

解决方法:

[python]  view plain  copy
 
  1. gem install redis  

或者可以命令:

wget https://rubygems.org/downloads/redis-3.3.1.gem


搞不下来的话,直接去网站:https://rubygems.org/gems/redis  下吧, 然后执行:

  1. gem install -l ~/Downloads/redis-3.3.1.gem 



上面三个问题解决后,启动创建集群应该可以正常启动了:

 Redis系列~集群(二十三)_第5张图片


Redis系列~集群(二十三)_第6张图片

这里输入yes

 

最后结果:

 Redis系列~集群(二十三)_第7张图片

 

到此,我们的集群搭建成功了。

 

6、接下来我们使用命令进入集群环境

[python]  view plain  copy
 
  1. redis-cli -c -p 7000  




redis集群操作

使用redis-cli客户端来操作redis集群,使用命令 :

[python]  view plain  copy
 
  1. redis-cli -c  -p [port]  


查看集群中的所有主节点信息

[python]  view plain  copy
 
  1. redis-cli -c -p 7000 cluster nodes [| grep master]  
Redis系列~集群(二十三)_第8张图片



redis集群添加节点

 

根据添加节点类型的不同,有两种方法来添加新节点

1、主节点:如果添加的是主节点,那么我们需要创建一个空节点,然后将某些哈希槽移动到这个空节点里面

2、从节点:如果添加的是从节点,我们也需要创建一个空节点,然后把这个新节点设置成集群中某个主节点的复制品。

 

 添加节点:

1、首先把需要添加的节点启动

创建7006目录,拷贝7000中的redis.conf到7006中,然后修改端口port为7006,修改好后进入7006目录启动这个节点:

[python]  view plain  copy
 
  1. redis-server redis.conf  

2、执行以下命令,将这个新节点添加到集群中:

[python]  view plain  copy
 
  1. redis-trib.rb add-node 192.168.33.130:7006 192.168.33.130:7000  

结果图示:

 Redis系列~集群(二十三)_第9张图片

 

3、执行命令查看刚才新增的节点:

[python]  view plain  copy
 
  1. redis-cli -c -p 7000 cluster nodes  
Redis系列~集群(二十三)_第10张图片

 

4、增加了新的节点之后,这个新的节点可以成为主节点或者是从节点

 

4.1将这个新增节点变成从节点


前面我们已经把这个新节点添加到集群中了,现在我们要让新节点成为192.168.33.130:7001的从节点,只需要执行下面的命令就可以了,命令后面的节点ID就是192.168.33.130:7001的节点ID。(注意,这个从节点哈希槽必须为空,如果不为空,则需要转移掉哈希槽使之为空)

[python]  view plain  copy
 
  1. redis-cli -c -p 7006 cluster replicate a246963893faf03c45cc19ef4188f82f5393bfef  


使用下面命令来确认一下192.168.33.130:7006是否已经成为192.168.33.130:7001的从节点。

[python]  view plain  copy
 
  1. redis-cli -p 7000 cluster nodes | grep slave | grep a246963893faf03c45cc19ef4188f82f5393bfef  
Redis系列~集群(二十三)_第11张图片

 

4.2、将这个新增节点变成主节点(不能继续使用上面的7006,因为7006已经是从节点,需要使用master节点,再分配slot):

使用redis-trib程序,将集群中的某些哈希槽移动到新节点里面,这个新节点就成为真正的主节点了。执行下面的命令对集群中的哈希槽进行移动:

[python]  view plain  copy
 
  1. redis-trib.rb reshard 192.168.33.130:7000  

命令执行后,系统会提示我们要移动多少哈希槽,这里移动1000个

 

 

然后还需要指定把这些哈希槽转移到哪个节点上

 Redis系列~集群(二十三)_第12张图片

输入我们刚才新增的节点的ID

d113e0f033c98e2f6b88fb93e6e98866256d85c4

 

然后需要我们指定转移哪几个几点的哈希槽

 

输入all 表示从所有的主节点中随机转移,凑够1000个哈希槽

 

然后再输入yes,redis集群就开始分配哈希槽了。

 Redis系列~集群(二十三)_第13张图片

 

至此,一个新的主节点就添加完成了,执行命令查看现在的集群中节点的状态

[python]  view plain  copy
 
  1. redis-cli -c -p 7000 cluster nodes  

结果图示:

 Redis系列~集群(二十三)_第14张图片

 

 

 

Redis集群删除节点

 

1、如果删除的节点是主节点,这里我们删除192.168.33.130:7006节点,这个节点有1000个哈希槽

首先要把节点中的哈希槽转移到其他节点中,执行下面的命令:

[python]  view plain  copy
 
  1. redis-trib.rb reshard 192.168.33.130:7000  

系统会提示我们要移动多少哈希槽,这里移动1000个,因为192.168.33.130:7006节点有1000个哈希槽。

 

 

然后系统提示我们输入要接收这些哈希槽的节点的ID,这里使用192.168.33.130:7001的节点ID

 

 

然后要我们选择从那些节点中转出哈希槽,这里一定要输入192.168.33.130:7006这个节点的ID

Redis系列~集群(二十三)_第15张图片 

最后输入done表示输入完毕。

 

最后一步,使用下面的命令把这个节点删除

[python]  view plain  copy
 
  1. redis-trib.rb del-node 192.168.33.130:7000 d113e0f033c98e2f6b88fb93e6e98866256d85c4    //最后一个参数为需要删除的节点ID  

Redis系列~集群(二十三)_第16张图片

 


2、如果是从节点,直接删除即可。

[python]  view plain  copy
 
  1. redis-trib.rb del-node 192.168.33.130:7000 d113e0f033c98e2f6b88fb93e6e98866256d85c4   //最后一个参数为需要删除节点的ID  
Redis系列~集群(二十三)_第17张图片

 

 

java操作redis集群

 

向Redis集群中存入键值:

 Redis系列~集群(二十三)_第18张图片

 

代码示例:

[java]  view plain  copy
 
  1. import java.util.HashSet;  
  2. //需要再pom.xml中引入jedis依赖  
  3. import redis.clients.jedis.HostAndPort;  
  4. import redis.clients.jedis.JedisCluster;  
  5. import redis.clients.jedis.JedisPool;  
  6. import redis.clients.jedis.JedisPoolConfig;  
  7.   
  8. public class RedisCluster {  
  9.     public static void main(String[] args) {  
  10.         //初始化集合,用于装下面的多个主机和端口  
  11.         HashSet nodes = new HashSet();  
  12.           
  13.         //创建多个主机和端口实例  
  14.         HostAndPort hostAndPort = new HostAndPort("192.168.33.130"7000);  
  15.         HostAndPort hostAndPort1 = new HostAndPort("192.168.33.130"7001);  
  16.         HostAndPort hostAndPort2 = new HostAndPort("192.168.33.130"7002);  
  17.         HostAndPort hostAndPort3 = new HostAndPort("192.168.33.130"7003);  
  18.         HostAndPort hostAndPort4 = new HostAndPort("192.168.33.130"7004);  
  19.         HostAndPort hostAndPort5 = new HostAndPort("192.168.33.130"7005);  
  20.           
  21.         //添加多个主机和端口到集合中  
  22.         nodes.add(hostAndPort);  
  23.         nodes.add(hostAndPort1);  
  24.         nodes.add(hostAndPort2);  
  25.         nodes.add(hostAndPort3);  
  26.         nodes.add(hostAndPort4);  
  27.         nodes.add(hostAndPort5);  
  28.           
  29.         //创建config  
  30.         JedisPoolConfig poolConfig = new JedisPoolConfig();  
  31.         //通过config创建集群实例  
  32.         JedisCluster jedisCluster = new JedisCluster(nodes,poolConfig);  
  33.         //获取集群中的key为name键的值  
  34.         String str = jedisCluster.get("name");  
  35.         System.out.println(str);  
  36.     }  
  37. }  

打印结果:

Redis系列~集群(二十三)_第19张图片

 

 

你可能感兴趣的:(Redis教程)