前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis Cluster 槽迁移与Smart客户端

Redis Cluster 槽迁移与Smart客户端

作者头像
一个架构师
发布2022-06-20 19:56:57
8200
发布2022-06-20 19:56:57
举报
文章被收录于专栏:从码农的全世界路过

在redis cluster集群中,不可避免的会出现数据不平衡的情况,为了平衡各节点的压力,就需要对集群做节点平衡处理,将数据从负载较高的节点迁移到负载低的节点.

代码语言:javascript
复制
redis-trib.rb rebalance 127.0.0.1:6379

当集群中新加入节点时,也需要对数据做迁移处理.

代码语言:javascript
复制
redis-trib.rb reshard --from all --to xxx --slots 110 127.0.0.1:6379

下面就一起看下hash槽迁移的过程.

槽迁移

在使用redis-trib.rb做rebalance和reshard进行节点迁移的时候,都会调用move_slot()方法进行数据数据和hash槽迁移.

通过方法可以了解具体迁移步骤

1.将迁移目标节点设置为importing状态

代码语言:javascript
复制
CLUSTER SETSLOT slot IMPORTING node

2.将迁移源节点设置为migrating状态

代码语言:javascript
复制
CLUSTER SETSLOT slot MIGRATING node

3.从源节点中取出槽对应部分key

代码语言:javascript
复制
CLUSTER GETKEYSINSLOT slot count

4.将取出的key写入目标节点

代码语言:javascript
复制
MIGRATE 192.168.1.34 6379 "" 0 5000 KEYS key1 key2 key3

5.重复上述3和4两步骤,直到数据迁移完毕

6.通知所有节点hash槽变化,并退出importing或migrating

代码语言:javascript
复制
CLUSTER SETSLOT slot NODE node

7.如果想取消hash槽迁移动作可以执行以下命令

代码语言:javascript
复制
CLUSTER SETSLOT slot stable

move_slot()方法主要逻辑如下:

代码语言:javascript
复制
def move_slot(source,target,slot,o={})
...
    if !o[:cold]
        target.r.cluster("setslot",slot,"importing",source.info[:name])
        source.r.cluster("setslot",slot,"migrating",target.info[:name])
    end
    # Migrate all the keys from source to target using the MIGRATE command
    while true
        keys = source.r.cluster("getkeysinslot",slot,o[:pipeline])
        break if keys.length == 0
        begin
            source.r.client.call(["migrate",target.info[:host],target.info[:port],"",0,@timeout,:keys,*keys])
        rescue => e
            if o[:fix] && e.to_s =~ /BUSYKEY/
                xputs "*** Target key exists. Replacing it for FIX."
                source.r.client.call(["migrate",target.info[:host],target.info[:port],"",0,@timeout,:replace,:keys,*keys])
            else
                puts ""
                xputs "[ERR] Calling MIGRATE: #{e}"
                exit 1
            end
        end
        print "."*keys.length if o[:dots]
        STDOUT.flush
    end
    puts if !o[:quiet]
    # Set the new node as the owner of the slot in all the known nodes.
    if !o[:cold]
        @nodes.each{|n|
            next if n.has_flag?("slave")
            n.r.cluster("setslot",slot,"node",target.info[:name])
        }
    end
....
end

Smart客户端

符合Redis的Smart客户端会在内部维护hash槽与节点的映射关系.

客户端在发送请求时,会先根据CRC16(key)%16384计算key对应的hash槽,通过映射关系,本地就可实现键到节点的查找,从而保证IO效率的最大化.

但如果出现故障转移或者hash槽迁移时,这个映射关系是如何维护的呢?

Moved

当对应的hash槽已经迁移到变的节点时,

1. Redis cluster会返回给客户端一个moved错误, 并告诉节点这个hash槽迁移后的节点IP和端口是多少

2. 客户端接受到moved错误时,会更新本地的映射关系

3. 客户端向新节点发送请求命令

Ask

如果hash槽是在迁移中时,发生的请求呢?

1. 源节点接收到请求后,会先判断这个key是否还在源节点,则返回请求结果

2. 如果key不在源节点时,会返回ask错误,并返回目标节点的IP和端口

3. 客户端向迁移目标节点,首先发送asking命令,再发送数据相关请求命令

4. 客户端在收到ask错误时,并不会更新本地槽与节点的映射关系

ask与moved可以简单的理解为hash槽的临时重定向和永久重定向.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 从码农的全世界路过 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档