转载来源:https://www.jianshu.com/p/c869feb5581d

Redis集群的原理和搭建

前言

Redis 是我们目前大规模使用的缓存中间件,由于它强大高效而又便捷的功能,得到了广泛的使用。单节点的Redis已经就达到了很高的性能,为了提高可用性我们可以使用Redis集群。本文参考了Rdis的官方文档和使用Redis官方提供的Redis Cluster工具搭建Rdis集群。

注意 :Redis的版本要在3.0以上,截止今天,Redis的版本是3.2.9,本教程也使用3.2.9作为教程

Redis集群的概念

介绍

Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。

Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的错误。

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

Redis 集群提供了以下两个好处:

  • 将数据自动切分(split)到多个节点的能力。
  • 当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。

数据分片

Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。

集群中的每个节点负责处理一部分哈希槽。 举个例子, 一个集群可以有三个哈希槽, 其中:

  • 节点 A 负责处理 0 号至 5500 号哈希槽。
  • 节点 B 负责处理 5501 号至 11000 号哈希槽。
  • 节点 C 负责处理 11001 号至 16384 号哈希槽。

这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说:
我现在想设置一个key,叫my_name:

set my_name zhangguoji

按照Redis Cluster的哈希槽算法,CRC16('my_name')%16384 = 2412 那么这个key就被分配到了节点A上
同样的,当我连接(A,B,C)的任意一个节点想获取my_name这个key,都会转到节点A上
再比如
如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。
增加一个D节点的结果可能如下:

  • 节点A覆盖1365-5460
  • 节点B覆盖6827-10922
  • 节点C覆盖12288-16383
  • 节点D覆盖0-1364,5461-6826,10923-1228

与此类似, 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。
因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。
所以,Redis Cluster的模型大概是这样的形状

 
082248582749859.jpg

主从复制模型

为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下, 仍然可以正常运作, Redis 集群对节点使用了主从复制功能: 集群中的每个节点都有 1 个至 N 个复制品(replica), 其中一个复制品为主节点(master), 而其余的 N-1 个复制品为从节点(slave)。

在之前列举的节点 A 、B 、C 的例子中, 如果节点 B 下线了, 那么集群将无法正常运行, 因为集群找不到节点来处理 5501 号至 11000号的哈希槽。

另一方面, 假如在创建集群的时候(或者至少在节点 B 下线之前), 我们为主节点 B 添加了从节点 B1 , 那么当主节点 B 下线的时候, 集群就会将 B1 设置为新的主节点, 并让它代替下线的主节点 B , 继续处理 5501 号至 11000 号的哈希槽, 这样集群就不会因为主节点 B 的下线而无法正常运作了。

不过如果节点 B 和 B1 都下线的话, Redis 集群还是会停止运作。

Redis一致性保证

Redis 并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操作:
第一个原因是因为集群是用了异步复制. 写操作过程:

  1. 客户端向主节点B写入一条命令.
  2. 主节点B向客户端回复命令状态.
  3. 主节点将写操作复制给他得从节点 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 集群的一个重要的配置选项

搭建Redis集群

要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下(为了简单演示都在同一台机器上面)

  1. 127.0.0.1:7000
  2. 127.0.0.1:7001
  3. 127.0.0.1:7002
  4. 127.0.0.1:7003
  5. 127.0.0.1:7004
  6. 127.0.0.1:7005

安装和启动Redis

下载安装包

  1. wget http://download.redis.io/releases/redis-3.2.9.tar.gz

解压安装

  1. tar zxvf redis-3.2.9.tar.gz
  2. cd redis-3.2.9
  3. make && make PREFIX=/usr/local/redis install

这里如果失败的自行yum安装gcc和tcl

  1. yum install gcc
  2. yum install tcl

创建目录

  1. cd /usr/local/redis
  2. mkdir cluster
  3. cd cluster
  4. mkdir 7000 7001 7002 7003 7004 7005

复制和修改配置文件

将redis目录下的配置文件复制到对应端口文件夹下,6个文件夹都要复制一份

  1. cp redis-3.2.9/redis.conf /usr/local/redis/cluster/7000

修改配置文件redis.conf,将下面的选项修改

  1. # 端口号
  2. port 7000
  3. # 后台启动
  4. daemonize yes
  5. # 开启集群
  6. cluster-enabled yes
  7. #集群节点配置文件
  8. cluster-config-file nodes-7000.conf
  9. # 集群连接超时时间
  10. cluster-node-timeout 5000
  11. # 进程pid的文件位置
  12. pidfile /var/run/redis-7000.pid
  13. # 开启aof
  14. appendonly yes
  15. # aof文件路径
  16. appendfilename "appendonly-7005.aof"
  17. # rdb文件路径
  18. dbfilename dump-7000.rdb

6个配置文件安装对应的端口分别修改配置文件

创建启动脚本

/usr/local/redis目录下创建一个start.sh

  1. #!/bin/bash
  2. bin/redis-server cluster/7000/redis.conf
  3. bin/redis-server cluster/7001/redis.conf
  4. bin/redis-server cluster/7002/redis.conf
  5. bin/redis-server cluster/7003/redis.conf
  6. bin/redis-server cluster/7004/redis.conf
  7. bin/redis-server cluster/7005/redis.conf

这个时候我们查看一下进程看启动情况

  1. ps -ef | grep redis

进程状态如下:

  1. root 1731 1 1 18:21 ? 00:00:49 bin/redis-server *:7000 [cluster]
  2. root 1733 1 0 18:21 ? 00:00:29 bin/redis-server *:7001 [cluster]
  3. root 1735 1 0 18:21 ? 00:00:08 bin/redis-server *:7002 [cluster]
  4. root 1743 1 0 18:21 ? 00:00:26 bin/redis-server *:7003 [cluster]
  5. root 1745 1 0 18:21 ? 00:00:13 bin/redis-server *:7004 [cluster]
  6. root 1749 1 0 18:21 ? 00:00:08 bin/redis-server *:7005 [cluster]

有6个redis进程在开启,说明我们的redis就启动成功了

开启集群

这里我们只是开启了6个redis进程而已,它们都还只是独立的状态,还么有组成集群
这里我们使用官方提供的工具redis-trib,不过这个工具是用ruby写的,要先安装ruby的环境

  1. yum install ruby rubygems -y

执行,报错

  1. [root@centos]# 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
  2. /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- redis (LoadError)
  3. from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
  4. from /usr/local/bin/redis-trib.rb:25
  5. [root@centos]#

原来是ruby和redis的连接没安装好
安装gem-redis

  1. gem install redis

安装到这里的时候突然卡住很久不动,网上搜了下,这里需要翻墙或者换镜像

  1. gem source -a https://gems.ruby-china.org

这里可以将镜像换成ruby-china的镜像,不过我好像更换失败,最终还是翻墙下载了

  1. [root@centos]# gem install redis
  2. Successfully installed redis-3.2.1
  3. 1 gem installed
  4. Installing ri documentation for redis-3.2.1...
  5. Installing RDoc documentation for redis-3.2.1...

等下载好后我们就可以使用了

  1. [root@centos]# gem install redis
  2. Successfully installed redis-3.2.1
  3. 1 gem installed
  4. Installing ri documentation for redis-3.2.1...
  5. Installing RDoc documentation for redis-3.2.1...

将redis-3.2.9的src目录下的trib复制到相应文件夹

  1. cp redis-3.2.9/src/redis-trib.rb /usr/local/redis/bin/redis-trib

创建集群:

  1. redis-trib 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 表示我们希望为集群中的每个主节点创建一个从节点。
    之后跟着的其他参数则是实例的地址列表, 我们希望程序使用这些地址所指示的实例来创建新集群。
    简单来说,以上的命令的意思就是让redis-trib程序帮我们创建三个主节点和三个从节点的集群
    接着, redis-trib 会打印出一份预想中的配置给你看, 如果你觉得没问题的话, 就可以输入 yes , redis-trib 就会将这份配置应用到集群当中:
  1. >>> Creating cluster
  2. >>> Performing hash slots allocation on 6 nodes...
  3. Using 3 masters:
  4. 127.0.0.1:7000
  5. 127.0.0.1:7001
  6. 127.0.0.1:7002
  7. Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
  8. Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
  9. Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
  10. M: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
  11. slots:0-5460 (5461 slots) master
  12. M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
  13. slots:5461-10922 (5462 slots) master
  14. M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
  15. slots:10923-16383 (5461 slots) master
  16. S: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
  17. replicates bdcddddd3d78a866b44b68c7ae0e5ccf875c446a
  18. S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
  19. replicates b85519795fa42aa33d4e88d25104cbae895933a6
  20. S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
  21. replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
  22. Can I set the above configuration? (type 'yes' to accept):

按下yes,集群就会将配置应用到各个节点,并连接起(join)各个节点,也即是,让各个节点开始通讯

  1. >>> Nodes configuration updated
  2. >>> Assign a different config epoch to each node
  3. >>> Sending CLUSTER MEET messages to join the cluster
  4. Waiting for the cluster to join...
  5. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  6. M: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
  7. slots:0-5460 (5461 slots) master
  8. 1 additional replica(s)
  9. S: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
  10. slots: (0 slots) slave
  11. replicates bdcddddd3d78a866b44b68c7ae0e5ccf875c446a
  12. S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
  13. slots: (0 slots) slave
  14. replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
  15. M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
  16. slots:5461-10922 (5462 slots) master
  17. 1 additional replica(s)
  18. S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
  19. slots: (0 slots) slave
  20. replicates b85519795fa42aa33d4e88d25104cbae895933a6
  21. M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
  22. slots:10923-16383 (5461 slots) master
  23. 1 additional replica(s)
  24. [OK] All nodes agree about slots configuration.
  25. >>> Check for open slots...
  26. >>> Check slots coverage...
  27. [OK] All 16384 slots covered.

Redis集群的使用

连接集群

这里我们使用reids-cli连接集群,使用时加上-c参数,就可以连接到集群
连接7000端口的节点

  1. [root@centos1 redis]# ./redis-cli -c -p 7000
  2. 127.0.0.1:7000> set name zgj
  3. -> Redirected to slot [5798] located at 127.0.0.1:7001
  4. OK
  5. 127.0.0.1:7001> get name
  6. "zgj"

前面的理论知识我们知道了,分配key的时候,它会使用CRC16算法,这里将keyname分配到了7001节点上

  1. Redirected to slot [5798] located at 127.0.0.1:7001

redis cluster 采用的方式很直接,它直接跳转到7001 节点了,而不是还在自身的7000节点。

好,现在我们连接7003这个从节点进入

  1. [root@centos1 redis]# ./redis-cli -c -p 7003
  2. 127.0.0.1:7003> get name
  3. -> Redirected to slot [5798] located at 127.0.0.1:7001
  4. "zgj"

这里获取name的值,也同样跳转到了7001上
我们再测试一下其他数据

  1. 127.0.0.1:7001> set age 20
  2. -> Redirected to slot [741] located at 127.0.0.1:7000
  3. OK
  4. 127.0.0.1:7000> set message helloworld
  5. -> Redirected to slot [11537] located at 127.0.0.1:7002
  6. OK
  7. 127.0.0.1:7002> set height 175
  8. -> Redirected to slot [8223] located at 127.0.0.1:7001
  9. OK

我们发现数据会在7000-7002这3个节点之间来回跳转

测试集群中的节点挂掉

上面我们建立了一个集群,3个主节点和3个从节点,7000-7002负责存取数据,7003-7005负责把7000-7005的数据同步到自己的节点上来。
我们现在来模拟一下一台matser服务器宕机的情况

  1. [root@centos1 redis]# ps -ef | grep redis
  2. root 1731 1 0 18:21 ? 00:01:02 bin/redis-server *:7000 [cluster]
  3. root 1733 1 0 18:21 ? 00:00:43 bin/redis-server *:7001 [cluster]
  4. root 1735 1 0 18:21 ? 00:00:22 bin/redis-server *:7002 [cluster]
  5. root 1743 1 0 18:21 ? 00:00:40 bin/redis-server *:7003 [cluster]
  6. root 1745 1 0 18:21 ? 00:00:27 bin/redis-server *:7004 [cluster]
  7. root 1749 1 0 18:21 ? 00:00:22 bin/redis-server *:7005 [cluster]
  8. root 23988 1 0 18:30 ? 00:00:42 ./redis-server *:6379
  9. root 24491 1635 0 21:55 pts/1 00:00:00 grep redis
  10. [root@centos1 redis]# kill 1731
  11. [root@centos1 redis]# bin/redis-trib check 127.0.0.1:7001
  12. >>> Performing Cluster Check (using node 127.0.0.1:7001)
  13. M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
  14. slots:5461-10922 (5462 slots) master
  15. 1 additional replica(s)
  16. M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
  17. slots:10923-16383 (5461 slots) master
  18. 1 additional replica(s)
  19. S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
  20. slots: (0 slots) slave
  21. replicates b85519795fa42aa33d4e88d25104cbae895933a6
  22. S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
  23. slots: (0 slots) slave
  24. replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
  25. M: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
  26. slots:0-5460 (5461 slots) master
  27. 0 additional replica(s)
  28. [OK] All nodes agree about slots configuration.
  29. >>> Check for open slots...
  30. >>> Check slots coverage...
  31. [OK] All 16384 slots covered.

这里看得出来,现在已经有了3个节点了,7003被选取成了替代7000成为主节点了。
我们再来模拟 7000节点重新启动了的情况,那么它还会自动加入到集群中吗?那么,7000这个节点上充当什么角色呢? 我们试一下:

  1. [root@centos1 redis]# bin/redis-server cluster/7000/redis.conf
  2. [root@centos1 redis]# bin/redis-trib check 127.0.0.1:7000
  3. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  4. S: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
  5. slots: (0 slots) slave
  6. replicates d403713ab9db48aeac5b5393b69e1201026ef479
  7. S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
  8. slots: (0 slots) slave
  9. replicates b85519795fa42aa33d4e88d25104cbae895933a6
  10. S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
  11. slots: (0 slots) slave
  12. replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
  13. M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
  14. slots:10923-16383 (5461 slots) master
  15. 1 additional replica(s)
  16. M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
  17. slots:5461-10922 (5462 slots) master
  18. 1 additional replica(s)
  19. M: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
  20. slots:0-5460 (5461 slots) master
  21. 1 additional replica(s)
  22. [OK] All nodes agree about slots configuration.
  23. >>> Check for open slots...
  24. >>> Check slots coverage...
  25. [OK] All 16384 slots covered.

这里我们可以看到7000节点变成了7003节点的从节点
我们试着将7000和7003两个节点都关掉

  1. [root@centos1 redis]# ps -ef | grep redis
  2. root 1733 1 0 18:21 ? 00:00:45 bin/redis-server *:7001 [cluster]
  3. root 1735 1 0 18:21 ? 00:00:24 bin/redis-server *:7002 [cluster]
  4. root 1743 1 0 18:21 ? 00:00:42 bin/redis-server *:7003 [cluster]
  5. root 1745 1 0 18:21 ? 00:00:29 bin/redis-server *:7004 [cluster]
  6. root 1749 1 0 18:21 ? 00:00:24 bin/redis-server *:7005 [cluster]
  7. root 23988 1 0 18:30 ? 00:00:43 ./redis-server *:6379
  8. root 24527 1 0 22:04 ? 00:00:00 bin/redis-server *:7000 [cluster]
  9. root 24541 1635 0 22:07 pts/1 00:00:00 grep redis
  10. [root@centos1 redis] kill 1743
  11. [root@centos1 redis] kill 24527
  12. [root@centos1 redis]# bin/redis-trib check 127.0.0.1:7001
  13. >>> Performing Cluster Check (using node 127.0.0.1:7001)
  14. M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
  15. slots:5461-10922 (5462 slots) master
  16. 1 additional replica(s)
  17. M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
  18. slots:10923-16383 (5461 slots) master
  19. 1 additional replica(s)
  20. S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
  21. slots: (0 slots) slave
  22. replicates b85519795fa42aa33d4e88d25104cbae895933a6
  23. S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
  24. slots: (0 slots) slave
  25. replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
  26. [OK] All nodes agree about slots configuration.
  27. >>> Check for open slots...
  28. >>> Check slots coverage...
  29. [ERR] Not all 16384 slots are covered by nodes.

这里我们的集群就不能工作了,因为两个节点主节点和从节点都挂掉了,原来7001分配的slot现在无节点接管,需要人工介入重新分配slots。

集群中加入新的主节点

这里在cluster目录下再新建一个7006并修改对应的配置文件,然后启动这个这个redis进程
然后再使用redis-trib的add node指令加入节点

  1. bin/redis-trib add-node 127.0.0.1:7006 127.0.0.1:7000

这里前面的节点表示要加入的节点,第二个节点表示要加入的集群中的任意一个节点,用来标识这个集群

  1. [root@centos1 redis]# bin/redis-trib add-node 127.0.0.1:7006 127.0.0.1:7000
  2. >>> Adding node 127.0.0.1:7006 to cluster 127.0.0.1:7000
  3. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  4. M: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
  5. slots:0-5460 (5461 slots) master
  6. 1 additional replica(s)
  7. S: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
  8. slots: (0 slots) slave
  9. replicates bdcddddd3d78a866b44b68c7ae0e5ccf875c446a
  10. S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
  11. slots: (0 slots) slave
  12. replicates b85519795fa42aa33d4e88d25104cbae895933a6
  13. M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
  14. slots:5461-10922 (5462 slots) master
  15. 1 additional replica(s)
  16. S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
  17. slots: (0 slots) slave
  18. replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
  19. M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
  20. slots:10923-16383 (5461 slots) master
  21. 1 additional replica(s)
  22. [OK] All nodes agree about slots configuration.
  23. >>> Check for open slots...
  24. >>> Check slots coverage...
  25. [OK] All 16384 slots covered.
  26. >>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.
  27. [OK] New node added correctly.
  28. [root@centos1 redis]# bin/redis-trib check 127.0.0.1:7006
  29. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  30. M: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
  31. slots:0-5460 (5461 slots) master
  32. 1 additional replica(s)
  33. S: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
  34. slots: (0 slots) slave
  35. replicates bdcddddd3d78a866b44b68c7ae0e5ccf875c446a
  36. S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
  37. slots: (0 slots) slave
  38. replicates b85519795fa42aa33d4e88d25104cbae895933a6
  39. M: e55599320dabfb31bd22a01407e66121f075e7d3 127.0.0.1:7006
  40. slots: (0 slots) master
  41. 0 additional replica(s)
  42. M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
  43. slots:5461-10922 (5462 slots) master
  44. 1 additional replica(s)
  45. S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
  46. slots: (0 slots) slave
  47. replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
  48. M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
  49. slots:10923-16383 (5461 slots) master
  50. 1 additional replica(s)
  51. [OK] All nodes agree about slots configuration.
  52. >>> Check for open slots...
  53. >>> Check slots coverage...
  54. [OK] All 16384 slots covered.

这里我们可以看到7006节点已经变成了一个主节点,然鹅,等等,好像发现了有什么地方不对

  1. M: e55599320dabfb31bd22a01407e66121f075e7d3 127.0.0.1:7006
  2. slots: (0 slots) master

里面0 slots,也就是说节点6没有分配哈希槽,即不能进行数据的存取,拿我加上去干嘛。。
原来redis cluster 不是在新加节点的时候帮我们做好了迁移工作,需要我们手动对集群进行重新分片迁移,也是这个命令:

  1. /bin/redis-trib reshard 127.0.0.1:7000

这个命令是用来迁移slot节点的,后面的127.0.0.1:7000是表示哪个集群的,7000-7006都是可以的

  1. [root@centos1]# redis-trib.rb reshard 127.0.0.1:7000
  2. Connecting to node 127.0.0.1:7006: OK
  3. Connecting to node 127.0.0.1:7001: OK
  4. Connecting to node 127.0.0.1:7004: OK
  5. Connecting to node 127.0.0.1:7000: OK
  6. Connecting to node 127.0.0.1:7002: OK
  7. Connecting to node 127.0.0.1:7005: OK
  8. Connecting to node 127.0.0.1:7003: OK
  9. >>> Performing Cluster Check (using node 127.0.0.1:7006)
  10. M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
  11. slots: (0 slots) master
  12. 0 additional replica(s)
  13. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  14. slots:5461-10922 (5462 slots) master
  15. 1 additional replica(s)
  16. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  17. slots: (0 slots) slave
  18. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  19. S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  20. slots: (0 slots) slave
  21. replicates d2237fdcfbba672de766b913d1186cebcb6e1761
  22. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  23. slots:10923-16383 (5461 slots) master
  24. 1 additional replica(s)
  25. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  26. slots: (0 slots) slave
  27. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  28. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  29. slots:0-5460 (5461 slots) master
  30. 1 additional replica(s)
  31. [OK] All nodes agree about slots configuration.
  32. >>> Check for open slots...
  33. >>> Check slots coverage...
  34. [OK] All 16384 slots covered.
  35. How many slots do you want to move (from 1 to 16384)?

它提示我们需要迁移多少slot到7006上,我们可以算一下:16384/4 = 4096,也就是说,为了平衡分配起见,我们需要移动4096个槽点到7006上。

好,那输入4096:
它又提示我们,接受的node ID是多少,7006的id 我们通过上面就可以看到是efc3131fbdc6cf929720e0e0f7136cae85657481:

  1. What is the receiving node ID? efc3131fbdc6cf929720e0e0f7136cae85657481
  2. Please enter all the source node IDs.
  3. Type 'all' to use all the nodes as source nodes for the hash slots.
  4. Type 'done' once you entered all the source nodes IDs.
  5. Source node #1:

接着, redis-trib 会向你询问重新分片的源节点(source node), 也即是, 要从哪个节点中取出 4096 个哈希槽, 并将这些槽移动到7006节点上面。

如果我们不打算从特定的节点上取出指定数量的哈希槽, 那么可以向 redis-trib 输入 all , 这样的话, 集群中的所有主节点都会成为源节点, redis-trib 将从各个源节点中各取出一部分哈希槽, 凑够 4096 个, 然后移动到7006节点上:

  1. Source node #1:all

接下来就开始迁移了,并且会询问你是否确认:

  1. Moving slot 1359 from d2237fdcfbba672de766b913d1186cebcb6e1761
  2. Moving slot 1360 from d2237fdcfbba672de766b913d1186cebcb6e1761
  3. Moving slot 1361 from d2237fdcfbba672de766b913d1186cebcb6e1761
  4. Moving slot 1362 from d2237fdcfbba672de766b913d1186cebcb6e1761
  5. Moving slot 1363 from d2237fdcfbba672de766b913d1186cebcb6e1761
  6. Moving slot 1364 from d2237fdcfbba672de766b913d1186cebcb6e1761
  7. Do you want to proceed with the proposed reshard plan (yes/no)?

输入yes并回车后,redis-trib就会正式执行重新分片操作,将制定的哈希槽从源节点一个个移动到7006节点上
迁移结束之后,我们来检查一下

  1. M: bdcddddd3d78a866b44b68c7ae0e5ccf875c446a 127.0.0.1:7000
  2. slots:1365-5460 (4096 slots) master
  3. 1 additional replica(s)
  4. S: d403713ab9db48aeac5b5393b69e1201026ef479 127.0.0.1:7003
  5. slots: (0 slots) slave
  6. replicates bdcddddd3d78a866b44b68c7ae0e5ccf875c446a
  7. S: b7ec92919e5bcffa76c8eee338f8ca5155293c64 127.0.0.1:7004
  8. slots: (0 slots) slave
  9. replicates b85519795fa42aa33d4e88d25104cbae895933a6
  10. M: e55599320dabfb31bd22a01407e66121f075e7d3 127.0.0.1:7006
  11. slots:0-1364,5461-6826,10923-12287 (4096 slots) master
  12. 0 additional replica(s)
  13. M: b85519795fa42aa33d4e88d25104cbae895933a6 127.0.0.1:7001
  14. slots:6827-10922 (4096 slots) master
  15. 1 additional replica(s)
  16. S: 8a0d2a3f271b349744a971e1b0a545405de2742e 127.0.0.1:7005
  17. slots: (0 slots) slave
  18. replicates b681e1a151890cbf957d1ff08352ee48f6ae39e6
  19. M: b681e1a151890cbf957d1ff08352ee48f6ae39e6 127.0.0.1:7002
  20. slots:12288-16383 (4096 slots) master
  21. 1 additional replica(s)
  22. [OK] All nodes agree about slots configuration.
  23. >>> Check for open slots...
  24. >>> Check slots coverage...
  25. [OK] All 16384 slots covered.

我们可以看到
slots:0-1364,5461-6826,10923-12287 (4096 slots)
这些原来在其他节点上的哈希槽都迁移到了7006上

增加一个从节点

新建一个 7007从节点,作为7006的从节点

我们再新建一个节点7007,步骤类似,就先省略了。建好后,启动起来,我们看如何把它加入到集群中的从节点中:

  1. [root@centos1]# redis-trib.rb add-node --slave 127.0.0.1:7007 127.0.0.1:7000

add-node的时候加上--slave表示是加入到从节点中,但是这样加,是随机的。这里的命令行完全像我们在添加一个新主服务器时使用的一样,所以我们没有指定要给哪个主服 务器添加副本。这种情况下,redis-trib会将7007作为一个具有较少副本的随机的主服务器的副本。

那么,你猜,它会作为谁的从节点,应该是7006,因为7006还没有从节点。我们运行下。

  1. [root@web3 7007]# redis-trib.rb add-node --slave 127.0.0.1:7007 127.0.0.1:7000
  2. ...
  3. ...
  4. [OK] All 16384 slots covered.
  5. Automatically selected master 127.0.0.1:7006
  6. Connecting to node 127.0.0.1:7007: OK
  7. >>> Send CLUSTER MEET to node 127.0.0.1:7007 to make it join the cluster.
  8. Waiting for the cluster to join.
  9. >>> Configure node as replica of 127.0.0.1:7006.
  10. [OK] New node added correctly.

上面提示说,自动选择了7006作为master节点。并且成功了。我们检查下:

  1. [root@centos1]# redis-trib.rb check 127.0.0.1:7000
  2. Connecting to node 127.0.0.1:7000: OK
  3. Connecting to node 127.0.0.1:7006: OK
  4. Connecting to node 127.0.0.1:7004: OK
  5. Connecting to node 127.0.0.1:7005: OK
  6. Connecting to node 127.0.0.1:7003: OK
  7. Connecting to node 127.0.0.1:7001: OK
  8. Connecting to node 127.0.0.1:7007: OK
  9. Connecting to node 127.0.0.1:7002: OK
  10. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  11. S: 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000
  12. slots: (0 slots) slave
  13. replicates d2237fdcfbba672de766b913d1186cebcb6e1761
  14. M: efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006
  15. slots:0-1364,5461-6826,10923-12287 (4096 slots) master
  16. 1 additional replica(s)
  17. S: 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004
  18. slots: (0 slots) slave
  19. replicates cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c
  20. S: 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005
  21. slots: (0 slots) slave
  22. replicates dfa0754c7854a874a6ebd2613b86140ad97701fc
  23. M: d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003
  24. slots:1365-5460 (4096 slots) master
  25. 1 additional replica(s)
  26. M: cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001
  27. slots:6827-10922 (4096 slots) master
  28. 1 additional replica(s)
  29. S: 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007
  30. slots: (0 slots) slave
  31. replicates efc3131fbdc6cf929720e0e0f7136cae85657481
  32. M: dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002
  33. slots:12288-16383 (4096 slots) master
  34. 1 additional replica(s)
  35. [OK] All nodes agree about slots configuration.
  36. >>> Check for open slots...
  37. >>> Check slots coverage...
  38. [OK] All 16384 slots covered.

果然,7007加入到了7006的从节点当中。

你说,我如果想指定一个主节点行不行?当然可以。我们再建一个7008节点。

  1. bin/redis-trib.rb add-node --slave --master-id efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7008 127.0.0.1:7000

--master-id 表示指定的主节点node id。这里指定的是 7006 这个主节点。

  1. Waiting for the cluster to join.
  2. >>> Configure node as replica of 127.0.0.1:7006.
  3. [OK] New node added correctly.

提示我们已经作为7006的从节点了,也就是加入到7006的从节点来了,照这么说,7006就有2个从节点了,我们看一下:

  1. bin/redis-cli -c -p 7008 cluster nodes |grep efc3131fbdc6cf929720e0e0f7136cae85657481
  2. 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007 slave efc3131fbdc6cf929720e0e0f7136cae85657481 0 1445089507786 8 connected
  3. efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006 master - 0 1445089508289 8 connected 0-1364 5461-6826 10923-12287
  4. 44321e7d619410dc4e0a8745366610a0d06d2395 127.0.0.1:7008 myself,slave efc3131fbdc6cf929720e0e0f7136cae85657481 0 0 0 connected

我们过滤了下看结果,果真,7007和7008是7006的从节点了。

刚好,我们再做一个实验,我把7006的进程杀掉,看7007和7008谁会变成主节点:

  1. [root@centos1]# ps -ef|grep redis
  2. root 11384 1 0 09:56 ? 00:00:16 redis-server *:7001 [cluster]
  3. root 11388 1 0 09:56 ? 00:00:16 redis-server *:7002 [cluster]
  4. root 11392 1 0 09:56 ? 00:00:16 redis-server *:7003 [cluster]
  5. root 11396 1 0 09:56 ? 00:00:15 redis-server *:7004 [cluster]
  6. root 11400 1 0 09:56 ? 00:00:15 redis-server *:7005 [cluster]
  7. root 12100 1 0 11:01 ? 00:00:11 redis-server *:7000 [cluster]
  8. root 12132 1 0 11:28 ? 00:00:11 redis-server *:7006 [cluster]
  9. root 12202 1 0 13:14 ? 00:00:02 redis-server *:7007 [cluster]
  10. root 12219 1 0 13:39 ? 00:00:00 redis-server *:7008 [cluster]
  11. root 12239 8259 0 13:49 pts/0 00:00:00 grep redis
  12. [root@centos1]# kill 12132
  13. [root@centos1]# redis-cli -c -p 7008
  14. 127.0.0.1:7008> get ss5rtr
  15. -> Redirected to slot [1188] located at 127.0.0.1:7007
  16. "66"
  17. 127.0.0.1:7007> cluster nodes
  18. efc3131fbdc6cf929720e0e0f7136cae85657481 127.0.0.1:7006 master,fail - 1445089780668 1445089779963 8 disconnected
  19. d2237fdcfbba672de766b913d1186cebcb6e1761 127.0.0.1:7003 master - 0 1445089812195 7 connected 1365-5460
  20. 30858dbf483b61b9838d5c1f853a60beaa4e7afd 127.0.0.1:7005 slave dfa0754c7854a874a6ebd2613b86140ad97701fc 0 1445089813710 3 connected
  21. 86d05e7c2b197dc182b5e71069e791d033cf899e 127.0.0.1:7007 myself,master - 0 0 10 connected 0-1364 5461-6826 10923-12287
  22. cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 127.0.0.1:7001 master - 0 1445089814214 2 connected 6827-10922
  23. 4b4aef8b48c427a3c903518339d53b6447c58b93 127.0.0.1:7004 slave cb5c04b6160c3b7e18cad5d49d8e2987b27e0d6c 0 1445089812701 2 connected
  24. 44321e7d619410dc4e0a8745366610a0d06d2395 127.0.0.1:7008 slave 86d05e7c2b197dc182b5e71069e791d033cf899e 0 1445089814214 10 connected
  25. 3707debcbe7be66d4a1968eaf3a5ffaf4308efa4 127.0.0.1:7000 slave d2237fdcfbba672de766b913d1186cebcb6e1761 0 1445089813204 7 connected
  26. dfa0754c7854a874a6ebd2613b86140ad97701fc 127.0.0.1:7002 master - 0 1445089813204 3 connected 12288-16383
  27. 127.0.0.1:7007>

这里7007获得了成为主节点的机会,7008就变成了7007的从节点。

那么这个时候,重启7006节点,那么他就会变成了一个7007的从节点了。

移除一个节点

上面是增加一个节点,接下来就是移除一个节点了,移除节点的命令是

  1. bin/redis-trib del-node 127.0.0.1:7000 `<node-id>`

没我们尝试下输入以下命令

  1. [root@centos]# bin/redis-trib.rb del-node 127.0.0.1:7000 86d05e7c2b197dc182b5e71069e791d033cf899e
  2. >>> Removing node 86d05e7c2b197dc182b5e71069e791d033cf899e from cluster 127.0.0.1:7000
  3. Connecting to node 127.0.0.1:7000: OK
  4. Connecting to node 127.0.0.1:7006: OK
  5. Connecting to node 127.0.0.1:7004: OK
  6. Connecting to node 127.0.0.1:7001: OK
  7. Connecting to node 127.0.0.1:7003: OK
  8. Connecting to node 127.0.0.1:7007: OK
  9. Connecting to node 127.0.0.1:7008: OK
  10. Connecting to node 127.0.0.1:7005: OK
  11. Connecting to node 127.0.0.1:7002: OK
  12. [ERR] Node 127.0.0.1:7007 is not empty! Reshard data away and try again.

这里报错了,提示我们7007节点里面有数据,让我们把7007节点里的数据移除出去,也就是说需要重新分片,这个和上面增加节点的方式一样,我们再来一遍

  1. bin/redis-trib.rb reshard 127.0.0.1:7000

省去中间内容,原来7007节点上已经有了4096个哈希槽,这里我们也移动4096个哈希槽
然后将这些哈希槽移动到7001节点上

  1. Source node #1:86d05e7c2b197dc182b5e71069e791d033cf899e
  2. Source node #2:done
  3. Do you want to proceed with the proposed reshard plan (yes/no)? yes

然后我们再继续执行移除命令,结果如下

  1. [root@centos1]# redis-trib.rb del-node 127.0.0.1:7000 86d05e7c2b197dc182b5e71069e791d033cf899e
  2. >>> Removing node 86d05e7c2b197dc182b5e71069e791d033cf899e from cluster 127.0.0.1:7000
  3. Connecting to node 127.0.0.1:7000: OK
  4. Connecting to node 127.0.0.1:7006: OK
  5. Connecting to node 127.0.0.1:7004: OK
  6. Connecting to node 127.0.0.1:7001: OK
  7. Connecting to node 127.0.0.1:7003: OK
  8. Connecting to node 127.0.0.1:7007: OK
  9. Connecting to node 127.0.0.1:7008: OK
  10. Connecting to node 127.0.0.1:7005: OK
  11. Connecting to node 127.0.0.1:7002: OK
  12. >>> Sending CLUSTER FORGET messages to the cluster...
  13. >>> 127.0.0.1:7006 as replica of 127.0.0.1:7001
  14. >>> 127.0.0.1:7008 as replica of 127.0.0.1:7001
  15. >>> SHUTDOWN the node.

删除成功,而且还很人性化的将7006和7008这2个原来7007的附属节点送给了7001。考虑的真周到~

移除一个从节点

移除一个从节点就比较简单了,因为从节点没有哈希槽,也不需要考虑数据迁移,直接移除就行

  1. [root@centos1]# redis-trib.rb del-node 127.0.0.1:7005 44321e7d619410dc4e0a8745366610a0d06d2395
  2. >>> Removing node 44321e7d619410dc4e0a8745366610a0d06d2395 from cluster 127.0.0.1:7005
  3. Connecting to node 127.0.0.1:7005: OK
  4. Connecting to node 127.0.0.1:7001: OK
  5. Connecting to node 127.0.0.1:7002: OK
  6. Connecting to node 127.0.0.1:7004: OK
  7. Connecting to node 127.0.0.1:7000: OK
  8. Connecting to node 127.0.0.1:7006: OK
  9. Connecting to node 127.0.0.1:7008: OK
  10. Connecting to node 127.0.0.1:7003: OK
  11. >>> Sending CLUSTER FORGET messages to the cluster...
  12. >>> SHUTDOWN the node.
  13. [root@centos1]# redis-trib.rb check 127.0.0.1:7008
  14. Connecting to node 127.0.0.1:7008: [ERR] Sorry, can't connect to node 127.0.0.1:7008

表示移除成功

Redis性能测试

Redis自带了性能测试工具redis-benchmark
使用说明如下:

  1. Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>]
  2. -h <hostname> Server hostname (default 127.0.0.1)
  3. -p <port> Server port (default 6379)
  4. -s <socket> Server socket (overrides host and port)
  5. -c <clients> Number of parallel connections (default 50)
  6. -n <requests> Total number of requests (default 10000)
  7. -d <size> Data size of SET/GET value in bytes (default 2)
  8. -k <boolean> 1=keep alive 0=reconnect (default 1)
  9. -r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD
  10. Using this option the benchmark will get/set keys
  11. in the form mykey_rand:000000012456 instead of constant
  12. keys, the <keyspacelen> argument determines the max
  13. number of values for the random number. For instance
  14. if set to 10 only rand:000000000000 - rand:000000000009
  15. range will be allowed.
  16. -P <numreq> Pipeline <numreq> requests. Default 1 (no pipeline).
  17. -q Quiet. Just show query/sec values
  18. --csv Output in CSV format
  19. -l Loop. Run the tests forever
  20. -t <tests> Only run the comma-separated list of tests. The test
  21. names are the same as the ones produced as output.
  22. -I Idle mode. Just open N idle connections and wait.

基准测试

基准的测试命令:
redis-benchmark -q -n 100000
结果入下:

  1. root@centos1 bin]# redis-benchmark -q -n 100000
  2. -bash: redis-benchmark: command not found
  3. [root@centos1 bin]# ./redis-benchmark -q -n 100000
  4. PING_INLINE: 61576.36 requests per second
  5. PING_BULK: 60277.28 requests per second
  6. SET: 61349.69 requests per second
  7. GET: 60459.49 requests per second
  8. INCR: 58858.15 requests per second
  9. LPUSH: 59066.75 requests per second
  10. RPUSH: 57339.45 requests per second
  11. LPOP: 55586.44 requests per second
  12. RPOP: 56465.27 requests per second
  13. SADD: 57045.07 requests per second
  14. SPOP: 53734.55 requests per second
  15. LPUSH (needed to benchmark LRANGE): 57012.54 requests per second
  16. LRANGE_100 (first 100 elements): 55803.57 requests per second
  17. LRANGE_300 (first 300 elements): 54914.88 requests per second
  18. LRANGE_500 (first 450 elements): 53333.33 requests per second
  19. LRANGE_600 (first 600 elements): 56529.11 requests per second
  20. MSET (10 keys): 59276.82 requests per second

这里可以看出,单机版的redis每秒可以处理6万个请求,这已经是一个非常厉害的数据了,不得不佩服
我们再来看下集群情况下是是什么情况

  1. [root@centos1 bin]# ./redis-benchmark -q -n 100000 -p 7000
  2. PING_INLINE: 64599.48 requests per second
  3. PING_BULK: 64184.85 requests per second
  4. SET: 66800.27 requests per second
  5. GET: 65616.80 requests per second
  6. INCR: 66269.05 requests per second
  7. LPUSH: 40273.86 requests per second
  8. RPUSH: 40355.12 requests per second
  9. LPOP: 43421.62 requests per second
  10. RPOP: 45187.53 requests per second
  11. SADD: 62539.09 requests per second
  12. SPOP: 61538.46 requests per second
  13. LPUSH (needed to benchmark LRANGE): 38182.51 requests per second
  14. LRANGE_100 (first 100 elements): 25555.84 requests per second
  15. LRANGE_300 (first 300 elements): 9571.21 requests per second
  16. LRANGE_500 (first 450 elements): 7214.49 requests per second
  17. LRANGE_600 (first 600 elements): 5478.85 requests per second
  18. MSET (10 keys): 41893.59 requests per second

这里看出大部分和单机版的性能查不多,主要是lrange命令的差别是很大的

流水线测试

使用流水线
默认情况下,每个客户端都是在一个请求完成之后才发送下一个请求(基准会模拟50个客户端除非使用-c指定特别的数量),这意味着服务器几乎是按顺序读取每个客户端的命令。RTT也加入了其中。
真实世界会更复杂,Redis支持/topics/pipelining,使得可以一次性执行多条命令成为可能。Redis流水线可以提高服务器的TPS
redis-benchmark -n 1000000 -t set,get -P 16 -q 加入-P选项使用管道技术,一次执行多条命令

  1. ./redis-benchmark -n 1000000 -t set,get -P 16 -q
  2. SET: 515198.34 requests per second
  3. GET: 613873.56 requests per second

每秒处理get/sret请求达到了60/50W,真的厉害!

遇到的问题

  1. 安装redis集群的时候遇到了挺多问题,踩了很多坑,单单是修改配置文件就出了不少问题,那些配置文件的内容都要一一修改,有些配置不修改就会出现无法创建进程的错误
  2. 注意配置集群的时候不要加密码,否则会出现无法连接的情况
  3. gem install的时候需要修改镜像或者翻墙
  4. 昨天启动成功,今天启动的时候报错
  1. [ERR] Node 172.168.63.202:7001 is not empty. Either the nodealready knows other nodes (check with CLUSTER NODES) or contains some key in database 0

解决方法:
1). 将需要新增的节点下aof、rdb等本地备份文件删除;
2). 同时将新Node的集群配置文件删除,即:删除你redis.conf里面cluster-config-file所在的文件;
3). 再次添加新节点如果还是报错,则登录新Node,执行bin/redis-cli–h x –p对数据库进行清除:

  1. 127.0.0.1:7001> flushdb #清空当前数据库

总结

之间对了Redis的了解并不是说非常多,只是简单的会用,因为现在企业里也很多都在用,刚好老大说接下来的项目可能会用到Redis集群,让我先去了解下,所以最近就在回头看,一边看文档,博客,一边实践,踩了很多的坑,出问题的时候的确是让人感到很痛苦很郁闷的,可是当运行成功的那一刻心情却是无比激动和开心的,可能这就是编程的魅力吧。

Redis集群的原理和搭建(转载)的更多相关文章

  1. Redis cluster集群:原理及搭建

    Redis cluster集群:原理及搭建 2018年03月19日 16:00:55 阅读数:6120 1.为什么使用redis? redis是一种典型的no-sql 即非关系数据库 像python的 ...

  2. Redis集群环境之linux搭建多机版---已完结,跟着一步一步来你就可以集群成功

    上一篇踩着各种坑写了Redis集群环境之linux搭建单机版,这一篇准备就多机版集群进行搭建,主要目的一来是在上一篇的基础上进行精华提粹总结,二来是把单机版与多机版的区别进行记录. 首先软硬件环境: ...

  3. Redis集群环境之linux搭建单机版

    Redis解决的问题是:作为一个缓存nosql数据库,能够支持高并发,关系型数据库是存储在磁盘中,通过io读写,而redis是存储在内存中,因此,能够实现高可用,他主要是解决数据库性能瓶颈而产生的. ...

  4. Redis 集群伸缩原理

    Redis 节点分别维护自己负责的槽和对应的数据.伸缩原理:Redis 槽和对应数据在不同节点之间移动 环境:CentOS7 搭建 Redis 集群 一.集群扩容 1. 手动扩容 (1) 准备节点 9 ...

  5. 三张图秒懂Redis集群设计原理

    转载Redis Cluster原理 转载https://blog.csdn.net/yejingtao703/article/details/78484151 redis集群部署方式: 单机 主从 r ...

  6. Redis集群设计原理

    ---恢复内容开始--- Redis集群设计包括2部分:哈希Slot和节点主从,本篇博文通过3张图来搞明白Redis的集群设计. 节点主从: 主从设计不算什么新鲜玩意,在数据库中我们也经常用主从来做读 ...

  7. 【集群】Redis集群设计原理

    Redis集群设计包括2部分:哈希Slot和节点主从 节点主从: 主从设计不算什么新鲜玩意,在数据库中我们也经常用主从来做读写分离,直接上图: 图上能看得到的信息: 1, 只有1个Master,可以有 ...

  8. linux高可用集群(HA)原理详解(转载)

    一.什么是高可用集群 高可用集群就是当某一个节点或服务器发生故障时,另一个 节点能够自动且立即向外提供服务,即将有故障节点上的资源转移到另一个节点上去,这样另一个节点有了资源既可以向外提供服务.高可用 ...

  9. Redis | 一文轻松搞懂redis集群原理及搭建与使用

    转载:https://juejin.im/post/5ad54d76f265da23970759d3 作者:SnailClimb 这里总结一下redis集群的搭建以便日后所需同时也希望能对你有所帮助. ...

随机推荐

  1. stm32——modbus例程网址收藏

    https://blog.csdn.net/baidu_31437863/article/details/82178708 STM32(五) Modbus https://blog.csdn.net/ ...

  2. 题解 [BZOJ4144] Petrol

    题目描述 ​ 有一张 n 个点 m 条边的无向图,其中有 s 个点上有加油站.有 Q 次询问(a,b,c), 问能否开一辆油箱容积为 c 的车从 a 走到 b.(a,b均为加油站) 输入格式 ​ 第一 ...

  3. Spring@PostConstruct和@PreDestroy注解详解

    @PostConstruct注解使用 @PostConstructApi使用说明 The PostConstruct annotation is used on a method that needs ...

  4. BZOJ 1097: [POI2007]旅游景点atr 状态压缩+Dijkstra

    题解: $k<=20,$ 考虑状压dp. 从 $1$ 号点走到 $n$ 号点经过的点的个数可能会非常多,但是强制要求经过的点一共才 $20$ 个. 而我们发现这个题好就好在可以经过某个城市,而不 ...

  5. WM_PAINT(父子窗口间)

    WM_PAINT(父子窗口间) 窗口句柄(HWND)都是由操作系统内核管理的,系统内部有一个z-order序列,记录着当前从屏幕底部(假象的从屏幕到眼睛的方向),到屏幕最高层的一个窗口句柄的排序,这个 ...

  6. javascript数据结构之单链表

    下面是用javascript实现的单链表,但是在输出的时候insert方法中存在问题,chrome的console报错说不能读取空的属性,调试了很久都没有通过,先在这里存着,以后再来修改一下. //数 ...

  7. DataTable转List,DataTable转为Model对象帮助类

    DataTable转List,DataTable转为Model对象帮助类 public class ModelConvertHelper<T> where T : new() { publ ...

  8. [Shell] 分隔字符串为数组

    #!/bin/bash tmp="test,girl,boy,love" OLD_IFS="$IFS" IFS="," arr=($a) I ...

  9. python3 threading.Lock() 多线程锁的使用

    import threadingimport time lock = threading.Lock() #创建锁 def fun(data): try: lock.acquire(True) #锁定 ...

  10. POJ3764

    题目 POJ3764 The xor-longest Path 原题传送门 主要思路: 1.求出每个点到根节点(这里是树,所以直接取0)路径上所有权值xor和为d[i],则任意两点间路径xor和则为 ...