感谢
doyoubi
提供这么好的项目,原文:https://github.com/doyoubi/undermoon/blob/master/docs/redis_cluster_protocol.md
Redis Cluster
是官方的 Redis
分布式解决方案,支持 sharding(分片)
和 failover(故障转移)
。与使用单实例 redis
相比,连接 Redis Cluster
的客户端需要实现 Redis Cluster Client Protocol
。它的基本作用是:
- 如果我们没有向正确的节点发送命令,则重定向请求。
- 从
CLUSTER NODES
和CLUSTER SLOTS
这两个命令之一缓存集群路由表。
这种客户端称为 Smart Client。
- https://redis.io/topics/cluster-tutorial
为了兼容现有的 Redis client
,还有一些 Redis Cluster Proxies
,如 redis-cluster-proxy(官方)、aster、corvus 和 samaritan,以使集群协议适应广泛支持的单实例协议。
- https://github.com/RedisLabs/redis-cluster-proxy
- https://github.com/wayslog/aster
- https://github.com/eleme/corvus
- https://github.com/samaritan-proxy/samaritan
Undermoon
是如何实现 “Redis Cluster Protocol”
的?
Undermoon
基于 server-side proxy
或 Server Proxy
实现 Redis Cluster Protocol
。Server Proxy
将像官方的 Redis Cluster Redis
一样工作,并在需要时返回重定向响应。
为什么要实现另一个 “Redis Cluster Protocol”?
该实现不仅支持水平可扩展性和高可用性,还使您能够构建一个自我管理的分布式 Redis
,支持:
Redis
资源池管理- 为不同的用户提供多个集群
- 将流量洪水均匀地传播到所有物理机
- 扩容迅速
- 操作和
Kubernetes
集成更容易。
为什么是 Server-side Proxy?
Redis
和大多数 redis
代理(如 redis-cluster-proxy
、corvus
、aster
、codis
)部署在独立的机器上,因为代理通常需要将请求分散到不同的 Redis
实例。
Server-side Proxy
不是路由请求,而是充当与这些代理不同的角色,类似于 Redis
的 cluster module
,通过使用一些定制的迁移协议,使其能够迁移数据
并快速扩展
。
Server-side Proxy
以下是 Server-side Proxy
和 Redis Cluster Protocol
的一小部分操作。
首先运行一个 redis-server
。
$ redis-server
构建并运行 server_proxy
,在端口 5299
上运行并将命令转发到 127.0.0.1:6379
。
> cargo build
> make server
代码语言:javascript复制> redis-cli -p 5299
# 通过 `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 节点
# 而不是同时显示主服务器和副本。
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
# 当我们使用 UMCTL SETCLUSTER 初始化它时,
# 插槽(slots) 8001-16383 属于另一个服务器代理 127.0.0.1:7000
# 所以我们得到一个重定向响应。
#
# 这是普通 Redis client 和 Redis Cluster client 的关键区别
# 因为我们需要处理重定向。
127.0.0.1:5299> get a
(error) MOVED 15495 127.0.0.1:7000
# Key 'b' 是该代理负责的,因此我们处理请求。
127.0.0.1:5299> set b 1
OK
更多
在 K8S 中快速部署 Redis Cluster & Redisinsight