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

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

摘要 :本文以真实项目为例,完整记录 Spring Boot 接入华为 MRS Redis 集群(用户名密码认证)的适配流程,覆盖依赖选型、配置编写、连接工厂定制、经典 NOAUTH 报错的根因与解法,以及联调验证方法。方案已在 MRS 3.5.1 集群实测通过,可直接复用。


一、背景与认证选型

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 / SDR JDK
3.5.x redis.clients:jedis:3.6.3-h0.cbu.mrs.350.r11(本地)/ .351.r22(服务器) Boot 2.4~2.7 / SDR 2.x 1.8
3.6.0 redis.clients:jedis:5.2.0-h0.cbu.mrs.360.r9 Boot 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:

xml 复制代码
<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 缩进坑):

properties 复制代码
# 集群节点,多个用逗号分隔,至少 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:

java 复制代码
@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 自动补全):

java 复制代码
@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 验证账号本身可用,排除网络因素:

bash 复制代码
/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 placeholder YAML 缩进错误 / 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 的"认证深水区"。

相关推荐
步行cgn1 小时前
Spring Boot 绑定嵌套 Bean 详解
java·spring boot·后端
AIGC小尼2 小时前
穿山甲 + 腾讯短剧短视频聚合广告平台|Android+SpringBoot+Vue+Docker 完整部署指南
android·vue.js·spring boot·聚合广告·广告平台·穿山甲广告·腾讯广告
●VON2 小时前
Flutter 鸿蒙插件适配实战:给 screen_security 补上截图与录屏防护
flutter·华为·harmonyos
William Dawson2 小时前
Spring Boot 接入华为 MRS ClickHouse(JDBC + 安全认证 + 负载均衡)实战
spring boot·redis·华为
摇滚侠10 小时前
《SpringBoot 3:入门与应用实战》第 12 章 JDBC 与事务 使用 JdbcTemplate 阅读笔记 32
spring boot·笔记·后端
思录Echo14 小时前
自助易AI数字人外挂技术剖析|如何解决政企智能客服的多端适配难题?
人工智能·华为·harmonyos
努力努力再努力wz15 小时前
【Redis入门系列】从 KEYS 到 SCAN:渐进式遍历、Cursor 与位反转原理
数据库·redis·缓存
互联网叫兽16 小时前
redis深入学习一
redis
沐沐师18 小时前
Redis 入门教程
redis·nestjs