You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用rocket_db_pools连接Redis集群多节点时hmget报错的解决办法

问题分析与解决方案

问题根源

你遇到的错误码853本质是TLS握手失败,核心原因有两点:

  1. 当前使用的deadpool_redis::Pool是单节点连接池,无法处理Redis集群的节点重定向逻辑;
  2. Redis集群重定向时默认返回非TLS地址(redis://),但客户端配置了rediss://(TLS连接),导致连接其他节点时TLS握手失败;若仅入口节点开启TLS、其他节点未配置,也会触发该错误。

解决方案

方案一:修正客户端连接池配置(推荐)

改用集群专用连接池,强制所有节点走TLS连接:

  1. 修改连接池定义:
use rocket_db_pools::{deadpool_redis, Database};

#[derive(Database)]
#[database("redis_tests")]
pub struct TestRedisPool(deadpool_redis::ClusterPool); // 替换为集群专用连接池
  1. 更新Rocket.toml配置:
[default.databases.redis_tests]
# 填写所有集群节点的TLS地址,用逗号分隔
url = "rediss://<node1-ip>:6379,rediss://<node2-ip>:6379,rediss://<node3-ip>:6379"
# 强制启用TLS
tls = true
# 测试环境可临时跳过证书验证(生产环境禁用)
tls_skip_verify = true
  1. 确保依赖版本兼容:
    检查Cargo.toml中依赖版本匹配,示例配置:
redis = { version = "0.21.5", features = ["tls", "tokio-native-tls-comp", "async-std-tls-comp", "cluster"] }
deadpool-redis = { version = "0.10.2", features = ["cluster", "async-std"] }
rocket_db_pools = { version = "0.1.0-rc.2", features = ["deadpool_redis"] }

方案二:修改Redis集群配置(若有权限)

让所有集群节点开启TLS,并公告TLS地址,确保重定向时返回正确的rediss://格式地址:

  1. 每个节点的redis.conf添加以下配置:
# 启用TLS端口
tls-port 6379
# 配置证书文件路径
tls-cert-file /path/to/your/cert.pem
tls-key-file /path/to/your/key.pem
tls-ca-cert-file /path/to/your/ca.pem
# 公告节点公网IP和TLS端口
cluster-announce-ip <node-public-ip>
cluster-announce-tls-port 6379
# 可选:禁用非TLS端口,强制所有连接走TLS
port 0
  1. 重启所有Redis节点,必要时重新执行集群初始化操作。

方案三:手动配置集群连接池(灵活定制)

如果rocket_db_pools的Database宏无法满足需求,可手动创建并挂载集群连接池:

use rocket::fairing::{Fairing, Info, Kind};
use rocket::{Build, Rocket};
use deadpool_redis::{ClusterConfig, ClusterPool};
use redis::TlsConfig;

pub struct RedisClusterFairing;

#[rocket::async_trait]
impl Fairing for RedisClusterFairing {
    fn info(&self) -> Info {
        Info {
            name: "Redis Cluster Pool Initializer",
            kind: Kind::Ignite,
        }
    }

    async fn on_ignite(&self, rocket: Rocket<Build>) -> rocket::fairing::Result {
        // 配置集群节点和TLS参数
        let config = ClusterConfig {
            nodes: vec![
                "rediss://<node1>:6379".parse().unwrap(),
                "rediss://<node2>:6379".parse().unwrap(),
                "rediss://<node3>:6379".parse().unwrap(),
            ],
            tls: Some(TlsConfig::new().map_err(|e| rocket::fairing::Error::Custom(e.to_string()))?),
            ..Default::default()
        };
        // 创建集群连接池
        let pool = ClusterPool::new(config).map_err(|e| rocket::fairing::Error::Custom(e.to_string()))?;
        // 挂载到Rocket应用中
        Ok(rocket.manage(pool))
    }
}

// 启动Rocket时加载自定义Fairing
#[launch]
fn rocket() -> _ {
    rocket::build()
        .attach(RedisClusterFairing)
        .mount("/", routes![your_redis_handler])
}

验证方法

执行HMGET操作前,先通过CLUSTER NODES命令检查集群节点的公告地址是否为rediss://格式,确保客户端能正确识别并连接所有节点。

内容的提问来源于stack exchange,提问作者white-dog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:05:20