## 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客户端
- Redis简介
- 简介
- 典型应用场景
- Redis安装
- 安装
- redis可执行文件说明
- 三种启动方法
- Redis常用配置
- API的使用和理解
- 通用命令
- 数据结构和内部编码
- 单线程
- 数据类型
- 字符串
- 哈希
- 列表
- 集合
- 有序集合
- Redis常用功能
- 慢查询
- Pipline
- 发布订阅
- Bitmap
- Hyperloglog
- GEO
- 持久化机制
- 概述
- snapshotting快照方式持久化
- append only file追加方式持久化AOF
- RDB和AOF的抉择
- 开发运维常见问题
- fork操作
- 子进程外开销
- AOF追加阻塞
- 单机多实例部署
- Redis复制原理和优化
- 什么是主从复制
- 主从复制配置
- 全量复制和部分复制
- 故障处理
- 开发运维常见问题
- Sentinel
- 主从复制高可用
- 架构说明
- 安装配置
- 客户端连接
- 实现原理
- 常见开发运维问题
- 高可用读写分离
- 故障转移client怎么知道新的master地址
- 总结
- Sluster
- 呼唤集群
- 数据分布
- 搭建集群
- 集群通信
- 集群扩容
- 集群缩容
- 客户端路由
- 故障转移
- 故障发现
- 故障恢复
- 开发运维常见问题
- 缓存设计与优化
- 缓存收益和成本
- 缓存更新策略
- 缓存粒度控制
- 缓存穿透优化
- 缓存雪崩优化
- 无底洞问题优化
- 热点key重建优化
- 总结
- 布隆过滤器
- 引出布隆过滤器
- 布隆过滤器基本原理
- 布隆过滤器误差率
- 本地布隆过滤器
- Redis布隆过滤器
- 分布式布隆过滤器
- 开发规范
- 内存管理
- 开发运维常见坑
- 实战
- 对文章进行投票
- 数据库的概念
- 启动多实例