redis集群创建

一、简介

1.1、Redis集群介绍

Redis 集群是一个提供在多个Redis间节点间共享数据的程序集。

Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误.

Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令. Redis 集群的优势:

      • 自动分割数据到不同的节点上。
      • 整个集群的部分节点失败或者不可达的情况下能够继续处理命令。

1.2、Redis 集群的数据分片

Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.

Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:

      • 节点 A 包含 0 到 5500号哈希槽.
      • 节点 B 包含5501 到 11000 号哈希槽.
      • 节点 C 包含11001 到 16384号哈希槽.

这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.

Redis 集群的主从复制模型

为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品.

在我们例子中具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用.

然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了

不过当B和B1 都失败后,集群是不可用的.

1.4、Redis 一致性保证

Redis 并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操作.

第一个原因是因为集群是用了异步复制. 写操作过程:

      • 客户端向主节点B写入一条命令.
      • 主节点B向客户端回复命令状态.
      • 主节点将写操作复制给他得从节点 B1, B2 和 B3.

主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。 注意:Redis 集群可能会在将来提供同步写的方法。 Redis 集群另外一种可能会丢失命令的情况是集群出现了网络分区, 并且一个客户端与至少包括一个主节点在内的少数实例被孤立。

举个例子 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, A1 、B1 、C1 为A,B,C的从节点, 还有一个客户端 Z1 假设集群中发生网络分区,那么集群可能会分为两方,大部分的一方包含节点 A 、C 、A1 、B1 和 C1 ,小部分的一方则包含节点 B 和客户端 Z1 .

Z1仍然能够向主节点B中写入, 如果网络分区发生时间较短,那么集群将会继续正常运作,如果分区的时间足够让大部分的一方将B1选举为新的master,那么Z1写入B中得数据便丢失了.

注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项:

 

 

 

 

yum    install    ruby
yum    install    rubygems
gem    install    redis

 

 

 

 

cluster,从创建六个节点目录

mkdir reids-cluster
cd reids-cluster
mkdir 7000 7001 7002 7003 7004 7005

    在文件夹 7000 至 7005 中, 各创建一个 redis.conf 文件,配置文件内容如下:

#这是官方最少选项的配置文件内容
#端口,六个节点中只有这个是不同
port 7000  
#是否启动集群模式
cluster-enabled yes
#设定了保存节点配置文件的路径, 默认值为 nodes.conf.节点配置文件无须人为修改, 它由 Redis 集群在启动时创建, 并在有需要时自动进行更新  
cluster-config-file nodes.conf
#几点超时时间
cluster-node-timeout 5000
#是否开启aof
appendonly yes


#下面是可以添加的
#密码设置,集群密码必须一致
requirepass  123456
#绑定ip地址
bind  127.0.0.1
#日志输出路径
logfile /usr/local/redis-5.0.0/redis-cluster/7001/redis.log
#数据文件存放位置
dir  /usr/local/redis-5.0.0/redis-cluster/7001/data
#是否设置为后台进程
daemonize yes
#设置pid文件,如果是守护进程并且没有指定这个文件,那么默认是/var/run/redis.pid
pidfile  /usr/local/redis-5.0.0/redis-cluster/7001/redis_7001

使用如下命令依次启动所有实例:

cd 7000
../redis-server ./redis.conf

通过使用 Redis 集群命令行工具 redis-trib 来完成创建新集群, 检查集群, 或者对集群进行重新分片(reshared)等工作

./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
#选项–replicas 1 表示我们希望为集群中的每个主节点创建一个从节点

之后跟着的其他参数则是这个集群实例的地址列表,3个master3个slave redis-trib 会打印出一份预想中的配置给你看, 如果你觉得没问题的话, 就可以输入 yes , redis-trib 就会将这份配置应用到集群当中,让各个节点开始互相通讯,最后可以得到如下信息:

[OK] All 16384 slots covered

2.3、使用实例

    使用redis-cli来进行连接

src/redis-cli -c -p 7001 -h 127.0.0.1 -a 123456
#
-c  启动集群
-p  指定端口
-h  指定ip
-a  密码

    连接后使用如下命令查看集群信息

cluster info  或者  info

 

三、集群拓展

  3.1、集群重新分片

    重新分片可以使用 redis-trib 程序来执行 执行以下命令可以开始一次重新分片操作

src/redis-trib.rb reshard 127.0.0.1:7000  //下面是主要过程
  1. How many slots do you want to move (from 1 to 16384)? 1000 //设置slot数1000  
  2. What is the receiving node ID? 03ccad2ba5dd1e062464bc7590400441fafb63f2 //新节点node id  
  3. Please enter all the source node IDs.  
  4.  Type 'all' to use all the nodes as source nodes for the hash slots.  
  5.  Type 'done' once you entered all the source nodes IDs.  
  6. Source node #1:all //表示全部节点重新洗牌  
  7. Do you want to proceed with the proposed reshard plan (yes/no)? yes //确认重新分 
 

    你只需要指定集群中其中一个节点的地址, redis-trib 就会自动找到集群中的其他节点。目前 redis-trib 只能在管理员的协助下完成重新分片的工作, 要让 redis-trib 自动将哈希槽从一个节点移动到另一个节点, 目前来说还做不到。在重新分片结束后你可以通过如下命令检查集群状态:

src/redis-trib.rb check 127.0.0.1:7000

  3.2、添加一个新节点

    3.2.1、添加主节点

      启动新的7006节点,使用的配置文件和以前的一样,只要把端口号改一下即可,过程如下:

      • 在终端打开一个新的标签页.
      • 进入cluster-test 目录.
      • 创建并进入 7006文件夹.
      • 和其他节点一样,创建redis.conf文件,需要将端口号改成7006.
      • 最后启动节点 ../redis-server ./redis.conf
      • 如果正常的话,节点会正确的启动.

      接下来使用redis-trib 来添加这个节点到现有的集群中去.

src/redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
使用addnode命令来添加节点,第一个参数是新节点的地址,第二个参数是任意一个已经存在的节点的IP和端口

      用下面的命令来查看节点:

cluster nodes

      新节点现在已经连接上了集群, 成为集群的一份子, 并且可以对客户端的命令请求进行转向了, 但是和其他主节点相比, 新节点还有两点区别:

      • 新节点没有包含任何数据, 因为它没有包含任何哈希槽.
      • 尽管新节点没有包含任何哈希槽, 但它仍然是一个主节点, 所以在集群需要将某个从节点升级为新的主节点时, 这个新节点不会被选中。

      接下来, 只要使用 redis-trib 程序, 将集群中的某些哈希桶移动到新节点里面, 新节点就会成为真正的主节点了。

    3.2.2、添加一个从节点

      有两种方法添加从节点,可以像添加主节点一样使用redis-trib 命令,也可以像下面的例子一样使用 –slave选项:

src/redis-trib.rb add-node --slave 127.0.0.1:7006 127.0.0.1:7000

      此处的命令和添加一个主节点命令类似,此处并没有指定添加的这个从节点的主节点,这种情况下系统会在其他的复制集中的主节点中随机选取一个作为这个从节点的主节点。

      可以通过下面的命令指定主节点:

src/redis-trib.rb add-node --slave --master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7006 127.0.0.1:7000

      也可以使用CLUSTER REPLICATE 命令添加.这个命令也可以改变一个从节点的主节点。

      例如,要给主节点 127.0.0.1:7005添加一个从节点,该节点哈希槽的范围1423-16383, 节点 ID 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e,我们需要链接新的节点(已经是空的主节点)并执行命令:

redis 127.0.0.1:7006> cluster replicate 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e

      我们新的从节点有了一些哈希槽,其他的节点也知道(过几秒后会更新他们自己的配置),可以使用如下命令确认:

$ src/redis-cli -p 7000 cluster nodes | grep slave | grep 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e

   3.3、移除一个节点

      只要使用 del-node 命令即可:

src/redis-trib del-node 127.0.0.1:7000 `<node-id>`
第一个参数是任意一个节点的地址,第二个节点是你想要移除的节点地址。

      使用同样的方法移除主节点,不过在移除主节点前,需要确保这个主节点是空的. 如果不是空的,需要将这个节点的数据重新分片到其他主节点上.

      替代移除主节点的方法是手动执行故障恢复,被移除的主节点会作为一个从节点存在,不过这种情况下不会减少集群节点的数量,也需要重新分片数据.取消过程如下:

# src/redis-trib.rb reshard 192.168.10.219:6378 //取消分配的slot,下面是主要过程  
  
How many slots do you want to move (from 1 to 16384)? 1000 //被删除master的所有slot数量  
What is the receiving node ID? 5d8ef5a7fbd72ac586bef04fa6de8a88c0671052 //接收6378节点slot的master  
Please enter all the source node IDs.  
 Type 'all' to use all the nodes as source nodes for the hash slots.  
 Type 'done' once you entered all the source nodes IDs.  
Source node #1:03ccad2ba5dd1e062464bc7590400441fafb63f2 //被删除master的node-id  
Source node #2:done   
  
Do you want to proceed with the proposed reshard plan (yes/no)? yes //取消slot后,reshard  

 

 

 

posted @ 2018-11-12 16:11  摆渡·人  阅读(232)  评论(0编辑  收藏  举报