Redis 监控与可观测性实战:生产运维全链路指南

Redis 生产监控与可观测性深度指南:涵盖核心指标告警、慢查询分析、延迟诊断(LATENCY DOCTOR)、Prometheus+Grafana 集成、Redis Insight 工具链、生产级 Alerting Rules 与 SLO 定义、CPU/内存排障、备份容灾与审计日志全链路

Redis 在生产环境中性能极高,但一旦出现问题往往是突发性的:内存瞬间耗尽导致 OOM、单条慢查询拖垮主线程、客户端连接数暴涨引发服务拒绝。监控与可观测性不是锦上添花,而是保障 Redis 持续可靠运行的底线工程。

本文从核心指标采集、慢查询与延迟诊断、Prometheus+Grafana 可视化、告警规则与 SLO 定义,到问题排障、备份容灾和审计日志,全方位构建一套可落地的 Redis 生产运维体系。


一、关键监控指标:四类核心维度

Redis 的监控指标应围绕性能、资源、可用性、数据质量四个维度展开。以下是每个维度必须采集的核心指标。

1.1 吞吐量与延迟:每秒操作数与响应时间

指标命令/来源说明
instantaneous_ops_per_secINFO stats每秒执行命令数,反映当前负载
keyspace_hits / keyspace_missesINFO stats命中/未命中次数,用于计算命中率
expired_keys / evicted_keysINFO stats过期/驱逐的键数量
cmdstat_*INFO commandstats各命令的调用次数与平均耗时

缓存命中率是 Redis 作为缓存最核心的业务指标:

命中率 = keyspace_hits / (keyspace_hits + keyspace_misses) × 100%

命中率低于 85% 通常意味着缓存穿透或缓存雪崩风险,低于 70% 则缓存基本失效。应在监控系统中将其作为一级告警指标。

1.2 内存使用:used_memory、used_memory_rss 与碎片率

指标来源监控意义
used_memoryINFO memoryRedis 实际使用的内存
used_memory_rssINFO memoryOS 实际分配的物理内存
used_memory_peakINFO memory历史峰值,容量规划依据
mem_fragmentation_ratioINFO memory碎片率 = RSS / used_memory
maxmemoryINFO memory配置上限

内存使用率公式:

内存使用率 = used_memory / maxmemory × 100%
  • < 70%:安全
  • 70%-85%:警戒,准备扩容
  • 85%:紧急,可能发生驱逐或 OOM

mem_fragmentation_ratio > 1.5 且持续上升,需要开启碎片整理或考虑重启实例。ratio < 1.0 则说明内存被交换到磁盘,性能会急剧下降。

1.3 客户端连接:连接数、阻塞与输出缓冲

指标来源说明
connected_clientsINFO clients当前连接数
blocked_clientsINFO clients被 BLPOP/BRPOP 等阻塞的客户端数
client_longest_output_listINFO clients输出缓冲最长的客户端
maxclients配置项最大允许连接数

connected_clients > maxclients × 80% 时触发扩容预警。client_longest_output_list 持续增大说明存在慢消费客户端,这类客户端可能因为网络差或处理慢,导致 Redis 需要为它们维护大量输出缓冲,最终占用过多内存。

1.4 持久化状态:RDB/AOF 进度与复制延迟

指标来源说明
rdb_last_bgsave_statusINFO persistence上次 RDB 状态
rdb_last_bgsave_time_secINFO persistence上次 RDB 耗时(秒)
aof_last_write_statusINFO persistence上次 AOF 写入状态
aof_current_size / aof_base_sizeINFO persistenceAOF 当前/基础大小
master_link_statusINFO replication主从连接状态
master_last_io_seconds_agoINFO replication上次与主节点通信时间

主从复制中,master_last_io_seconds_ago > 10 秒意味着从节点可能已经掉线或网络分区。如果配置了 min-replicas-to-write,主节点会拒绝写入,导致写入失败。


二、慢查询日志分析:定位性能瓶颈

慢查询日志记录执行耗时超过设定阈值的命令,是发现性能瓶颈的第一现场。

2.1 基础配置

# 记录超过 10ms 的命令
slowlog-log-slower-than 10000
# 保留最近 128 条记录
slowlog-max-len 128

slowlog-log-slower-than 的单位是微秒,生产线上建议设置为 10000(10ms)。对延迟极度敏感的业务可以设为 5000 或更低。注意 O(n) 命令如 KEYSSMEMBERSHGETALL 在大数据量下极易触发慢日志。

2.2 查询与分析方法

# 查看最近 10 条慢查询
SLOWLOG GET 10
# 获取慢日志条目数
SLOWLOG LEN
# 清空慢日志
SLOWLOG RESET

慢查询日志的返回格式包含:唯一 ID、执行时间戳、执行耗时、命令与参数数组、客户端信息。

示例:

redis> SLOWLOG GET 1
1) 1) (integer) 0
   2) (integer) 1723700000
   3) (integer) 15230        # 耗时 15.23 毫秒
   4) 1) "SMEMBERS"
      2) "large_set_key"      # 集合 key
   5) "192.168.1.10:54321"
   6) ""

2.3 慢查询高频模式与优化建议

高频导致慢查询的命令和场景:

场景典型命令根因解决方案
遍历大数据量KEYS pattern, HGETALL, SMEMBERS全量扫描或返回极大数据包改用 SCAN、分片读取、SSCAN
大 Key 操作LRANGE list -100000 -1List/Hash/ZSet 单个元素过大拆分大 Key、业务层分页
复杂聚合ZUNIONSTORE、SORT计算密集、中间结果大业务层异步预计算
过期键清理EXPIRE + 高写入主动过期或惰性过期集中触发分散 Key 过期时间、lazy-expire

smembers、hgetall 的替代方案:

# 用 SSCAN 分批获取
redis> SSCAN large_set_key 0 COUNT 100
# 用 HSCAN 分批获取 Hash
redis> HSCAN large_hash_key 0 COUNT 100
# 避免 KEYS,改用渐进式扫描
redis> SCAN 0 MATCH user:* COUNT 1000

对慢日志进行结构化分析时,建议收集到 Elasticsearch 或 Loki,按命令维度聚合统计 P99 耗时。


三、延迟监控:LATENCY DOCTOR 与实时延迟追踪

Redis 2.8.13 引入了延迟监控框架,能够追踪 16 种不同事件的延迟表现。

3.1 启用延迟监控

CONFIG SET latency-monitor-threshold 10
# 阈值为 10ms,超过该值的事件会被记录

latency-monitor-threshold 在生产环境建议设为 10ms,调试环境可设 1ms 以捕获更多事件。

3.2 常用诊断命令

# 查看不同类型事件的历史延迟统计
LATENCY LATEST
# 查看指定事件类型的延迟直方图
LATENCY HISTORY command
# 查看所有事件类型的延迟报告,按严重程度排序
LATENCY DOCTOR
# 重置所有延迟数据
LATENCY RESET

3.3 LATENCY DOCTOR 输出解读

127.0.0.1:6379> LATENCY DOCTOR
Dave, I have observed latency spikes in this Redis instance.
1. command: 15 ms latency spike (average 212 us) - 12 times over the last minute.
# Explanation: high command processing latency. Possible causes:
- Large collections of keys/commands in a single request.
- SLOW commands (KEYS, HGETALL, SORT, etc.).

LATENCY DOCTOR 会自动生成诊断建议,识别出延迟事件类型:

事件类型含义常见原因
command命令执行耗时高慢查询、大 Key、复杂计算
fork子进程 fork 耗时高内存大、AOF/RDB rewrite 时 fork
rdb-unlink-temp-fileRDB 临时文件删除大文件 unlink 阻塞
aof-writeAOF 写入阻塞磁盘 IO 瓶颈、sync 策略
exprie-cycle主动过期阻塞大量 Key 同时过期

fork 延迟是生产最常见的问题之一。 当 Redis 内存达到数十 GB 时,fork() 执行写时复制需要遍历页表,耗时可达到数百毫秒甚至数秒,这段时间主线程完全阻塞。监控 fork 延迟是容量规划的重要环节。


四、Prometheus + Grafana 集成:可视化监控面板

Prometheus 是 Redis 监控的事实标准。通过 redis_exporter 采集指标后,可以在 Grafana 中构建完整的监控面板。

4.1 redis_exporter 配置

# docker-compose.yml 示例
services:
  redis-exporter:
    image: oliver006/redis_exporter:latest
    command:
      - --redis.addr=redis://redis:6379
      - --redis.password=your_password
      - --check-keys=db0=mykey:*,db1=session:*
    ports:
      - "9121:9121"

Prometheus 的 scrape 配置:

scrape_configs:
  - job_name: 'redis'
    static_configs:
      - targets: ['redis-exporter:9121']
    scrape_interval: 15s

4.2 核心 Grafana Panel 配置

Panel 1: 实时 QPS

# 瞬时操作数
redis_instantaneous_ops_per_sec{instance=~"$instance"}
# 1分钟内的 QPS 变化率
rate(redis_commands_processed_total{instance=~"$instance"}[1m])

Panel 2: 内存使用率(百分比)

(redis_memory_used_bytes{instance=~"$instance"} / redis_memory_max_bytes{instance=~"$instance"}) * 100

Panel 3: 缓存命中率

(1 - (rate(redis_keyspace_misses_total{instance=~"$instance"}[5m]) / rate(redis_keyspace_hits_total{instance=~"$instance"}[5m]))) * 100

注意:当从无命中切换到命中时,需处理分母为零的情况。可添加条件:

(1 - (rate(redis_keyspace_misses_total[5m]) / clamp_min(rate(redis_keyspace_hits_total[5m]), 1))) * 100

Panel 4: 网络入/出流量

rate(redis_net_input_bytes_total{instance=~"$instance"}[1m])
rate(redis_net_output_bytes_total{instance=~"$instance"}[1m])

Panel 5: 客户端连接数

redis_connected_clients{instance=~"$instance"}
redis_blocked_clients{instance=~"$instance"}
redis_config_maxclients{instance=~"$instance"}

Panel 6: 慢查询趋势(需要 exporter 配置 –include-system-metrics)

若 redis_exporter 支持慢日志指标导出,PromQL 可统计慢查询出现频次。或者通过单独的日志采集管道(如 Promtail + Loki)聚合慢查询,在 Grafana 的面板中查询:

{job="redis-slowlog"} |= "SLOWLOG"

4.3 完整的 Grafana Dashboard JSON 片段

以下为一个关键面板的 JSON 片段,展示了内存使用率的 Gauge 面板配置:

{
  "id": 10,
  "title": "内存使用率",
  "type": "gauge",
  "targets": [
    {
      "expr": "(redis_memory_used_bytes / redis_memory_max_bytes) * 100",
      "legendFormat": "内存使用率 %",
      "refId": "A"
    }
  ],
  "fieldConfig": {
    "defaults": {
      "thresholds": {
        "mode": "absolute",
        "steps": [
          { "color": "green", "value": null },
          { "color": "yellow", "value": 70 },
          { "color": "orange", "value": 85 },
          { "color": "red", "value": 95 }
        ]
      },
      "unit": "percent",
      "min": 0,
      "max": 100
    }
  },
  "options": {
    "showThresholdLabels": true,
    "showThresholdMarkers": true
  }
}

建议 Dashboard 按节点维度提供 Variable,便于在面板中切换实例:

{
  "name": "instance",
  "type": "query",
  "query": "label_values(redis_up, instance)",
  "refresh": 1,
  "sort": 1
}

五、Redis Insight 与企业级监控工具

除了 Prometheus+Grafana 这套通用监控体系外,Redis 官方提供了更加垂直的工具链。

5.1 Redis Insight 功能概览

Redis Insight 是 Redis 官方的免费图形化管理与监控工具,支持单机、Sentinel、Cluster 三种部署模式。

核心功能包括:

  • Browser:树形浏览 Key,支持按数据类型筛选和搜索
  • Profiler:实时采集命令流,分析耗时分布和高频命令
  • 慢查询分析:自动发现并聚合慢查询,提供可视化分布
  • 内存分析:识别大 Key、内存占用排行榜、内存使用趋势
  • 实时监控:QPS、内存、网络、客户端的实时折线图
  • Workbench:支持编写和调试 Lua 脚本、RedisJSON、RediSearch 查询

Profiler 是 Redis Insight 最有价值的诊断功能。启用后它会在后台以 MONITOR 命令方式采集命令,以不影响正常服务的方式采样分析。Profiler 的结果可按命令类型、耗时、客户端 IP 等多个维度下钻分析。

5.2 CLI 实时分析命令

在没有图形化工具的环境中,原生命令同样强大:

# 实时命令监控(生产环境慎用,性能开销大)
redis-cli MONITOR | head -n 100

# 实时内存占用分析,按内存大小排序前 20 的 Key
redis-cli --memkeys-samples 1000 --bigkeys

# 采样内存分析,找出大 Key
redis-cli --hotkeys

5.3 企业级方案选择

工具适用场景成本
Redis Insight开发调试、单集群诊断免费
Prometheus+Grafana生产统一监控、告警开源免费
Redis Enterprise + Redis Cloud多云多集群统一管理、自动伸缩按需付费
Datadog/AppDynamics与应用监控深度集成SaaS 订阅

六、告警规则与 SLO 定义

监控的价值通过告警体现,而告警必须有明确的 SLO(Service Level Objective)支撑。

6.1 一级告警:立即响应

规则PromQL持续时间级别响应时间
实例不可达redis_up == 01mP05分钟
主从复制中断redis_master_link_up == 02mP05分钟
内存使用率 > 90%redis_memory_used / redis_memory_max > 0.95mP05分钟
客户端连接数 > 90%redis_connected_clients / redis_config_maxclients > 0.95mP115分钟
持久化失败redis_rdb_last_bgsave_status != 10m(立即)P130分钟
命中率 < 70%hit_ratio < 7010mP130分钟

6.2 二级告警:趋势预警

规则PromQL持续时间级别
内存日增长率 > 10%avg_over_time(delta(used)[1d]) / used > 0.11hP2
AOF 文件增长过快derivative(aof_size[1h]) > 100MB/h30mP2
碎片率持续 > 1.5mem_fragmentation_ratio > 1.54hP2
连接数持续增长delta(connected_clients[1h]) > 1001hP2

6.3 完整的 Alertmanager 规则 YAML

groups:
  - name: redis-alerts
    rules:
      - alert: RedisInstanceDown
        expr: redis_up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Redis 实例 {{ $labels.instance }} 不可达"
          description: "Redis 实例已宕机超过 1 分钟,请立即检查节点状态和网络连通性。"

      - alert: RedisMemoryHigh
        expr: |
          redis_memory_used_bytes / redis_memory_max_bytes > 0.85
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Redis 内存使用率过高: {{ $labels.instance }}"
          description: "内存使用率当前为 {{ $value | humanizePercentage }},超过阈值 85%。"

      - alert: RedisConnectionsHigh
        expr: |
          redis_connected_clients / redis_config_maxclients > 0.8
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Redis 连接数接近上限"
          description: "当前连接数 {{ $value | humanizePercentage }},接近最大连接数限制。"

      - alert: RedisReplicationBroken
        expr: redis_master_link_up == 0
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Redis 主从复制中断"
          description: "从节点 {{ $labels.instance }} 与主节点断开连接已超过 2 分钟。"

      - alert: RedisHighKeyEviction
        expr: rate(redis_evicted_keys_total[5m]) > 100
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Redis 驱逐率过高"
          description: "每分钟驱逐 Key 数超过 100,内存已达上限且淘汰策略正在高频剔除数据。"

      - alert: RedisHitRatioLow
        expr: |
          (
            rate(redis_keyspace_misses_total[5m]) /
            clamp_min(rate(redis_keyspace_hits_total[5m]), 1)
          ) > 0.3
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Redis 缓存命中率过低"
          description: "Miss 率超过 30%,缓存可能存在穿透或数据预热不足。"

      - alert: RedisAofRewriteProblem
        expr: redis_aof_last_rewrite_status != 1
        for: 0m
        labels:
          severity: warning
        annotations:
          summary: "Redis AOF rewrite 失败"
          description: "AOF 重写操作失败,可能导致 AOF 文件无限膨胀。"

6.4 SLO 定义建议

SLO 类型指标目标值测量周期
可用性redis_up99.9%月度
响应延迟命令 P99 延迟< 10ms每周
缓存命中率hit_ratio> 90%每周
数据持久化RDB/AOF 成功次数/总次数100%月度
复制延迟master_last_io_seconds< 1s每小时

七、故障排查:高 CPU、内存膨胀与响应变慢

生产中最常见的三类 Redis 故障是 CPU 飙高、内存膨胀和响应延迟异常。

7.1 CPU 100% 排查流程

Redis 是单线程的,CPU 100% 通常意味着主线程被长时间占用。

诊断步骤:

  1. 执行 INFO commandstats,找出 cmdstat 中 usec_per_call 最高的命令
  2. 检查 slowlog,确认是否有 KEYS、HGETALL 等消耗型命令
  3. 如果是高频简单命令,检查是否客户端使用了 MGET/MSET 的超大批次(如一次 MGET 数百个 Key)
  4. 检查是否有大量 Key 同时过期,触发主动过期(active expire)

排查命令:

# 查看各命令累计耗时与平均耗时
redis-cli INFO commandstats

# 输出示例
# cmdstat_get:calls=1000000,usec=1234567,usec_per_call=1.23
# cmdstat_keys:calls=100,usec=5000000,usec_per_call=50000.00
# 重点关注 usec_per_call 异常高的命令

缓解方案:

  • SCAN 替代 KEYS
  • UNLINK 替代 DEL(非阻塞删除)
  • 对大 Key 分批处理,避免单条命令阻塞
  • 分散 Key 的过期时间,避免集中过期

7.2 内存膨胀排查

内存使用量远超预期时,排查路径如下:

  1. 对比 used_memory 与 used_memory_rss,计算碎片率
  2. 执行 MEMORY DOCTOR 获取分析建议
  3. 使用 redis-cli --bigkeys 识别大 Key
  4. 检查是否存在大量过期但未删除的 Key(惰性过期积压)
  5. 检查客户端输出缓冲:INFO clients 中 client_longest_output_list 和 client_biggest_input_buf

MEMORY DOCTOR 输出示例:

127.0.0.1:6379> MEMORY DOCTOR
Hi Sam, I can't find any memory issue in your instance.
# 或者返回内存使用过多的具体原因

启用碎片整理:

# 开启主动碎片整理(Redis 4.0+)
activedefrag yes
# 达到 100MB 碎片才开始整理
active-defrag-ignore-bytes 100mb
# 碎片率达到 10% 才开始整理
active-defrag-threshold-lower 10
# 最多使用 25% CPU 整理碎片
active-defrag-cycle-max 25

7.3 延迟异常排查

redis-cli --latency 可以快速测量网络往返延迟:

# 测量即时延迟
redis-cli --latency -h 127.0.0.1 -p 6379
# 测量延迟历史分布
redis-cli --latency-history -i 1

如果网络延迟正常(< 1ms),服务端延迟高,按 LATENCY DOCTOR 的诊断结果处理。若所有事件都正常但请求仍然慢,则需排查:

  • 是否有大 Key 正在进行 UNLINK 的异步删除,导致后台 IO 线程争抢
  • AOF 每次写入调用 fsync(appendfsync always)时磁盘 IO 是否饱和
  • 是否正在进行 bgsave/AOF rewrite,fork 操作阻塞了主线程

八、备份与灾难恢复

8.1 RDB 备份策略

RDB 是全量快照,适合定时冷备份:

# 手动触发备份
redis-cli BGSAVE
# 备份文件位置
/var/lib/redis/dump.rdb
# 定期备份脚本
0 3 * * * cp /var/lib/redis/dump.rdb /backup/redis/dump-$(date +%Y%m%d).rdb

8.2 AOF 备份策略

AOF 文件包含所有写操作,数据完整性更高:

# AOF 重写时生成 clean 的 AOF 副本
redis-cli BGREWRITEAOF
# 在 AOF rewrite 完成后,拷贝新生成的 appendonly.aof

8.3 主从复制作为实时备份

部署至少一个异地从节点,即使主节点磁盘完全损坏,从节点仍持有实时数据副本。异地从节点应配置:

replicaof master_host master_port
replica-read-only yes
min-replicas-to-write 1
min-replicas-max-lag 10
appendonly yes

8.4 灾难恢复演练

定期执行恢复演练是保障 DR 方案有效性的唯一手段:

  1. 在测试环境用备份的 RDB/AOF 文件启动新 Redis 实例
  2. 验证数据一致性( Key 数量、采样数据校验)
  3. redis-check-rdbredis-check-aof 检查文件完整性
redis-check-rdb /backup/redis/dump-20260816.rdb
redis-check-aof --fix /backup/redis/appendonly.aof

8.5 备份生命周期管理

备份类型保留周期存储位置
每日 RDB7 天对象存储(S3/OSS)
每周全量30 天异地对象存储
每月归档365 天冷存储(Glacier/归档)
AOF 实时副本实时异地从节点磁盘

九、日志分析与审计追踪

9.1 Redis 日志配置

loglevel notice          # debug / verbose / notice / warning
logfile /var/log/redis/redis-server.log
# 开启审计日志(Redis 6.0+ ACL 支持)
aclfile /etc/redis/users.acl

日志级别建议:生产环境用 notice(默认),仅在排障时临时改为 verbosedebug

9.2 日志内容分析

Redis 日志的关键事件包括:

  • 连接事件:客户端连接、断开、认证失败
  • 复制事件:副本连接、全量同步、部分同步
  • 持久化事件:RDB save 开始/结束、AOF rewrite 开始/结束
  • 内存事件:达到 maxmemory、驱逐键数量
  • 配置加载:配置文件热重载(CONFIG RELOAD)

使用 rsyslog 转发至 ELK 堆栈:

# /etc/rsyslog.d/redis.conf
:programname, isequal, "redis-server" /var/log/redis/forward.log
& stop

然后通过 Filebeat 采集:

filebeat.inputs:
  - type: log
    paths:
      - /var/log/redis/redis-server.log
    fields:
      service: redis
      environment: production
output.elasticsearch:
  hosts: ["elasticsearch:9200"]

在 Kibana 中建立 Dashboard,关注:

  • errorwarning 级别的日志趋势
  • 认证失败次数(Failed authenticating
  • 连接拒绝次数(Max number of clients reached
  • 持久化失败事件

9.3 ACL 审计(Redis 6.0+)

开启 ACL 日志记录所有命令执行:

ACL LOG
ACL LOG RESET

ACL LOG 记录了谁在什么时间执行了什么命令、是否被允许、IP 地址等,是安全审计的核心数据来源。ACL 日志应定期导出到 SIEM 系统进行合规分析。

9.4 最小化日志的风险

注意 Redis 的日志不会记录命令参数(以免泄露敏感数据),慢查询日志同样不记录参数值(除非参数中包含 Key 名)。如需更细粒度的审计,需通过中间代理层或使用 Redis Enterprise 的审计模块。


十、总结与最佳实践

Redis 的可观测性体系是分层构建的:

  1. 指标层:Prometheus + redis_exporter采集 ops、内存、连接、复制四大维度,Grafana 可视化。命中率、内存使用率、连接数使用率是最关键的三个黄金指标。

  2. 日志层:Redis 原生日志记录运行事件,slowlog 记录慢查询,ACL LOG 记录权限审计。三套日志通过 Loki/ELK 统一收集分析。

  3. 追踪层:LATENCY DOCTOR 和 --latency --hist 提供事件级延迟追踪,Profiler 和 MONITOR 提供命令级追踪。

  4. 告警层:Alertmanager 分级告警(P0-P2),配合明确的 SLO(可用性 99.9%、P99 延迟 < 10ms、命中率 > 90%)驱动响应。

  5. 排障层:高 CPU 查慢查询与 commandstats,内存膨胀查 bigkeys 与碎片率,延迟异常查 LATENCY DOCTOR 和 fork/AOF 状态。

  6. 灾备层:RDB 定时冷备、AOF 增量保护、异地从节点实时热备三层备份策略,配合定期恢复演练。

一套完整的监控方案,能够让你从“Redis 挂了才知道”进化到“Redis 快要出问题时就提前干预”,这才是生产运维应有的水位。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「database」更多文章

  1. 缓存架构演进之路:从单机 Redis 到亿级分布式多级缓存体系
  2. Redis 7.x 重大新特性与架构升级深度解析
  3. Redis 消息队列深度对比:Pub/Sub、Streams 与 Kafka/RabbitMQ 选型指南