Redis-plus-plus学习笔记-cluster模式命令发送

Redis plus plus是一个c++版本的Redis客户端,更详细的介绍见:https://blog.csdn.net/qq_34999565/article/details/119918553
cluster模式的命令发送接口如下,和普通命令发送接口的区别主要有几点
1,当命令返回一个io错误IoError的时候,有可能是主节点已经下线,这时候从节点会被晋升为主节点。往一个旧的的主节点发送命令就会返回一个IoError错误,这种情况下需要更新槽位映射关系;
2,如果一个节点已被移除,再往这个节点发送命令也会返回一个错误-ClosedError,这时也需要重新更新槽位映射;
3,对重定向MovedError错误的处理,发生这个错误意味着槽位映射出错了,所以也要更新槽位映射;
4,aski错误,这种情况发生于槽位迁移过程中,这种情况不需要更新槽位映射,ask错误会把目标节点信息带过来,只需从目标节点中获取一条新的连接,再往该链接发送一个asking命令,然后在重发命令

ReplyUPtr RedisCluster::_command(Cmd cmd, const StringView &key, Args &&...args) {
    for (auto idx = 0; idx < 2; ++idx) {
        try {
            auto pool = _pool.fetch(key);
            assert(pool);
            SafeConnection safe_connection(*pool);

            return _command(cmd, safe_connection.connection(), std::forward<Args>(args)...);
        } catch (const IoError &err) {
            // When master is down, one of its replicas will be promoted to be the new master.
            // If we try to send command to the old master, we'll get an *IoError*.
            // In this case, we need to update the slots mapping.
            _pool.update();
        } catch (const ClosedError &err) {
            // Node might be removed.
            // 1. Get up-to-date slot mapping to check if the node still exists.
            _pool.update();

            // TODO:
            // 2. If it's NOT exist, update slot mapping, and retry.
            // 3. If it's still exist, that means the node is down, NOT removed, throw exception.
        } catch (const MovedError &err) {
            // Slot mapping has been changed, update it and try again.
            _pool.update();
        } catch (const AskError &err) {
            auto pool = _pool.fetch(err.node());
            assert(pool);
            SafeConnection safe_connection(*pool);
            auto &connection = safe_connection.connection();

            // 1. send ASKING command.
            _asking(connection);

            // 2. resend last command.
            try {
                return _command(cmd, connection, std::forward<Args>(args)...);
            } catch (const MovedError &err) {
                throw Error("Slot migrating... ASKING node hasn't been set to IMPORTING state");
            }
        } // For other exceptions, just throw it.
    }

    // Possible failures:
    // 1. Source node has already run 'CLUSTER SETSLOT xxx NODE xxx',
    //    while the destination node has NOT run it.
    //    In this case, client will be redirected by both nodes with MovedError.
    // 2. Other failures...
    throw Error("Failed to send command with key: " + std::string(key.data(), key.size()));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值