Rust 寫的 Undermoon Redis 集群 -Redis Cluster Protocol與Server Proxy
感謝 doyoubi 提供這么好的項(xiàng)目,原文:https://github.com/doyoubi/undermoon/blob/master/docs/redis_cluster_protocol.md
Redis Cluster 是官方的 Redis 分布式解決方案,支持 sharding(分片) 和 failover(故障轉(zhuǎn)移)。與使用單實(shí)例 redis 相比,連接 Redis Cluster 的客戶端需要實(shí)現(xiàn) Redis Cluster Client Protocol。它的基本作用是:
- 如果我們沒(méi)有向正確的節(jié)點(diǎn)發(fā)送命令,則重定向請(qǐng)求。
- 從 CLUSTER NODES 和 CLUSTER SLOTS 這兩個(gè)命令之一緩存集群路由表。
這種客戶端稱為 Smart Client。
https://redis.io/topics/cluster-tutorial
為了兼容現(xiàn)有的 Redis client,還有一些 Redis Cluster Proxies,如 redis-cluster-proxy(官方)、aster、corvus 和 samaritan,以使集群協(xié)議適應(yīng)廣泛支持的單實(shí)例協(xié)議。
- https://github.com/RedisLabs/redis-cluster-proxy
- https://github.com/wayslog/aster
- https://github.com/eleme/corvus
- https://github.com/samaritan-proxy/samaritan
Undermoon 是如何實(shí)現(xiàn) “Redis Cluster Protocol” 的?
Undermoon 基于 server-side proxy 或 Server Proxy 實(shí)現(xiàn) Redis Cluster Protocol。Server Proxy 將像官方的 Redis Cluster Redis 一樣工作,并在需要時(shí)返回重定向響應(yīng)。
為什么要實(shí)現(xiàn)另一個(gè) “Redis Cluster Protocol”?
該實(shí)現(xiàn)不僅支持水平可擴(kuò)展性和高可用性,還使您能夠構(gòu)建一個(gè)自我管理的分布式 Redis,支持:
- Redis 資源池管理
- 為不同的用戶提供多個(gè)集群
- 將流量洪水均勻地傳播到所有物理機(jī)
- 擴(kuò)容迅速
- 操作和 Kubernetes 集成更容易。
為什么是 Server-side Proxy?
Redis 和大多數(shù) redis 代理(如 redis-cluster-proxy、corvus、aster、codis)部署在獨(dú)立的機(jī)器上,因?yàn)榇硗ǔP枰獙⒄?qǐng)求分散到不同的 Redis 實(shí)例。
Server-side Proxy 不是路由請(qǐng)求,而是充當(dāng)與這些代理不同的角色,類似于 Redis 的 cluster module,通過(guò)使用一些定制的遷移協(xié)議,使其能夠遷移數(shù)據(jù)并快速擴(kuò)展。
Server-side Proxy
以下是 Server-side Proxy 和 Redis Cluster Protocol 的一小部分操作。
首先運(yùn)行一個(gè) redis-server。
$ redis-server
構(gòu)建并運(yùn)行 server_proxy,在端口 5299 上運(yùn)行并將命令轉(zhuǎn)發(fā)到 127.0.0.1:6379。
> cargo build
> make server
> redis-cli -p 5299
# 通過(guò) `UMCTL` 命令初始化代理。
127.0.0.1:5299> UMCTL SETCLUSTER v2 1 NOFLAGS mydb 127.0.0.1:6379 1 0-8000 PEER 127.0.0.1:7000 1 8001-16383
# Done! 我們可以像 Redis Cluster 一樣使用它!
# 和官方的 Redis Cluster 不同,這里只顯示 master 節(jié)點(diǎn)
# 而不是同時(shí)顯示主服務(wù)器和副本。
127.0.0.1:5299> CLUSTER NODES
mydb________________9f8fca2805923328____ 127.0.0.1:5299 myself,master - 0 0 1 connected 0-8000
mydb________________d458dd9b55cc9ad9____ 127.0.0.1:7000 master - 0 0 1 connected 8001-16383
# 當(dāng)我們使用 UMCTL SETCLUSTER 初始化它時(shí),
# 插槽(slots) 8001-16383 屬于另一個(gè)服務(wù)器代理 127.0.0.1:7000
# 所以我們得到一個(gè)重定向響應(yīng)。
#
# 這是普通 Redis client 和 Redis Cluster client 的關(guān)鍵區(qū)別
# 因?yàn)槲覀冃枰幚碇囟ㄏ颉?br>127.0.0.1:5299> get a
(error) MOVED 15495 127.0.0.1:7000
# Key 'b' 是該代理負(fù)責(zé)的,因此我們處理請(qǐng)求。
127.0.0.1:5299> set b 1
OK