RCProxy:轻快的 Redis 集群代理,使用 Rust 开发

1,213 阅读2分钟

为什么要开发

开始,使用 Rust 支持 Redis 集群的程序库直接连接集群,发现里面涉及多键的操作会报错,因为键没有被分配到一个 Slot 里面。

网上搜寻解决方案,推荐比较好的做法是在 Redis 集群前面搭建一层代理层,可以比较好的解决这个问题。

集群代理考察过多种方案,如下:

  • Redis 官方 redis-cluster-proxy:2020-4月后没维护了,很多问题,尝试时因为使用官方GUI客户端多输了个密码,导致服务爆掉了。因此不予采用。
  • 网易云信 Camellia:这两年开发的,积极维护中,功能较丰富。不过是基于Java开发的,比较吃内存,2G起步,考虑到测试环境服务器没这么多资源,因此不予采用。
  • B站Go版本的 Overlord:B站内部在用,维护一般,功能尚可。尝试时发现居然不支持连接时使用密码,考虑后为了服务的安全性还是放弃。
  • B站Rust版本的 Aster(github.com/wayslog/ast…):B站个人开发的,据说内部也在用,性能比Go版本高几倍,也不支持连接时使用密码,但应该比较好实现,所以决定对它进行定制开发。

最终,对 Aster 进行定制开发,实现了密码功能,仓库地址:github.com/clia/rcprox… 国内地址:gitee.com/clia/rcprox…

RCProxy 2.2 版本中,已能对 Redis 官方客户端 RedisInsight 提供完整支持了。

安装方式

把源代码拉取到服务器上,用 Rust 进行编译(编译该程序时内存会到4G左右,需要服务器内存大于4G)。

也可以直接从源代码仓库下载编译好的二进制程序。

从 default.toml 创建配置文件,更改里面的配置项,测试环境的配置内容如下:

# 日志配置
[log]
level = "libaster=info" # "trace" "info" "debug" "warn" "error"
ansi = true  # 支持 ANSI 颜色显示
stdout = false # 打印日志到 stdout
directory = "/var/log/rcproxy" # 日志文件目录
file_name = "rcproxy.log" # 日志文件名

# 测量服务配置
[metrics]
port = 2110

# 集群配置
[[clusters]]
name = "test-cluster"
listen_addr = "0.0.0.0:7788"
hash_tag = "{}"
thread = 1
cache_type = "redis_cluster"
servers = ["172.20.151.60:7001", "172.20.151.61:7001", "172.20.151.62:7001", "172.20.151.60:7002", "172.20.151.61:7002", "172.20.151.62:7002"]

fetch_interval = 1800000 # 1800s , 30 minutes
fetch_since_latest_cmd = 1000 # 3600s , 1 hour
read_from_slave = false

ping_fail_limit = 10
ping_interval = 300

read_timeout = 1000
write_timeout = 1000
dial_timeout = 500
listen_proto = "tcp"
node_connections = 1

auth = "mypasswd" # Redis密码,留空则忽略

直接运行,就可以把服务器跑起来了:

./rcproxy default.toml

如果要安装成 Linux 上的 systemd 服务,可以使用仓库里的 service 下的配置文件:

sudo cp ./target/release/rcproxy /usr/local/bin/
sudo mkdir /etc/rcproxy
sudo cp default.toml /etc/rcproxy/
sudo mkdir /var/log/rcproxy
sudo cp service/systemd/rcproxy.service /lib/systemd/system/
sudo systemctl enable rcproxy
sudo systemctl start rcproxy