Skip to content

面试专题

This content is not available in your language yet.

面试重点不是背 RedisTemplate API,而是能解释连接所有权、序列化边界和消费语义。

先给答案:先确认连接归属,再确认序列化与消费语义

Section titled “先给答案:先确认连接归属,再确认序列化与消费语义”

RedisTemplate 的核心价值是把连接获取释放、命令回调和对象到字节的转换放在统一边界内;事务开启后,相关命令必须落到绑定的同一连接,提交或回滚时再由事务同步完成收尾。

排查数据问题要先看 serializer 是否一致,排查事务要看连接是否真正参与同步,排查消息则要区分 Pub/Sub 的在线即收与 Stream 的 pending/ack 状态。Lettuce 与 Jedis 被统一的是接口,不是线程模型和底层连接能力。

30 秒版:它用 callback 统一获取和释放连接,并在命令前后完成序列化和反序列化。

展开:核心逻辑在 core/RedisTemplate.java:397-427,连接来自 RedisConnectionUtils,callback 可获得代理连接,最后统一 release。

加分项:默认不暴露 native connection,createRedisConnectionProxy 位于 :545-550。

常见错答:说它只是 Redis 命令的门面,忽略了事务和资源生命周期。

30 秒版:二者实现 RedisConnectionFactory,上层只依赖 RedisConnection 和命令接口。

展开:接口坐标为 connection/RedisConnectionFactory.java:27-68;Lettuce 和 Jedis 各自负责 client、pool、Cluster 资源。

加分项:两者的 start/stop 都是生命周期边界,而不是每次命令创建客户端。

常见错答:认为 Spring Data Redis 直接把 Jedis API 暴露给模板。

30 秒版:Redis 只保存 bytes,serializer 决定数据格式、跨语言能力和兼容策略。

展开:RedisSerializer.java:31-104 定义最小契约;DefaultRedisSerializationContext.java:30-45 为 key/value/hash 分别持有 pair。

加分项:动态 JSON 类型由 GenericJackson2JsonRedisSerializer.java:301-316 解析,但有类型信任风险。

常见错答:只看 Java 泛型,不看真实 Redis bytes。

30 秒版:Pub/Sub 适合实时广播,离线期间消息不保留;Stream 有 ID、消费组和 pending 语义。

展开:Pub/Sub 用一个 subscriber 复用连接,见 listener/RedisMessageListenerContainer.java:73-90;Stream 使用 StreamPollTask 长轮询,见 stream/StreamPollTask.java:119-170。

加分项:Stream 的 latest offset 可能跳过轮询期间到达的消息。

常见错答:把 Pub/Sub 当作可靠队列。

不是。pipeline 在 RedisTemplate.java:447-511 批量发送并集中取回结果;MULTI/EXEC 在 :946-982 和连接同步器中提供事务队列与提交语义。

Redis 事务为什么需要绑定连接?

Section titled “Redis 事务为什么需要绑定连接?”

因为 MULTI 队列属于单个 Redis 连接。RedisConnectionUtils#doGetConnection 在 :126-181 通过 TransactionSynchronizationManager 绑定 holder,事务结束时 :401-425 统一 exec/discard 并解绑。

DefaultStreamMessageListenerContainer#stop 在 stream/DefaultStreamMessageListenerContainer.java:164-175 遍历取消订阅;任务在 StreamPollTask.java:84-87 委托给 poll state。

线上出现 Redis 连接泄漏,如何排查?

Section titled “线上出现 Redis 连接泄漏,如何排查?”

先确认是否绕过 RedisTemplate 直接获取连接,再检查 callback 是否自行关闭或异常路径是否跳过释放,重点看 RedisTemplate.java:425-427 与工厂 stop 实现。

核对 offset 选择、消费组 ACK、listener 异常策略和任务取消时机。不要默认使用 latest,接口文档已在 StreamMessageListenerContainer.java:80-82 提示其丢消息风险。

  • 业务更需要广播,还是需要可追踪、可重放的消费组?
  • Redis Cluster 下是否要求事务跨 key 原子?
  • serializer 是否有跨版本迁移方案?