阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Redis Cluster学习笔记

137次阅读
没有评论

共计 16327 个字符,预计需要花费 41 分钟才能阅读完成。

Redis 在 3.0 版正式引入了集群这个特性。Redis 集群是一个分布式(distributed)、容错(fault-tolerant)的 Redis 内存 K / V 服务,集群可以使用的功能是普通单机 Redis 所能使用的功能的一个子集(subset),比如 Redis 集群并不支持处理多个 keys 的命令, 因为这需要在不同的节点间移动数据, 从而达不到像 Redis 那样的性能, 在高负载的情况下可能会导致不可预料的错误。

Redis 集群的几个重要特征:

(1).Redis 集群的分片特征在于将键空间分拆了 16384 个槽位,每一个节点负责其中一些槽位。

(2).Redis 提供一定程度的可用性, 可以在某个节点宕机或者不可达的情况下继续处理命令.

(3).Redis 集群中不存在中心(central)节点或者代理(proxy)节点,集群的其中一个主要设计目标是达到线性可扩展性(linear scalability)。

1. Redis 的数据分片(Sharding)

Redis 集群的键空间被分割为 16384(2^14)个槽(slot),集群的最大节点数量也是 16384 个(推荐的最大节点数量为 1000 个),同理每个主节点可以负责处理 1 到 16384 个槽位。

当 16384 个槽位都有主节点负责处理时,集群进入”稳定“上线状态,可以开始处理数据命令。当集群没有处理稳定状态时,可以通过执行重配置(reconfiguration)操作,使得每个哈希槽都只由一个节点进行处理。

重配置指的是将某个 / 某些槽从一个节点移动到另一个节点。一个主节点可以有任意多个从节点,这些从节点用于在主节点发生网络断线或者节点失效时,对主节点进行替换。

集群的使用公式 CRC16(Key)&16383 计算 key 属于哪个槽:

HASH_SLOT = CRC16(key) mod 16384

CRC16 其结果长度为 16 位。

下面关于 Redis 的文章您也可能喜欢,不妨参考下:

Ubuntu 14.04 下 Redis 安装及简单测试 http://www.linuxidc.com/Linux/2014-05/101544.htm

Redis 主从复制基本配置 http://www.linuxidc.com/Linux/2015-03/115610.htm

Redis 集群明细文档 http://www.linuxidc.com/Linux/2013-09/90118.htm

Ubuntu 12.10 下安装 Redis(图文详解)+ Jedis 连接 Redis http://www.linuxidc.com/Linux/2013-06/85816.htm

Redis 系列 - 安装部署维护篇 http://www.linuxidc.com/Linux/2012-12/75627.htm

CentOS 6.3 安装 Redis http://www.linuxidc.com/Linux/2012-12/75314.htm

Redis 安装部署学习笔记 http://www.linuxidc.com/Linux/2014-07/104306.htm

Redis 配置文件 redis.conf 详解 http://www.linuxidc.com/Linux/2013-11/92524.htm

2. Redis 集群节点

部分内容摘自附录 2。Redis 集群中的节点不仅要记录键和值的映射,还需要记录集群的状态,包括键到正确节点的映射。它还具有自动发现其他节点,识别工作不正常的节点,并在有需要时,在从节点中选举出新的主节点的功能。

为了执行以上列出的任务,集群中的每个节点都与其他节点建立起了“集群连接(cluster bus)”,该连接是一个 TCP 连接,使用二进制协议进行通讯。

节点之间使用 Gossip 协议 来进行以下工作:

a). 传播(propagate)关于集群的信息,以此来发现新的节点。

b). 向其他节点发送 PING 数据包,以此来检查目标节点是否正常运作。

c). 在特定事件发生时,发送集群信息。

除此之外,集群连接还用于在集群中发布或订阅信息。

集群节点不能前端代理命令请求,所以客户端应该在节点返回 -MOVED或者 -ASK转向(redirection)错误时,自行将命令请求转发至其他节点。

客户端可以自由地向集群中的任何一个节点发送命令请求,并可以在有需要时,根据转向错误所提供的信息,将命令转发至正确的节点,所以在理论上来说,客户端是无须保存集群状态信息的。但如果客户端可以将键和节点之间的映射信息保存起来,可以有效地减少可能出现的转向次数,籍此提升命令执行的效率。

每个节点在集群中由一个独一无二的 ID 标识,该 ID 是一个十六进制表示的 160 位随机数,在节点第一次启动时由 /dev/urandom 生成。节点会将它的 ID 保存到配置文件,只要这个配置文件不被删除,节点就会一直沿用这个 ID。一个节点可以改变它的 IP 和端口号,而不改变节点 ID。集群可以自动识别出 IP/ 端口号的变化,并将这一信息通过 Gossip 协议广播给其他节点知道。

下面是每个节点都有的关联信息,并且节点会将这些信息发送给其他节点:

a). 节点所使用的 IP 地址和 TCP 端口号。

b). 节点的标志(flags)。

c). 节点负责处理的哈希槽。

b). 节点最近一次使用集群连接发送 PING 数据包(packet)的时间。

e). 节点最近一次在回复中接收到 PONG 数据包的时间。

f). 集群将该节点标记为下线的时间。

 

g). 该节点的从节点数量。

如果该节点是从节点的话,那么它会记录主节点的节点 ID。如果这是一个主节点的话,那么主节点 ID 这一栏的值为 0000000。

在了解 Redis Cluster 的集群基本特征后,我们首先搭建出这个 Redis Cluster 集群。

3. 安装 Redis 3.0.x

当前最新版为 3.0.1

wget http://download.redis.io/releases/redis-3.0.1.tar.gz
tar xvzf redis-3.0.1.tar.gz
cd redis-3.0.1/
make -j
#apt-get install tcl
make test
### 将 redis 安装到 /usr/local/redis3 上
#cd src && make PREFIX=/usr/local/redis3 install
### 创建符号链接
 #ls /usr/local/redis3/bin/redis-*
/usr/local/redis3/bin/redis-benchmark  /usr/local/redis3/bin/redis-check-dump  /usr/local/redis3/bin/redis-sentinel
/usr/local/redis3/bin/redis-check-aof  /usr/local/redis3/bin/redis-cli         /usr/local/redis3/bin/redis-server
#for i in `cd /usr/local/redis3/bin; ls redis-*`
do
ln -s /usr/local/redis3/bin/$i /usr/local/bin/$i
done;
#mkdir -p /usr/local/redis3/conf
#ln -sf /usr/local/redis3/conf /etc/redis3
### 检查版本信息
redis-cli -v
redis-cli 3.0.1

4. Redis Cluster 配置

运行在集群模式的 Redis 实例与普通的 Redis 实例有所不同,集群模式需要通过配置启用 cluster 特性,开启集群模式后的 Redis 实例便可以使用集群特有的命令和特性了. 下面是一个最少选项的集群的配置文件 : 注意如果使用的是单机测试,最好把 cluster-config-file nodes.conf 设置为对应的 端口 nodes-xxx.conf,还有就是 pid 设置为当前 目录下 pidfile ./redis.pid

port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

文件中的 cluster-enabled 选项用于开实例的集群模式,而 cluster-conf-file 选项则设定了保存节点配置文件的路径,默认值为 nodes.conf。该节点配置文件无须人为修改,它由 Redis 集群在启动时自动创建,并在有需要时自动进行更新。

若要让集群正常运作至少需要三个主节点,我们的环境中,每个主节点附带一个从节点,所以一共六个节点。端口为 7001-7006。

在 /app/redis3,并创建六个以端口号为名字的子目录,稍后我们在将每个目录中运行一个 Redis 实例:

cd /app/redis3
mkdir 7001 7002 7003 7004 7005 7006
 cp /etc/redis3/conf/redis.conf  /app/redis3/7001/
......
cp /etc/redis3/conf/redis.conf  /app/redis3/7006/

将 redis.conf 里的端口号修改为对应的端口。下面我们打开对应的目录,启动 redis 实例即可,启动的时候要进入到对应的目录然后启动。

cd /app/redis3/7001;nohup redis-server redis.conf &
cd /app/redis3/7002;nohup redis-server redis.conf &
......

实例打印的日志显示,因为 nodes.conf 文件不存在,所以每个节点都为它自身指定了一个新的 ID ,

/app/redis3/7006# tail -f nohup.out
27040:M 09 May 22:53:50.197 * No cluster configuration found, I'm 1984c27297c6ef50bbfcbd35c11b93cc40ba17e4
/app/redis3/7006# cat nodes.conf 
d2b437ca8b9007dcdb63ac16210f6540860361e3 :0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0

现在我们已经有了六个正在运行中的 Redis 实例,接下来我们需要使用这些实例来创建集群。通过使用 Redis 集群命令行工具 redis-trib,编写节点配置文件的工作可以非常容易地完成:redis-trib 位于 Redis 源码的 src 文件夹中,它是一个 Ruby 程序,这个程序通过向实例发送特殊命令来完成创建新集群,检查集群,或者对集群进行重新分片(reshared)等工作。这里通过 create 命令来创建集群,指定 replicas=1,即每一个主实例有一个从实例。redis-trib 会打印出一份预想中的配置给你看,如果你觉得没问题的话,就可以输入 yes,redis-trib 就会将这份配置应用到集群当中, 让各个节点开始互相通讯, 最后可以得到如下信息

~/redis-3.0.1/src# apt-get install ruby gem
~/redis-3.0.1/src# gem sources -a http://ruby.taobao.org/
~/redis-3.0.1/src# gem install redis
~/redis-3.0.1/src# cp redis-trib.rb /usr/local/redis3/bin/
~/redis-3.0.1/src# ln -sf /usr/local/redis3/bin/redis-trib.rb /usr/bin/redis-trib.rb
~/redis-3.0.1/src# redis-trib.rb create --replicas 1  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 127.0.0.1:7006
M: 1984c27297c6ef50bbfcbd35c11b93cc40ba17e4 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
M: 481e256be4c724f5a2c64a761e52b4be61ca45b4 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
M: b5b652fa02d9999861e66c843b01fd2700c02adf 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
S: 821ec823dc0c2d4f65319e84fe74157fb1014155 127.0.0.1:7004
   replicates 1984c27297c6ef50bbfcbd35c11b93cc40ba17e4
S: b3b8541b9520d707180d56a2fb3cf3ee6895ed10 127.0.0.1:7005
   replicates 481e256be4c724f5a2c64a761e52b4be61ca45b4
S: d2b437ca8b9007dcdb63ac16210f6540860361e3 127.0.0.1:7006
   replicates b5b652fa02d9999861e66c843b01fd2700c02adf
Can I set the above configuration? (type 'yes' to accept):
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

以上信息的其中一部分可以通过向集群中的任意节点(主节点或者从节点都可以)发送 CLUSTER NODES 命令来获得。该命令还可以获得节点 ID,IP 地址和端口号,标志(flag),最后发送 PING 的时间,最后接收 PONG 的时间,连接状态,节点负责处理的槽。

redis-cli -p 7001 cluster nodes
481e256be4c724f5a2c64a761e52b4be61ca45b4 127.0.0.1:7002 master - 0 1431186119174 2 connected 5461-10922
b3b8541b9520d707180d56a2fb3cf3ee6895ed10 127.0.0.1:7005 slave 481e256be4c724f5a2c64a761e52b4be61ca45b4 0 1431186120677 5 connected
d2b437ca8b9007dcdb63ac16210f6540860361e3 127.0.0.1:7006 slave b5b652fa02d9999861e66c843b01fd2700c02adf 0 1431186119174 6 connected
b5b652fa02d9999861e66c843b01fd2700c02adf 127.0.0.1:7003 master - 0 1431186118673 3 connected 10923-16383
821ec823dc0c2d4f65319e84fe74157fb1014155 127.0.0.1:7004 slave 1984c27297c6ef50bbfcbd35c11b93cc40ba17e4 0 1431186120176 4 connected
1984c27297c6ef50bbfcbd35c11b93cc40ba17e4 127.0.0.1:7001 myself,master - 0 0 1 connected 0-5460

5. 连接 Redis 集群

通过上面的输出,我们可以看出 Redis 三个主节点的 slot 范围。一个 Redis 客户端可以向集群中的任意节点(包括从节点)发送命令请求。我们首先连接第一个节点:

redis-cli -p 7001
127.0.0.1:7001> set a 1 
(error) MOVED 15495 127.0.0.1:7003
127.0.0.1:7001> get a
(error) MOVED 15495 127.0.0.1:7003
127.0.0.1:7001> set b 1
OK

节点会对命令请求进行分析和 key 的 slot 计算,并且会查找这个命令所要处理的键所在的槽。如果要查找的哈希槽正好就由接收到命令的节点负责处理,那么节点就直接执行这个命令。

另一方面,如果所查找的槽不是由该节点处理的话,节点将查看自身内部所保存的哈希槽到节点 ID 的映射记录,并向客户端回复一个 MOVED 错误。上面的错误信息包含键 x 所属的哈希槽 15495,以及负责处理这个槽的节点的 IP 和端口号 127.0.0.1:7003。

虽然我们用 Node ID 来标识集群中的节点,但是为了让客户端的转向操作尽可能地简单,节点在 MOVED 错误中直接返回目标节点的 IP 和端口号,而不是目标节点的 ID。客户端应该记录槽 15495 由节点 127.0.0.1:7003 负责处理“这一信息,这样当再次有命令需要对槽 15495 执行时,客户端就可以加快寻找正确节点的速度。这样,当集群处于稳定状态时,所有客户端最终都会保存有一个哈希槽至节点的映射记录,使得集群非常高效:客户端可以直接向正确的节点发送命令请求,无须转向、代理或者其他任何可能发生单点故障(single point failure)的实体(entiy)。

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2016-04/130156p2.htm

6.Java 连接 Redis 集群

使用 jedis-2.7.2.jar jar 包

import java.util.HashSet;
import java.util.Set;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

public class JedisClusterTest {

 public static void main(String[] args) {

  JedisPoolConfig config = new JedisPoolConfig();
  config.setMaxTotal(20);
  config.setMaxIdle(2);

  HostAndPort hp0 = new HostAndPort(“localhost”, 7000);
  HostAndPort hp1 = new HostAndPort(“localhost”, 7001);
  HostAndPort hp2 = new HostAndPort(“localhost”, 7002);
  HostAndPort hp3 = new HostAndPort(“localhost”, 7003);
  HostAndPort hp4 = new HostAndPort(“localhost”, 7004);
  HostAndPort hp5 = new HostAndPort(“localhost”, 7005);

  Set<HostAndPort> hps = new HashSet<HostAndPort>();
  hps.add(hp0);
  hps.add(hp1);
  hps.add(hp2);
  hps.add(hp3);
  hps.add(hp4);
  hps.add(hp5);

  // 超时,最大的转发数,最大链接数,最小链接数都会影响到集群
  JedisCluster jedisCluster = new JedisCluster(hps, 5000, 10, config);

  long start = System.currentTimeMillis();
  for (int i = 0; i < 100; i++) {
   jedisCluster.set(“sn” + i, “n” + i);
  }
  long end = System.currentTimeMillis();

  System.out.println(“Simple  @ Sharding Set : ” + (end – start) / 10000);

  for (int i = 0; i < 1000; i++) {
   System.out.println(jedisCluster.get(“sn” + i));
  }

  jedisCluster.close();

 }

}

7.java 连接 Redis 集群常见错误

7.1.Too many Cluster redirections
这种情况一般情况下都是 redis 绑定 ip 问题,默认情况下 redis 绑定的 ip 是本机的 127.0.0.1 如果 redis 部署在其他机器上,而本地测试程序想要通过网络链接到 redis 集群,那么就需要注意,在 redis.conf 文件中配置 bind xxx.xxx.xxx.xxx 注意这个地方要配置成客户端链接的 ip

注意:如果 redis 绑定了指定的 ip 地址了,这时候在启动集群的时候也需要注意,需要指定 ip 地址了,本来启动集群的方式是这样的:
./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
现在就是这样的
./redis-trib.rb create –replicas 1 xxx.xxx.xxx.xxx:7000  xxx.xxx.xxx.xxx:7001 xxx.xxx.xxx.xxx:7002 xxx.xxx.xxx.xxx:7003 xxx.xxx.xxx.xxx:7004 xxx.xxx.xxx.xxx:7005./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

Redis 的详细介绍:请点这里
Redis 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-04/130156.htm 

Redis 在 3.0 版正式引入了集群这个特性。Redis 集群是一个分布式(distributed)、容错(fault-tolerant)的 Redis 内存 K / V 服务,集群可以使用的功能是普通单机 Redis 所能使用的功能的一个子集(subset),比如 Redis 集群并不支持处理多个 keys 的命令, 因为这需要在不同的节点间移动数据, 从而达不到像 Redis 那样的性能, 在高负载的情况下可能会导致不可预料的错误。

Redis 集群的几个重要特征:

(1).Redis 集群的分片特征在于将键空间分拆了 16384 个槽位,每一个节点负责其中一些槽位。

(2).Redis 提供一定程度的可用性, 可以在某个节点宕机或者不可达的情况下继续处理命令.

(3).Redis 集群中不存在中心(central)节点或者代理(proxy)节点,集群的其中一个主要设计目标是达到线性可扩展性(linear scalability)。

1. Redis 的数据分片(Sharding)

Redis 集群的键空间被分割为 16384(2^14)个槽(slot),集群的最大节点数量也是 16384 个(推荐的最大节点数量为 1000 个),同理每个主节点可以负责处理 1 到 16384 个槽位。

当 16384 个槽位都有主节点负责处理时,集群进入”稳定“上线状态,可以开始处理数据命令。当集群没有处理稳定状态时,可以通过执行重配置(reconfiguration)操作,使得每个哈希槽都只由一个节点进行处理。

重配置指的是将某个 / 某些槽从一个节点移动到另一个节点。一个主节点可以有任意多个从节点,这些从节点用于在主节点发生网络断线或者节点失效时,对主节点进行替换。

集群的使用公式 CRC16(Key)&16383 计算 key 属于哪个槽:

HASH_SLOT = CRC16(key) mod 16384

CRC16 其结果长度为 16 位。

下面关于 Redis 的文章您也可能喜欢,不妨参考下:

Ubuntu 14.04 下 Redis 安装及简单测试 http://www.linuxidc.com/Linux/2014-05/101544.htm

Redis 主从复制基本配置 http://www.linuxidc.com/Linux/2015-03/115610.htm

Redis 集群明细文档 http://www.linuxidc.com/Linux/2013-09/90118.htm

Ubuntu 12.10 下安装 Redis(图文详解)+ Jedis 连接 Redis http://www.linuxidc.com/Linux/2013-06/85816.htm

Redis 系列 - 安装部署维护篇 http://www.linuxidc.com/Linux/2012-12/75627.htm

CentOS 6.3 安装 Redis http://www.linuxidc.com/Linux/2012-12/75314.htm

Redis 安装部署学习笔记 http://www.linuxidc.com/Linux/2014-07/104306.htm

Redis 配置文件 redis.conf 详解 http://www.linuxidc.com/Linux/2013-11/92524.htm

2. Redis 集群节点

部分内容摘自附录 2。Redis 集群中的节点不仅要记录键和值的映射,还需要记录集群的状态,包括键到正确节点的映射。它还具有自动发现其他节点,识别工作不正常的节点,并在有需要时,在从节点中选举出新的主节点的功能。

为了执行以上列出的任务,集群中的每个节点都与其他节点建立起了“集群连接(cluster bus)”,该连接是一个 TCP 连接,使用二进制协议进行通讯。

节点之间使用 Gossip 协议 来进行以下工作:

a). 传播(propagate)关于集群的信息,以此来发现新的节点。

b). 向其他节点发送 PING 数据包,以此来检查目标节点是否正常运作。

c). 在特定事件发生时,发送集群信息。

除此之外,集群连接还用于在集群中发布或订阅信息。

集群节点不能前端代理命令请求,所以客户端应该在节点返回 -MOVED或者 -ASK转向(redirection)错误时,自行将命令请求转发至其他节点。

客户端可以自由地向集群中的任何一个节点发送命令请求,并可以在有需要时,根据转向错误所提供的信息,将命令转发至正确的节点,所以在理论上来说,客户端是无须保存集群状态信息的。但如果客户端可以将键和节点之间的映射信息保存起来,可以有效地减少可能出现的转向次数,籍此提升命令执行的效率。

每个节点在集群中由一个独一无二的 ID 标识,该 ID 是一个十六进制表示的 160 位随机数,在节点第一次启动时由 /dev/urandom 生成。节点会将它的 ID 保存到配置文件,只要这个配置文件不被删除,节点就会一直沿用这个 ID。一个节点可以改变它的 IP 和端口号,而不改变节点 ID。集群可以自动识别出 IP/ 端口号的变化,并将这一信息通过 Gossip 协议广播给其他节点知道。

下面是每个节点都有的关联信息,并且节点会将这些信息发送给其他节点:

a). 节点所使用的 IP 地址和 TCP 端口号。

b). 节点的标志(flags)。

c). 节点负责处理的哈希槽。

b). 节点最近一次使用集群连接发送 PING 数据包(packet)的时间。

e). 节点最近一次在回复中接收到 PONG 数据包的时间。

f). 集群将该节点标记为下线的时间。

 

g). 该节点的从节点数量。

如果该节点是从节点的话,那么它会记录主节点的节点 ID。如果这是一个主节点的话,那么主节点 ID 这一栏的值为 0000000。

在了解 Redis Cluster 的集群基本特征后,我们首先搭建出这个 Redis Cluster 集群。

3. 安装 Redis 3.0.x

当前最新版为 3.0.1

wget http://download.redis.io/releases/redis-3.0.1.tar.gz
tar xvzf redis-3.0.1.tar.gz
cd redis-3.0.1/
make -j
#apt-get install tcl
make test
### 将 redis 安装到 /usr/local/redis3 上
#cd src && make PREFIX=/usr/local/redis3 install
### 创建符号链接
 #ls /usr/local/redis3/bin/redis-*
/usr/local/redis3/bin/redis-benchmark  /usr/local/redis3/bin/redis-check-dump  /usr/local/redis3/bin/redis-sentinel
/usr/local/redis3/bin/redis-check-aof  /usr/local/redis3/bin/redis-cli         /usr/local/redis3/bin/redis-server
#for i in `cd /usr/local/redis3/bin; ls redis-*`
do
ln -s /usr/local/redis3/bin/$i /usr/local/bin/$i
done;
#mkdir -p /usr/local/redis3/conf
#ln -sf /usr/local/redis3/conf /etc/redis3
### 检查版本信息
redis-cli -v
redis-cli 3.0.1

4. Redis Cluster 配置

运行在集群模式的 Redis 实例与普通的 Redis 实例有所不同,集群模式需要通过配置启用 cluster 特性,开启集群模式后的 Redis 实例便可以使用集群特有的命令和特性了. 下面是一个最少选项的集群的配置文件 : 注意如果使用的是单机测试,最好把 cluster-config-file nodes.conf 设置为对应的 端口 nodes-xxx.conf,还有就是 pid 设置为当前 目录下 pidfile ./redis.pid

port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

文件中的 cluster-enabled 选项用于开实例的集群模式,而 cluster-conf-file 选项则设定了保存节点配置文件的路径,默认值为 nodes.conf。该节点配置文件无须人为修改,它由 Redis 集群在启动时自动创建,并在有需要时自动进行更新。

若要让集群正常运作至少需要三个主节点,我们的环境中,每个主节点附带一个从节点,所以一共六个节点。端口为 7001-7006。

在 /app/redis3,并创建六个以端口号为名字的子目录,稍后我们在将每个目录中运行一个 Redis 实例:

cd /app/redis3
mkdir 7001 7002 7003 7004 7005 7006
 cp /etc/redis3/conf/redis.conf  /app/redis3/7001/
......
cp /etc/redis3/conf/redis.conf  /app/redis3/7006/

将 redis.conf 里的端口号修改为对应的端口。下面我们打开对应的目录,启动 redis 实例即可,启动的时候要进入到对应的目录然后启动。

cd /app/redis3/7001;nohup redis-server redis.conf &
cd /app/redis3/7002;nohup redis-server redis.conf &
......

实例打印的日志显示,因为 nodes.conf 文件不存在,所以每个节点都为它自身指定了一个新的 ID ,

/app/redis3/7006# tail -f nohup.out
27040:M 09 May 22:53:50.197 * No cluster configuration found, I'm 1984c27297c6ef50bbfcbd35c11b93cc40ba17e4
/app/redis3/7006# cat nodes.conf 
d2b437ca8b9007dcdb63ac16210f6540860361e3 :0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0

现在我们已经有了六个正在运行中的 Redis 实例,接下来我们需要使用这些实例来创建集群。通过使用 Redis 集群命令行工具 redis-trib,编写节点配置文件的工作可以非常容易地完成:redis-trib 位于 Redis 源码的 src 文件夹中,它是一个 Ruby 程序,这个程序通过向实例发送特殊命令来完成创建新集群,检查集群,或者对集群进行重新分片(reshared)等工作。这里通过 create 命令来创建集群,指定 replicas=1,即每一个主实例有一个从实例。redis-trib 会打印出一份预想中的配置给你看,如果你觉得没问题的话,就可以输入 yes,redis-trib 就会将这份配置应用到集群当中, 让各个节点开始互相通讯, 最后可以得到如下信息

~/redis-3.0.1/src# apt-get install ruby gem
~/redis-3.0.1/src# gem sources -a http://ruby.taobao.org/
~/redis-3.0.1/src# gem install redis
~/redis-3.0.1/src# cp redis-trib.rb /usr/local/redis3/bin/
~/redis-3.0.1/src# ln -sf /usr/local/redis3/bin/redis-trib.rb /usr/bin/redis-trib.rb
~/redis-3.0.1/src# redis-trib.rb create --replicas 1  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 127.0.0.1:7006
M: 1984c27297c6ef50bbfcbd35c11b93cc40ba17e4 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
M: 481e256be4c724f5a2c64a761e52b4be61ca45b4 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
M: b5b652fa02d9999861e66c843b01fd2700c02adf 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
S: 821ec823dc0c2d4f65319e84fe74157fb1014155 127.0.0.1:7004
   replicates 1984c27297c6ef50bbfcbd35c11b93cc40ba17e4
S: b3b8541b9520d707180d56a2fb3cf3ee6895ed10 127.0.0.1:7005
   replicates 481e256be4c724f5a2c64a761e52b4be61ca45b4
S: d2b437ca8b9007dcdb63ac16210f6540860361e3 127.0.0.1:7006
   replicates b5b652fa02d9999861e66c843b01fd2700c02adf
Can I set the above configuration? (type 'yes' to accept):
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

以上信息的其中一部分可以通过向集群中的任意节点(主节点或者从节点都可以)发送 CLUSTER NODES 命令来获得。该命令还可以获得节点 ID,IP 地址和端口号,标志(flag),最后发送 PING 的时间,最后接收 PONG 的时间,连接状态,节点负责处理的槽。

redis-cli -p 7001 cluster nodes
481e256be4c724f5a2c64a761e52b4be61ca45b4 127.0.0.1:7002 master - 0 1431186119174 2 connected 5461-10922
b3b8541b9520d707180d56a2fb3cf3ee6895ed10 127.0.0.1:7005 slave 481e256be4c724f5a2c64a761e52b4be61ca45b4 0 1431186120677 5 connected
d2b437ca8b9007dcdb63ac16210f6540860361e3 127.0.0.1:7006 slave b5b652fa02d9999861e66c843b01fd2700c02adf 0 1431186119174 6 connected
b5b652fa02d9999861e66c843b01fd2700c02adf 127.0.0.1:7003 master - 0 1431186118673 3 connected 10923-16383
821ec823dc0c2d4f65319e84fe74157fb1014155 127.0.0.1:7004 slave 1984c27297c6ef50bbfcbd35c11b93cc40ba17e4 0 1431186120176 4 connected
1984c27297c6ef50bbfcbd35c11b93cc40ba17e4 127.0.0.1:7001 myself,master - 0 0 1 connected 0-5460

5. 连接 Redis 集群

通过上面的输出,我们可以看出 Redis 三个主节点的 slot 范围。一个 Redis 客户端可以向集群中的任意节点(包括从节点)发送命令请求。我们首先连接第一个节点:

redis-cli -p 7001
127.0.0.1:7001> set a 1 
(error) MOVED 15495 127.0.0.1:7003
127.0.0.1:7001> get a
(error) MOVED 15495 127.0.0.1:7003
127.0.0.1:7001> set b 1
OK

节点会对命令请求进行分析和 key 的 slot 计算,并且会查找这个命令所要处理的键所在的槽。如果要查找的哈希槽正好就由接收到命令的节点负责处理,那么节点就直接执行这个命令。

另一方面,如果所查找的槽不是由该节点处理的话,节点将查看自身内部所保存的哈希槽到节点 ID 的映射记录,并向客户端回复一个 MOVED 错误。上面的错误信息包含键 x 所属的哈希槽 15495,以及负责处理这个槽的节点的 IP 和端口号 127.0.0.1:7003。

虽然我们用 Node ID 来标识集群中的节点,但是为了让客户端的转向操作尽可能地简单,节点在 MOVED 错误中直接返回目标节点的 IP 和端口号,而不是目标节点的 ID。客户端应该记录槽 15495 由节点 127.0.0.1:7003 负责处理“这一信息,这样当再次有命令需要对槽 15495 执行时,客户端就可以加快寻找正确节点的速度。这样,当集群处于稳定状态时,所有客户端最终都会保存有一个哈希槽至节点的映射记录,使得集群非常高效:客户端可以直接向正确的节点发送命令请求,无须转向、代理或者其他任何可能发生单点故障(single point failure)的实体(entiy)。

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2016-04/130156p2.htm

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-22发表,共计16327字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中