## moved重定向
* 概念:在集群模式下,Redis接收任何鍵相關命令時首先計算鍵對應的槽,再根據槽找出所對應的節點,如果節點是自身,則處理鍵命令;否則回復MOVED重定向錯誤,通知客戶端請求正確的節點。如下圖所示

## 槽命中
```
? 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節點中完成請求轉發,如下圖所示:

* **節點對于不屬于它的鍵命令只回復重定向響應,并不負責轉發**。熟悉Cassandra的用戶希望在這里做好區分,不要混淆。正因為集群模式下把解析發起重定向的過程放到客戶端完成,所以集群客戶端協議相對于單機有了很大的變化;
## ask重定向
* Redis集群支持在線遷移槽(slot)和數據來完成水平伸縮,當slot對應的數據從源節點到目標節點遷移過程中,客戶端需要做到智能識別,保證鍵命令可正常執行。例如當一個slot數據從源節點遷移到目標節點時,期間可能出現一部分數據在源節點,而另一部分在目標節點,如下圖所示

**當出現上述情況時,客戶端鍵命令執行流程將發生變化,如下所示:**
* 1)客戶端根據本地slots緩存發送命令到源節點,如果存在鍵對象則直 接執行并返回結果給客戶端
* 2)如果鍵對象不存在,則可能存在于目標節點,這時源節點會回復 ASK重定向異常。格式如下:(error) ASK {slot} {targetIP}:{targetPort}
* 3)客戶端從ASK重定向異常提取出目標節點信息,發送asking命令到目標節點打開客戶端連接標識,再執行鍵命令。如果存在則執行,不存在則返 回不存在信息

**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布隆過濾器
- 分布式布隆過濾器
- 開發規范
- 內存管理
- 開發運維常見坑
- 實戰
- 對文章進行投票
- 數據庫的概念
- 啟動多實例