当前位置: 代码网 > it编程>编程语言>Java > Spring Boot 对接华为 MRS Redis 集群(密码认证)全流程实战

Spring Boot 对接华为 MRS Redis 集群(密码认证)全流程实战

2026年09月11日 Java 我要评论
一、背景与认证选型mrs 是华为云大数据平台,fusioninsight 是其私有化部署形态。mrs redis 基于开源 redis cluster 深度定制,接入层增加了安全认证机制:要求客户端提

一、背景与认证选型

mrs 是华为云大数据平台,fusioninsight 是其私有化部署形态。mrs redis 基于开源 redis cluster 深度定制,接入层增加了安全认证机制:要求客户端提供「用户名 + 密码」,经集群认证中心(kdc)校验后才允许读写,普通 redis 的"只填密码"玩法在这里行不通。

mrs redis 官方支持的客户端认证方式主要有三种:

认证方式说明适用场景
用户名密码(basic)认证用户名+密码向 kdc 换取票据,再 auth 认证spring boot + jedis,无需 keytab,本文方案
auth.conf 文件认证配置文件全局认证原生 jedis、老旧项目
kerberos keytab 认证keytab + gssapi sasl 握手等保合规要求高的环境

选型建议:新项目优先用用户名密码认证。只需在 fusioninsight manager 创建人机用户,把账号密码写入配置即可,不用准备 keytab 和 krb5.conf,接入成本最低。

二、版本选型:什么 mrs 配什么依赖

这是最先踩坑的地方——mrs 版本不同,配套的 jedis 制品、spring boot 版本甚至 jdk 都不同,混用必报错。

mrs 版本jedis(groupid:artifactid:version)spring boot / sdrjdk
3.5.xredis.clients:jedis:3.6.3-h0.cbu.mrs.350.r11(本地)/ .351.r22(服务器)boot 2.4~2.7 / sdr 2.x1.8
3.6.0redis.clients:jedis:5.2.0-h0.cbu.mrs.360.r9boot 3.x / sdr 3.4.9+17

三个结论:① mrs 定制 jedis 的 groupid 仍是 redis.clients,版本号带 h0.cbu.mrs 后缀,内含集群连接增强类;② mrs 3.6.0 官方样例基于 jdk 17,团队还在用 jdk 1.8 就选 mrs 3.5.x;③ spring-boot-starter-data-redis 不写版本号,交给 boot 父 pom 管理。

三、pom.xml 依赖配置

核心依赖三块:starter(排除 lettuce)+ mrs 定制 jedis + commons-pool2:

<properties>
    <jedis.version>3.6.3-h0.cbu.mrs.350.r11</jedis.version>
</properties>
<dependencies>
    <!-- 必须用 starter 并排除 lettuce -->
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-data-redis</artifactid>
        <exclusions>
            <exclusion>
                <groupid>io.lettuce</groupid>
                <artifactid>lettuce-core</artifactid>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- @slf4j 日志注解(config 代码用到;不用 lombok 可自行删除) -->
    <dependency>
        <groupid>org.projectlombok</groupid>
        <artifactid>lombok</artifactid>
        <optional>true</optional>
    </dependency>
    <!-- mrs 定制 jedis -->
    <dependency>
        <groupid>redis.clients</groupid>
        <artifactid>jedis</artifactid>
        <version>${jedis.version}</version>
    </dependency>
    <dependency>
        <groupid>org.apache.commons</groupid>
        <artifactid>commons-pool2</artifactid>
        <version>2.11.1</version>
    </dependency>
</dependencies>

三条纪律:必须用 spring-boot-starter-data-redis,单独引 spring-data-redis 不会触发自动装配,启动报 nosuchbeandefinitionexception;必须排除 lettuce,否则与 jedis 类冲突;不要额外声明 junit(starter-test 已包含)。

四、配置文件 application.properties

推荐 properties 格式(可规避 yaml 缩进坑):

# 集群节点,多个用逗号分隔,至少 1 个,其余自动拓扑发现
spring.redis.cluster.nodes=192.168.x.1:22400,192.168.x.2:22401,192.168.x.3:22402
server.port=9093
# ★ 密码认证核心配置
spring.redis.username=your_mrs_user
spring.redis.password=your_password
spring.redis.ssl=false
spring.redis.timeout=5000
# 连接池
spring.redis.jedis.pool.max-active=10
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.min-idle=2
spring.redis.jedis.pool.max-wait=2000

注意两点:① 端口规律:实例端口 = 22400 + 实例id - 1(r1→22400、r2→22401),节点信息可用 netstat -tlnp | grep redis-server 获取;② 若用 yaml,nodes 必须比 cluster 多缩进 2 格,否则解析成 spring.redis.nodes,报 could not resolve placeholder

五、核心难点:boot 2.x 的 noauth 缺陷

配置就绪后启动,大概率遇到经典报错:

noauth authentication required

根因不是账号密码错了,而是 boot 2.x 自动装配的 jedisconnectionfactory 创建集群连接时,内部 createcluster() 只把 password 传给 jedis,没有传 username;mrs redis 开启 acl 认证,要求两者同时提供,缺一即拒。

更棘手的是时序问题:bean 初始化时自动调用 afterpropertiesset(),此刻连接已建立并抛异常,bean 初始化中断;事后想补传 username 为时已晚。

解法:绕开自动装配,手动构建携带 username 的 jediscluster,再反射注入 jedisconnectionfactory:

@slf4j
@configuration
public class mrsredisconfig {
    @value("${spring.redis.cluster.nodes}") private string nodesstr;
    @value("${spring.redis.username}")      private string username;
    @value("${spring.redis.password}")      private string password;
    @value("${spring.redis.timeout:5000}")  private int timeout;
    @bean
    @primary   // ★ 覆盖 boot 自动装配的连接工厂
    public redisconnectionfactory redisconnectionfactory() throws exception {
        // 1. 解析节点
        set<hostandport> hosts = new hashset<>();
        for (string node : nodesstr.split(",")) {
            string[] hp = node.trim().split(":");
            hosts.add(new hostandport(hp[0], integer.parseint(hp[1])));
        }
        // 2. 连接池 + 空闲驱逐策略(避免空闲连接被服务端回收后 ping 超时)
        jedispoolconfig poolconfig = new jedispoolconfig();
        poolconfig.setmaxtotal(10);
        poolconfig.setminidle(2);
        poolconfig.settimebetweenevictionrunsmillis(30000);
        poolconfig.setminevictableidletimemillis(60000);
        poolconfig.settestwhileidle(true);
        // 3. ★ 关键:同时传 username + password
        defaultjedisclientconfig clientconfig = defaultjedisclientconfig.builder()
                .user(username).password(password)
                .connectiontimeoutmillis(timeout)
                .sockettimeoutmillis(timeout).build();
        // 4. 手动构建带用户名认证的 jediscluster
        jediscluster jediscluster = new jediscluster(hosts, clientconfig, 5, poolconfig);
        // 5. ★ 不调用 afterpropertiesset(),直接反射注入 cluster
        jedisconnectionfactory factory = new jedisconnectionfactory();
        field clusterfield = jedisconnectionfactory.class.getdeclaredfield("cluster");
        clusterfield.setaccessible(true);
        clusterfield.set(factory, jediscluster);
        log.info("mrs redis 集群连接工厂初始化完成");
        return factory;
    }
}

若你的项目是 boot 2.3.x + 老版 com.huawei.jredis:jedis-mrs:反射字段名是 configuration 而非 cluster(2.4+ 才是 cluster),且需额外处理 shardinfo 空指针,建议直接升级 boot 版本走本方案。

照抄提示:代码依赖 lombok @slf4j(见上文 pom);import 只需补全 jedisconnectionfactoryjedisclusterdefaultjedisclientconfighostandportjedispoolconfigset/hashsetjava.lang.reflect.field,ide 可自动导入。setmaxtotal(10) 等连接池参数若想从配置文件读取,给字段加 @value("${spring.redis.jedis.pool.max-active:10}") 即可,与第四节 properties 一一对应。

另注意:config/controller 必须放在启动类所在包(或其子包)内,否则组件扫描不到、自定义连接工厂不生效——症状是仍走自动装配,继续报 noauth。

六、controller 与联调验证

连接工厂就绪后 redistemplate 由 boot 自动装配,直接注入使用。boot 2.x 泛型为 redistemplate<object, object>(boot 3.x 才是 <string, string>),泛型不符会报 nosuchbeandefinitionexception。代码省略 import(@restcontroller/@autowired/@getmapping/redistemplate,ide 自动补全):

@restcontroller
public class rediscontroller {
    @autowired
    private redistemplate<object, object> redistemplate;  // boot 2.x 泛型
    @getmapping("/set")
    public string set() {
        redistemplate.opsforvalue().set("key", "value");
        return "success";
    }
    @getmapping("/get")
    public object get() {
        return redistemplate.opsforvalue().get("key");
    }
}

联调前先用 redis-cli 验证账号本身可用,排除网络因素:

/opt/hadoopclient/redis/bin/redis-cli -h <hostip> -p <port> -c --realm <realm> --user <username> -a <password>

应用启动后,日志出现 mrs redis 集群连接工厂初始化完成 即代表连接成功,随后 curl http://localhost:9093/set/get 验证读写。

七、常见问题速查表

报错根因解法
noauth authentication required建连只传 password 没传 username本文第五节方案
nosuchbeandefinitionexception单独引 spring-data-redis 或泛型不符用 starter;注入 <object,object>
could not resolve placeholderyaml 缩进错误 / properties 未打包nodes 比 cluster 多缩进 2 格;pom 显式声明 resources
jedisconnectionexception: auth failed用户名或密码错误核对 manager 人机用户
no reachable node in cluster网络不通 / ssl 开关不一致ping 节点,核对 spring.redis.ssl 与集群 redis_ssl_on 一致
nosuchfieldexception: clusterconfig老版本 jedis 字段名不同反射改用 configuration 字段

八、总结

一句话:绕开 boot 2.x 连接工厂的 acl 缺陷,用 defaultjedisclientconfig 把 username 和 password 完整传给 jediscluster。把握三点即可少走弯路:

  1. 版本对齐:mrs 3.5.x ↔ boot 2.4~2.7 + jdk 8;mrs 3.6.0 ↔ boot 3.x + jdk 17;
  2. 依赖纪律:starter-data-redis(排除 lettuce)+ mrs 定制 jedis,缺一不可;
  3. 认证纪律:用户名密码必须成对传递,任何"只传 password"的写法在 mrs acl 集群上必然失败。

本文代码整理自已在生产服务器验证的示例项目,希望能帮你顺利趟过 mrs redis 的"认证深水区"。

到此这篇关于spring boot 对接华为 mrs redis 集群(密码认证)全流程实战的文章就介绍到这了,更多相关spring boot 华为 mrs redis 集群内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com