设为首页 收藏本站
查看: 1407|回复: 0

[经验分享] redis-cluster集群扩容以及扩容client读写数据影响的探究

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-2-22 10:50:56 | 显示全部楼层 |阅读模式
redis-cluster集群扩容以及扩容client读写数据影响的探究

    一直以来,从来只是对codis做过slot的动态迁移(同扩容)而且也只是线下环境,而没有对线上的redis-cluster做过扩容和迁移。早就想有空测试一下却一直没有实际去做,然而就在今天收到了产品部的需求,要对线上某个业务线的redis-cluster做扩容。。。 这也正印证佛家那就话,你结下的因,早晚成你的果。(不懂,瞎说的)
    借此契机,一探究竟。

测试环境:
    主机类型:虚拟机  操作系统:centos6.5_x86_64
    配置:1×1 4G 内存

1 构建集群
    (具体过程略)
    在单台主机上运行6个redis实例(端口:6380-6385)构造一个小集群,如下:
1
2
3
4
5
6
7
[iyunv@salt-master ~]# redis-cli -c -p 6380 cluster nodes
ffb86e1168215b138c5b7a81ad92e44ca7095b54 192.168.11.3:6380 myself,master - 0 0 1 connected 0-5460
88e0cdfb2794816cb9a1ca39b7ad640656d5ef85 192.168.11.3:6382 master - 0 1487335437581 3 connected 10923-16383
a7a1020c36b8b0277c41ac7fc649ed9e81fa1448 192.168.11.3:6384 slave 8b20dd24f0aa2ba05754c4db016e0a29299df24e 0 1487335430478 5 connected
8de9d0da9dfd0db0553c68386cbccdcb58365123 192.168.11.3:6383 slave ffb86e1168215b138c5b7a81ad92e44ca7095b54 0 1487335436632 4 connected
e8e6d0e32e0f2ee918795e3a232b9c768b671f39 192.168.11.3:6385 slave 88e0cdfb2794816cb9a1ca39b7ad640656d5ef85 0 1487335435563 6 connected
8b20dd24f0aa2ba05754c4db016e0a29299df24e 192.168.11.3:6381 master - 0 1487335433541 2 connected 5461-1092




    从上面的输出可以看出,此集群有3个主节点(master),每个节点1个副本(slave),以及各个节点的IP、端口、ID、16384个slot槽位的分配。

2 模拟数据
    为了稍后测试扩容时是否影响读写,我们先在集群里写点数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from rediscluster import StrictRedisCluster
# Requires at least one node for cluster discovery. Multiple nodes is recommended.
startup_nodes = [{"host": "192.168.11.3", "port": "6380"},
                {"host": "192.168.11.3", "port": "6381"},
                {"host": "192.168.11.3", "port": "6382"},
                {"host": "192.168.11.3", "port": "6383"},
                {"host": "192.168.11.3", "port": "6384"},
                {"host": "192.168.11.3", "port": "6385"}]
rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
# pre_time = time.time()
for i in xrange(100000):
    key = "key_%s" % i
    value = "value_%s" % i
    rc.set(key, value)
# aft_time = time.time()
# print aft_time - pre_time





(PS:我的这个小集群set 10万个key耗时21秒,有兴趣的可以和你自己的对比一下)
补充:
    redis-cluster会额外启用一个端口(默认是所监听的port+10000)其他与其它节点通信的总线端口(一个有N个节点的集群,则在每个节点上,都有N-1个进来的连接和N-1个出去的连接与其他节点进行通信)。所以连接上集群的任一节点,即可知晓所有节点。

3 新增资源
     还是在这台虚拟机上,我们在启动2个redis实例,作为新增的资源。
     新增两个实例端口分别为6386 6387
1
2
[iyunv@salt-master conf]# /usr/local/redis-server/bin/redis-server /usr/local/redis-server/conf/redis6386.conf
[iyunv@salt-master conf]# /usr/local/redis-server/bin/redis-server /usr/local/redis-server/conf/redis6387.conf




4 扩容集群
    将上面新增的2个实例扩容到集群,此时只是集群间相互知道有新的成员了,但新成员上未分配slot(slot集群分配数据的最小单元),所以此时新增节点上不会有任何数据。

4.1 添加主节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[iyunv@salt-master conf]# /usr/local/redis-server/bin/redis-trib.rb add-node 192.168.11.3:6386 192.168.11.3:6380
>>> Adding node 192.168.11.3:6386 to cluster 192.168.11.3:6380
>>> Performing Cluster Check (using node 192.168.11.3:6380)
M: ffb86e1168215b138c5b7a81ad92e44ca7095b54 192.168.11.3:6380
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 88e0cdfb2794816cb9a1ca39b7ad640656d5ef85 192.168.11.3:6382
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: a7a1020c36b8b0277c41ac7fc649ed9e81fa1448 192.168.11.3:6384
   slots: (0 slots) slave
   replicates 8b20dd24f0aa2ba05754c4db016e0a29299df24e
S: 8de9d0da9dfd0db0553c68386cbccdcb58365123 192.168.11.3:6383
   slots: (0 slots) slave
   replicates ffb86e1168215b138c5b7a81ad92e44ca7095b54
S: e8e6d0e32e0f2ee918795e3a232b9c768b671f39 192.168.11.3:6385
   slots: (0 slots) slave
   replicates 88e0cdfb2794816cb9a1ca39b7ad640656d5ef85
M: 8b20dd24f0aa2ba05754c4db016e0a29299df24e 192.168.11.3:6381
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.11.3:6386 to make it join the cluster.
[OK] New node added correctly.



    解释:
redis-trib.rb add-node 192.168.11.3:6386 192.168.11.3:6380
命令          添加节点   新节点的IP:port    集群任意节点的IP:port(用于集群发现)

    同理,为刚添加的主节点增加副本(即添加从节点)
    首先查看新增节点的ID:
1
2
[iyunv@salt-master conf]# redis-cli -c -p 6380 CLUSTER nodes | grep 6386
301b60cdb455b9ae27b7b562524c0d039e640815 192.168.11.3:6386 master - 0 1487342302506 0 connected





   4.2 添加从节点:
1
2
3
redis-trib.rb add-node  
--slave --master-id 301b60cdb455b9ae27b7b562524c0d039e640815 192.168.11.3:6387
192.168.11.3:6380



    查看整个集群状况:
1
2
3
4
5
6
7
8
9
[iyunv@salt-master conf]# redis-cli -c -p 6380 CLUSTER nodes
301b60cdb455b9ae27b7b562524c0d039e640815 192.168.11.3:6386 master - 0 1487342439807 0 connected
ffb86e1168215b138c5b7a81ad92e44ca7095b54 192.168.11.3:6380 myself,master - 0 0 1 connected 0-5460
b34e53b4b82fb11043f73819179524d49ce75ead 192.168.11.3:6387 slave 301b60cdb455b9ae27b7b562524c0d039e640815 0 1487342438797 0 connected
88e0cdfb2794816cb9a1ca39b7ad640656d5ef85 192.168.11.3:6382 master - 0 1487342441826 3 connected 10923-16383
a7a1020c36b8b0277c41ac7fc649ed9e81fa1448 192.168.11.3:6384 slave 8b20dd24f0aa2ba05754c4db016e0a29299df24e 0 1487342434759 5 connected
8de9d0da9dfd0db0553c68386cbccdcb58365123 192.168.11.3:6383 slave ffb86e1168215b138c5b7a81ad92e44ca7095b54 0 1487342440816 4 connected
e8e6d0e32e0f2ee918795e3a232b9c768b671f39 192.168.11.3:6385 slave 88e0cdfb2794816cb9a1ca39b7ad640656d5ef85 0 1487342443843 6 connected
8b20dd24f0aa2ba05754c4db016e0a29299df24e 192.168.11.3:6381 master - 0 1487342444851 2 connected 5461-10922





    可以看到新增的2个节点已经加入集群,但是没有分配slot,所有目前不会接受任何redis client连接请求
5 迁移slot,测试读写

    接下来我们重新分配集群的slot,使所有的节点数量均衡,于此同时模拟业务程序对集群读写操作,观察扩容迁移过程中读写是否出错并统计出错的key数量。

5.1 模拟业务程序
    逻辑:在迁移slot过程中,对集群操作,变更key对应的值,然后立刻获取key的值,若得到的值与我们设置的值相同,则数据一致,未出错;若不同(即set没有写入或get错误结果)则统计为错误。
    该程序暂不运行,待到开始迁移slot后,运行该程序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from rediscluster import StrictRedisCluster
# Requires at least one node for cluster discovery. Multiple nodes is recommended.
startup_nodes = [{"host": "192.168.11.3", "port": "6380"},
                {"host": "192.168.11.3", "port": "6381"},
                {"host": "192.168.11.3", "port": "6382"},
                {"host": "192.168.11.3", "port": "6383"},
                {"host": "192.168.11.3", "port": "6384"},
                {"host": "192.168.11.3", "port": "6385"}]
rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
count = 0
for i in xrange(100000):
    key = "key_%s" % i
    value = "_value_%s" % i
    rc.set(key, value)
    result = rc.get(key)
    if result == value:
        pass
    else:
        count +=1
print count




5.2 迁移slot
    为新增的节点分配slot,也就是把防止在其他节点上的slot迁移到这个节点上,网友的一句话形容的很形象:就像玩扑克抽牌一样:slot从A迁移到B,就好像从A抽一张牌,从其他所有节点迁移N个slot,类似重新洗牌发牌一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[iyunv@salt-master bin]# redis-trib.rb reshard 192.168.11.3:6380    # 分配slot
>>> Performing Cluster Check (using node 192.168.11.3:6380)
M: ffb86e1168215b138c5b7a81ad92e44ca7095b54 192.168.11.3:6380
   slots:2683-5460 (2778 slots) master
   1 additional replica(s)
S: 8617133eb1d2ef07f87dd6b108a4a0ec53ccdf99 192.168.11.3:6391
   slots: (0 slots) slave
   replicates cdbcbd49b78684188fe321eec90e625ed394e0b7
(省略部分输出......)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 6384            # 输入要迁移的slot的数量
What is the receiving node ID? cdbcbd49b78684188fe321eec90e625ed394e0b7
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:all                                                    # 输入slot来源节点,all表示所有其它节点
    Moving slot 6260 from 301b60cdb455b9ae27b7b562524c0d039e640815
    Moving slot 6261 from 301b60cdb455b9ae27b7b562524c0d039e640815
    Moving slot 6262 from 301b60cdb455b9ae27b7b562524c0d039e640815
    Moving slot 6263 from 301b60cdb455b9ae27b7b562524c0d039e640815
Do you want to proceed with the proposed reshard plan (yes/no)? yes    # 最终确认
Moving slot 0 from 192.168.11.3:6388 to 192.168.11.3:6390: .....
.......





    迁移的slot的数量可以根据节点配置不同而不同,若各节点配置相同,则可以平均分配slot(n=16384/主节点数量)
    另外,在承载业务的集群上面进行迁移时,数据量越大,迁移时间越长。

6 本次探究结论
    redis-cluster扩容(slot迁移)不影响数据的读写。




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-345628-1-1.html 上篇帖子: Redis集群redis主从自动切换Sentinel(哨兵模式) 下篇帖子: Redis高级特性介绍及实例分析 影响
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表