多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## moved重定向 * 概念:在集群模式下,Redis接收任何键相关命令时首先计算键对应的槽,再根据槽找出所对应的节点,如果节点是自身,则处理键命令;否则回复MOVED重定向错误,通知客户端请求正确的节点。如下图所示 ![](https://img.kancloud.cn/cf/b9/cfb9e18acb17904e5cd371cf35bdd1ad_506x545.png) ## 槽命中 ``` ➜ bin redis-cli -p 7000 127.0.0.1:7000> cluster keyslot age (integer) 741 //查询分配的槽位是741,这个槽位属于7002节点的 127.0.0.1:7000> cluster slots 1) 1) (integer) 0 2) (integer) 471 3) 1) "127.0.0.1" 2) (integer) 7001 3) "26cdec411e03740e81741fd1af56c84a8995e1bf" 4) 1) "127.0.0.1" 2) (integer) 7005 3) "4c0dcdf4862435f9e0b7ab9573c5d88ebce69c9e" 2) 1) (integer) 559 2) (integer) 719 3) 1) "127.0.0.1" 2) (integer) 7001 3) "26cdec411e03740e81741fd1af56c84a8995e1bf" 4) 1) "127.0.0.1" 2) (integer) 7005 3) "4c0dcdf4862435f9e0b7ab9573c5d88ebce69c9e" 3) 1) (integer) 1235 2) (integer) 1364 3) 1) "127.0.0.1" 2) (integer) 7001 3) "26cdec411e03740e81741fd1af56c84a8995e1bf" 4) 1) "127.0.0.1" 2) (integer) 7005 3) "4c0dcdf4862435f9e0b7ab9573c5d88ebce69c9e" 4) 1) (integer) 1407 2) (integer) 2405 3) 1) "127.0.0.1" 2) (integer) 7001 3) "26cdec411e03740e81741fd1af56c84a8995e1bf" 4) 1) "127.0.0.1" 2) (integer) 7005 3) "4c0dcdf4862435f9e0b7ab9573c5d88ebce69c9e" 5) 1) (integer) 5904 2) (integer) 6179 3) 1) "127.0.0.1" 2) (integer) 7001 3) "26cdec411e03740e81741fd1af56c84a8995e1bf" 4) 1) "127.0.0.1" 2) (integer) 7005 3) "4c0dcdf4862435f9e0b7ab9573c5d88ebce69c9e" 6) 1) (integer) 7282 2) (integer) 10922 3) 1) "127.0.0.1" 2) (integer) 7001 3) "26cdec411e03740e81741fd1af56c84a8995e1bf" 4) 1) "127.0.0.1" 2) (integer) 7005 3) "4c0dcdf4862435f9e0b7ab9573c5d88ebce69c9e" 7) 1) (integer) 12743 2) (integer) 13522 3) 1) "127.0.0.1" 2) (integer) 7001 3) "26cdec411e03740e81741fd1af56c84a8995e1bf" 4) 1) "127.0.0.1" 2) (integer) 7005 3) "4c0dcdf4862435f9e0b7ab9573c5d88ebce69c9e" 8) 1) (integer) 2406 2) (integer) 5653 3) 1) "127.0.0.1" 2) (integer) 7000 3) "e4bba455615996a2419f5ea68fb483572da69a4e" 4) 1) "127.0.0.1" 2) (integer) 7004 3) "f29d5a33719410d0d965f0cd04a1aaf62772113c" 9) 1) (integer) 6180 2) (integer) 7281 3) 1) "127.0.0.1" 2) (integer) 7000 3) "e4bba455615996a2419f5ea68fb483572da69a4e" 4) 1) "127.0.0.1" 2) (integer) 7004 3) "f29d5a33719410d0d965f0cd04a1aaf62772113c" 10) 1) (integer) 10923 2) (integer) 12742 3) 1) "127.0.0.1" 2) (integer) 7000 3) "e4bba455615996a2419f5ea68fb483572da69a4e" 4) 1) "127.0.0.1" 2) (integer) 7004 3) "f29d5a33719410d0d965f0cd04a1aaf62772113c" 11) 1) (integer) 13523 2) (integer) 13845 3) 1) "127.0.0.1" 2) (integer) 7000 3) "e4bba455615996a2419f5ea68fb483572da69a4e" 4) 1) "127.0.0.1" 2) (integer) 7004 3) "f29d5a33719410d0d965f0cd04a1aaf62772113c" 12) 1) (integer) 472 2) (integer) 558 3) 1) "127.0.0.1" 2) (integer) 7002 3) "86ebe5a560dc152174ae87b4555890486aa35051" 4) 1) "127.0.0.1" 2) (integer) 7003 3) "6f0a7298bd81de901ebd4989504a4d914e5002e2" 13) 1) (integer) 720 //741属于7002节点 2) (integer) 1234 3) 1) "127.0.0.1" 2) (integer) 7002 3) "86ebe5a560dc152174ae87b4555890486aa35051" 4) 1) "127.0.0.1" 2) (integer) 7003 3) "6f0a7298bd81de901ebd4989504a4d914e5002e2" 14) 1) (integer) 1365 2) (integer) 1406 3) 1) "127.0.0.1" 2) (integer) 7002 3) "86ebe5a560dc152174ae87b4555890486aa35051" 4) 1) "127.0.0.1" 2) (integer) 7003 3) "6f0a7298bd81de901ebd4989504a4d914e5002e2" 15) 1) (integer) 5654 2) (integer) 5903 3) 1) "127.0.0.1" 2) (integer) 7002 3) "86ebe5a560dc152174ae87b4555890486aa35051" 4) 1) "127.0.0.1" 2) (integer) 7003 3) "6f0a7298bd81de901ebd4989504a4d914e5002e2" 16) 1) (integer) 13846 2) (integer) 16383 3) 1) "127.0.0.1" 2) (integer) 7002 3) "86ebe5a560dc152174ae87b4555890486aa35051" 4) 1) "127.0.0.1" 2) (integer) 7003 3) "6f0a7298bd81de901ebd4989504a4d914e5002e2" ``` ``` ➜ bin redis-cli -p 7000 //没有以集群模式连接 127.0.0.1:7000> set age 20 (error) MOVED 741 127.0.0.1:7002 //返回moved错误,并且通知客户端经过哈希计算云这个key被分配的槽位,然后需要客户端自行的去连接这个节点重新set ``` ``` ➜ bin redis-cli -c -p 7000 //以集群模式启动 -c 127.0.0.1:7000> set age 20 -> Redirected to slot [741] located at 127.0.0.1:7002 //moved重定向写入成功 OK 127.0.0.1:7002> //可以看到客户端自动重定向到7002这个节点了 ``` redis-cli自动帮我们连接到正确的节点执行命令,这个过程是在redis-cli内部维护,-c参数支持自动重定向,简化手动发起重定向操作.实质上是client端接到MOVED信息之后再次发起请求,并不在Redis节点中完成请求转发,如下图所示: ![](https://img.kancloud.cn/bf/2f/bf2fbdcd02e3c091fae54b092246c3dc_637x409.png) * **节点对于不属于它的键命令只回复重定向响应,并不负责转发**。熟悉Cassandra的用户希望在这里做好区分,不要混淆。正因为集群模式下把解析发起重定向的过程放到客户端完成,所以集群客户端协议相对于单机有了很大的变化; ## ask重定向 * Redis集群支持在线迁移槽(slot)和数据来完成水平伸缩,当slot对应的数据从源节点到目标节点迁移过程中,客户端需要做到智能识别,保证键命令可正常执行。例如当一个slot数据从源节点迁移到目标节点时,期间可能出现一部分数据在源节点,而另一部分在目标节点,如下图所示 ![](https://img.kancloud.cn/ec/c1/ecc1e869b07f5b96093ed686a5044865_495x555.png) **当出现上述情况时,客户端键命令执行流程将发生变化,如下所示:** * 1)客户端根据本地slots缓存发送命令到源节点,如果存在键对象则直 接执行并返回结果给客户端 * 2)如果键对象不存在,则可能存在于目标节点,这时源节点会回复 ASK重定向异常。格式如下:(error) ASK {slot} {targetIP}:{targetPort} * 3)客户端从ASK重定向异常提取出目标节点信息,发送asking命令到目标节点打开客户端连接标识,再执行键命令。如果存在则执行,不存在则返 回不存在信息 ![](https://img.kancloud.cn/14/a2/14a26b00e1e8d0b6fe8d5174436ab758_638x474.png) **ASK与MOVED虽然都是对客户端的重定向控制,但是有着本质区别:** * ASK重定向说明集群正在进行slot数据迁移,客户端无法知道什么时候迁移 完成,因此只能是临时性的重定向,客户端不会更新slots缓存 * 但是MOVED重定向说明键对应的槽已经明确指定到新的节点,因此需要更新slots缓存 ## moved和ask区别 1. 两者都是客户端重定向(都需要客户端重新发起请求); 2. moved:槽位已经确定迁移; 3. ask:槽还在迁移中; ## smart客户端