news 2026/9/15 1:24:59

redis-py 原生 OpenTelemetry 集成指南:指标采集、分布式追踪与告警实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
redis-py 原生 OpenTelemetry 集成指南:指标采集、分布式追踪与告警实战

redis-py 原生 OpenTelemetry 集成指南:指标采集、分布式追踪与告警实战

【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-py

本指南以 docs/opentelemetry.rst 为核心骨架,系统讲解 redis-py 的 OpenTelemetry 可观测性能力:从 tracing 基础概念、原生指标集成(推荐方案)的安装与配置,到外部插桩、Uptrace 可视化、OpenTelemetry Collector 监控 Redis Server 以及告警规则编写。读完本文,你将能够为生产环境的 redis-py 应用一键接入标准化的指标采集与分布式追踪,并用源码级视角理解其内部工作原理。


1. OpenTelemetry 是什么

OpenTelemetry 是一个开源的可观测性框架,覆盖 traces(链路追踪)、metrics(指标)和 logs(日志)三大信号。它由 CNCF(Cloud Native Computing Foundation)托管,是 OpenCensus 与 OpenTracing 两个项目合并的产物。

其核心价值在于供应商无关(vendor agnostic):开发者只需插桩一次,之后可以随时新增或替换后端(如各种兼容 OpenTelemetry 的 APM 厂商),而无需改动业务代码中的插桩逻辑。采集到的遥测数据通过统一的 OpenTelemetry 协议(OTLP)导出,可供任意兼容后端消费。

2. 什么是 Tracing:从 Span 到 Trace

分布式追踪(Distributed Tracing)用于观察一个请求如何在多个服务和系统之间流转,记录每个操作的耗时、产生的日志以及发生的错误。在微服务架构中,追踪还能揭示服务之间的依赖关系与相互影响——某个微服务自身的性能问题如何传导到下游服务。

追踪把请求拆解为一个个Span(跨度)。一个 Span 代表应用处理请求时执行的一个操作单元(unit of work),例如一次数据库查询或一次网络调用。

Trace(追踪)是 Span 构成的树,展示请求在应用中的完整路径。树中的第一个 Span 称为Root Span(根跨度)

3. 原生 OpenTelemetry 集成(推荐方案)

redis-py 内置了对 OpenTelemetry指标采集的完整支持。相比外部插桩包,原生集成无需 monkey-patching,即可提供全面且细粒度的指标,因此是官方推荐的使用方式。

3.1 安装依赖

使用[otel]extra 安装原生支持所需依赖:

pip install redis[otel]

从仓库的 pyproject.toml 可以看到,该 extra 实际引入的依赖包括:

  • opentelemetry-api>=1.39.1
  • opentelemetry-sdk>=1.39.1
  • opentelemetry-exporter-otlp-proto-http>=1.39.1

3.2 基本设置:一次初始化,全客户端生效

在应用启动时初始化一次 OpenTelemetry 可观测性,之后所有 Redis 客户端都会自动采集指标,无需逐个客户端配置:

from opentelemetry import metrics from opentelemetry.sdk.metrics import MeterProvider from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter # 1. 设置 OpenTelemetry MeterProvider exporter = OTLPMetricExporter(endpoint="http://localhost:4318/v1/metrics") reader = PeriodicExportingMetricReader(exporter=exporter, export_interval_millis=10000) provider = MeterProvider(metric_readers=[reader]) metrics.set_meter_provider(provider) # 2. 初始化 redis-py 可观测性 from redis.observability import get_observability_instance, OTelConfig otel = get_observability_instance() otel.init(OTelConfig()) # 3. 正常使用 Redis —— 指标自动采集 import redis r = redis.Redis(host='localhost', port=6379) r.set('key', 'value') # 指标自动采集 r.get('key') # 4. 应用退出时关闭可观测性(冲刷待导出指标) otel.shutdown()

关键点说明:

  • PeriodicExportingMetricReader每 10 秒(export_interval_millis=10000)将累积指标导出到 OTLP HTTP 端点http://localhost:4318/v1/metrics,该端点通常是 OpenTelemetry Collector 或兼容后端(如 Uptrace、Jaeger)的监听地址;
  • MeterProvider 必须由应用先设置好,redis-py 复用全局 MeterProvider,而不是自建一套(见 providers.py 的模块注释)。

3.3 OTelConfig 配置选项:细粒度控制

OTelConfig类提供对指标采集的精细控制。其全部参数定义在 config.py:

from redis.observability import OTelConfig, MetricGroup config = OTelConfig( # 启用的指标组(默认:CONNECTION_BASIC | RESILIENCY) metric_groups=[ MetricGroup.CONNECTION_BASIC, # 连接创建耗时、relaxed timeout MetricGroup.CONNECTION_ADVANCED, # 连接等待耗时、超时、关闭的连接 MetricGroup.COMMAND, # 命令执行耗时 MetricGroup.RESILIENCY, # 错误计数、维护通知 MetricGroup.PUBSUB, # PubSub 消息计数 MetricGroup.STREAMING, # Stream 消息延迟 MetricGroup.CSC, # Client Side Caching 指标 ], # 过滤需要跟踪的命令 include_commands=['GET', 'SET', 'HGET'], # 只跟踪这些命令 # 或者 exclude_commands=['DEBUG', 'SLOWLOG'], # 跟踪除这些之外的所有命令 # 隐私控制 hide_pubsub_channel_names=True, # 在 PubSub 指标中隐藏频道名 hide_stream_names=True, # 在流式指标中隐藏流名 ) otel = get_observability_instance() otel.init(config)

各参数的源码级行为:

  • 命令过滤逻辑should_track_command,见 config.py):命令名统一转为大写后比较;include_commandsexclude_commands互斥生效——若设置了 allowlist 则仅跟踪列表内的命令,否则跟踪除 blocklist 外的全部命令;
  • 默认指标组CONNECTION_BASIC | RESILIENCY(见 config.py),即默认只开启连接基础指标与弹性指标;
  • 隐私开关实际在录制阶段生效:record_pubsub_messagerecord_streaming_lag在调用采集器前会把频道名/流名替换为None(见 recorder.py 与 recorder.py)。

3.4 可用指标组一览

Metric Group描述
CONNECTION_BASIC连接创建耗时、relaxed timeout、连接交接(handoff)
CONNECTION_ADVANCED连接等待耗时、超时、关闭的连接
COMMAND命令执行耗时
RESILIENCY错误计数、维护通知
PUBSUBPubSub 消息计数(发布/接收)
STREAMINGStream 消息延迟(XREAD/XREADGROUP)
CSCClient Side Caching(请求、驱逐、节省字节数)

MetricGroup在源码中使用IntFlag枚举实现(见 config.py),因此多个组可以按位或组合。上述每个组都对应 metrics.py 中RedisMetricsCollector.__init__里的一组仪器初始化分支。

3.5 可用指标明细

根据启用的指标组,采集以下指标(仪器定义见 metrics.py):

连接类指标(Connection Metrics)

  • db.client.connection.create_time—— 新建连接耗时(histogram,单位 s)
  • db.client.connection.timeouts—— 连接超时次数(counter)
  • db.client.connection.wait_time—— 从连接池获取连接的耗时(histogram,单位 s)
  • db.client.connection.count—— 当前连接数(按连接池、状态 idle/used 维度)
  • redis.client.connection.closed—— 累计关闭连接数(counter)
  • redis.client.connection.relaxed_timeout—— relaxed timeout 事件(up/down counter:放宽 +1,恢复 -1)
  • redis.client.connection.handoff—— 连接交接事件(counter,如收到 MOVING 通知后)

命令类指标(Command Metrics)

  • db.client.operation.duration—— 命令执行耗时(histogram,单位 s)

弹性类指标(Resiliency Metrics)

  • redis.client.errors—— 错误计数,按错误类型等属性细分(counter)
  • redis.client.maintenance.notifications—— 服务端维护通知计数(counter)

此外,源码中还定义了redis.client.geofailover.failovers(通过 MultiDbClient 发生的故障转移总数),与 MultiDB/地理故障转移功能配套使用。

PubSub 指标

  • redis.client.pubsub.messages—— 发布与接收的消息数(counter)

流式指标(Streaming Metrics)

  • redis.client.stream.lag—— 消息端到端延迟(histogram,单位 s)

Client Side Caching(CSC)指标

  • redis.client.csc.requests—— 缓存请求数,带 hit/miss 结果属性(counter)
  • redis.client.csc.evictions—— 缓存驱逐数(counter)
  • redis.client.csc.network_saved—— 通过缓存节省的网络字节数(counter,单位 By)
  • redis.client.csc.items—— 当前缓存大小(observable gauge)

版本演进提示(来自源码):文档中db.client.connection.count早期以 observable gauge 方式实现,但当前源码已改为push-based UpDownCounter跟踪(connection_count_updown,见 metrics.py);旧的 gauge 实现被标记为已弃用,指标名改为db.client.connection.count.deprecated,将在下一个主版本移除(见 metrics.py 的弃用说明)。如果你在生产中依赖该指标,建议以新实现为准。

3.6 自定义直方图桶边界

为获得更合适的统计粒度,可以自定义直方图桶(bucket)边界。源码中每个直方图都通过explicit_bucket_boundaries_advisory将配置透传给 OTel SDK(见 metrics.py):

config = OTelConfig( buckets_operation_duration=[0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1], buckets_connection_create_time=[0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5], buckets_connection_wait_time=[0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1], buckets_stream_processing_duration=[0.001, 0.01, 0.1, 1, 10], )

若不指定,源码默认值分别为:

  • 操作耗时桶(default_operation_duration_buckets,见 config.py):[0.0001, 0.00025, 0.0005, 0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5](秒)
  • 其余直方图桶(default_histogram_buckets,见 config.py):[0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10](秒)

3.7 上下文管理器用法:自动冲刷

需要自动清理时,使用上下文管理器模式——退出with块时会自动冲刷(force flush)待导出的指标:

from redis.observability import get_observability_instance, OTelConfig otel = get_observability_instance() with otel.get_provider_manager(): # 在此执行 Redis 操作 r = redis.Redis() r.set('key', 'value') # 退出时自动冲刷指标

get_provider_manager()返回OTelProviderManager(见 providers.py),其__exit__调用shutdown(),而shutdown()实际执行的是force_flush()——不会关闭应用拥有的全局 MeterProvider,只负责把待导出指标冲刷出去,避免与应用自身的 Provider 生命周期冲突。

3.8 错误处理:非侵入式设计

原生集成的设计目标是非侵入:所有指标录制函数都被 try-except 包裹,指标采集过程中发生的任何异常都不会影响 Redis 操作本身

从源码看,这一保证体现在两个层面:

  1. 录制函数(如 recorder.py 的record_operation_duration)在调用采集器时捕获所有异常并静默忽略;
  2. 存在快速路径(fast path)优化:若可观测性未初始化,_metrics_collectorNone,录制函数直接返回,几乎零开销(见 recorder.py)。即使初始化失败(例如 OpenTelemetry 未安装),_get_or_create_collector也会返回None而不抛错(见 recorder.py)。

另外需要注意:若指标已启用但应用未设置全局 MeterProvider,get_meter_provider()会抛出带完整指引的RuntimeError,提示必须先创建并设置MeterProvider(见 providers.py)。

4. 源码级原理:指标如何从客户端流向 OTel

理解原生集成,只需掌握三个层次的模块(均在 redis/observability 目录下):

① 单例入口层—— providers.py 中的get_observability_instance()返回全局单例ObservabilityInstanceinit(config)可安全重复调用(再次初始化前会先 shutdown 旧实例,见 providers.py)。它还提供reset_observability_instance()用于测试/基准场景重置全局状态。

② 采集器层—— metrics.py 中的RedisMetricsCollectorMETER_NAME = "redis-py"METER_VERSION = "1.0.0"从全局 Meter 创建仪器(Counter / Histogram / UpDownCounter / ObservableGauge),并根据metric_groups决定初始化哪些仪器。

③ 录制层(recorder)—— recorder.py 提供record_operation_durationrecord_connection_create_timerecord_error_countrecord_pubsub_messagerecord_streaming_lag等简洁 API,供 Redis 核心代码直接调用,无需了解 OTel 内部细节。

录制链路示例(以命令耗时为例):客户端执行命令时,在 client.py 的execute_command成功路径上调用record_operation_duration(command_name=..., duration_seconds=...);失败路径则调用record_error_count(...)(见 client.py)。录制函数内部解析出_metrics_collector后调用RedisMetricsCollector.record_operation_duration,后者通过should_track_command做命令过滤,再用AttributeBuilder(见 attributes.py)构建符合语义约定(semantic conventions)的属性集(db.system="redis"db.operation.nameserver.addresserror.type等),最终写入直方图。

属性构建遵循 OTel 数据库客户端语义约定(源码头部注释指向对应规范),例如基础属性固定包含db.system: redisredis.client.library: redis-py:v<版本号>(见 attributes.py),便于多语言、多客户端数据统一聚合。

异步客户端同样支持redis/asyncio/observability/recorder.py提供 async-safe 的录制 API,复用与同步端相同的RedisMetricsCollector与配置(见 redis/asyncio/observability/recorder.py),因此一次otel.init(OTelConfig())即可同时覆盖同步与异步客户端

仓库中还提供了完整的单元测试验证录制链路:tests/test_observability/test_recorder.py通过 mock MeterProvider,逐一验证各record_*函数是否正确地把参数透传给底层 OTel 仪器(Counter、Histogram、UpDownCounter),以及属性键是否符合语义约定。

5. 外部 OpenTelemetry 插桩(替代方案)

除原生集成外,也可以使用外部opentelemetry-instrumentation-redis包作为替代方案。该方案通过monkey-patching方式对 redis-py 进行插桩。

插桩(Instrumentation)是为流行框架和库开发的 OpenTelemetry 插件,用于记录重要操作(HTTP 请求、数据库查询、日志、错误等)。

安装:

pip install opentelemetry-instrumentation-redis

插桩用法:

from opentelemetry.instrumentation.redis import RedisInstrumentor RedisInstrumentor().instrument()

插桩完成后即可照常使用 redis-py,同步与异步客户端均受支持:

# 同步客户端 client = redis.Redis() client.get("my-key") # 异步客户端 client = redis.asyncio.Redis() await client.get("my-key")

两种方案的选择建议:原生集成不依赖对客户端内部方法的运行时补丁,指标更全面(覆盖连接池、PubSub、Streaming、CSC 等维度),且与库的演进同步维护,是官方推荐路径;外部插桩更轻量,适合只想快速获得命令级 tracing 的场景,但指标维度有限且依赖第三方包的维护节奏。

6. OpenTelemetry API 使用入门

OpenTelemetry API 是用于插桩代码并采集 traces、metrics、logs 遥测数据的编程接口。即使不借助插桩包,你也可以直接用它对关键操作进行手工埋点:

from opentelemetry import trace tracer = trace.get_tracer("app_or_package_name", "1.0.0") # 创建名为 "operation-name"、kind="server" 的 span with tracer.start_as_current_span("operation-name", kind=trace.SpanKind.CLIENT) as span: do_some_work()

用属性记录上下文信息:

if span.is_recording(): span.set_attribute("http.method", "GET") span.set_attribute("http.route", "/projects/:id")

监控异常:

except ValueError as exc: # 记录异常并更新 span 状态 span.record_exception(exc) span.set_status(trace.Status(trace.StatusCode.ERROR, str(exc)))

7. 用 Uptrace 可视化 redis-py 遥测数据

Uptrace 是一款支持分布式追踪、指标与日志的开源 APM 工具,可用于监控应用并配置自动告警,通过邮件、Slack、Telegram 等渠道接收通知。

仓库在 docs/examples/opentelemetry 提供了完整的 Uptrace 集成示例(含 docker-compose.yml、otel-collector.yaml 与 main.py)。运行步骤概览:

  1. 克隆仓库后进入docs/examples/opentelemetry目录;
  2. (可选)创建虚拟环境:python3 -m venv .venv && source .venv/bin/activate
  3. 安装依赖:pip install -e .(依赖见 requirements.txt);
  4. 用 Docker 启动 Redis 与 Uptrace:docker-compose up -d,并用docker-compose logs uptrace确认 Uptrace 已就绪;
  5. 运行示例:python3 main.py,随后按 CLI 输出的 trace 链接查看追踪(示例输出形如trace: http://localhost:14318/traces/...)。

示例main.py的核心逻辑(见 main.py):调用uptrace.configure_opentelemetry(...)配置导出端点,然后RedisInstrumentor().instrument()完成插桩,在handle_request中执行GET/SET/MSET及 pipeline 批量写入,并在自定义 span 内观察这些 Redis 命令的耗时。

8. 用 OpenTelemetry Collector 监控 Redis Server 性能

除了监控 redis-py 客户端,还可以用 OpenTelemetry Collector Agent 监控Redis Server 自身的性能

OpenTelemetry Collector 是应用与追踪/指标后端(如 Uptrace、Jaeger)之间的代理(proxy/middleman):它接收遥测数据、进行处理,再导出到能够持久化存储的 APM 工具。

例如,使用 Otel Collector 的OpenTelemetry Redis receiverredisreceiver)即可采集 Redis 服务端指标——包括内存使用、键命中率(keyspace hit rate)、连接数、命令处理速率等。仓库示例中docs/examples/opentelemetry/config/otel-collector.yaml演示了 Collector 的接收与导出管道配置,配合 docker-compose 即可一键拉起完整的采集链路。

9. 告警与通知配置

Uptrace 还支持基于 OpenTelemetry 指标配置告警规则(alerting rules)。以下 monitor 使用group by node表达式,当某个 Redis 分片(shard)宕机时触发告警:

monitors: - name: Redis shard is down metrics: - redis_up as $redis_up query: - group by cluster # 监控每个集群 - group by bdb # 每个数据库 - group by node # 每个分片 - $redis_up min_allowed_value: 1 # 分片需持续宕机 5 分钟才触发告警 for_duration: 5m

也可以编写更复杂的表达式。例如,当 keyspace 命中率低于 75% 时告警:

monitors: - name: Redis read hit rate < 75% metrics: - redis_keyspace_read_hits as $hits - redis_keyspace_read_misses as $misses query: - group by cluster - group by bdb - group by node - $hits / ($hits + $misses) as hit_rate min_allowed_value: 0.75 for_duration: 5m

这类告警依赖redis_upredis_keyspace_read_hits等由 Redis receiver 导出的服务端指标,可与客户端指标互为补充:客户端指标反映调用侧体验,服务端指标反映实例侧健康状况。

10. 下一步学习方向

在打通 redis-py → OTel → 后端的采集链路后,可以进一步:

  • 学习为应用配置uptrace-python,把 spans、metrics、logs 统一导出到 Uptrace;
  • 将本文的指标采集与应用的 Web 框架(如 Django、Flask、FastAPI)及 ORM(如 SQLAlchemy)的 OpenTelemetry 插桩结合,构建覆盖 HTTP 入口 → 业务逻辑 → Redis 调用的完整调用链;
  • 深入阅读本仓库源码:指标定义见 redis/observability/metrics.py,配置解析见 redis/observability/config.py,录制 API 见 redis/observability/recorder.py,属性语义约定见 redis/observability/attributes.py;
  • 参考测试用例 tests/test_observability/test_recorder.py 与 tests/test_observability/test_cluster_metrics_error_handling.py,理解各指标录制与异常场景的处理方式。

【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-py

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 1:23:20

一物一码吸粉红包系统开发:公众号授权、微信支付与防刷设计

简介&#xff1a;这是一套基于微信公众平台的一物一码吸粉红包系统源码&#xff0c;版本V3.2.2全开源&#xff0c;面向需要做O2O营销、门店引流和粉丝裂变的运营者或开发者。通过批量生成二维码红包&#xff0c;可将其嵌入海报、传单、产品包装或活动现场&#xff0c;顾客扫码即…

作者头像 李华
网站建设 2026/9/15 1:22:41

Ubuntu22.04下安装配置IsaacLab 2.2机器人仿真平台

1. 项目概述IsaacLab 2.2是NVIDIA推出的机器人仿真开发平台&#xff0c;基于强大的物理引擎和AI工具链构建。作为Isaac Sim的轻量级版本&#xff0c;它特别适合在Ubuntu22.04 LTS系统上进行机器人算法开发和测试验证。我在最近三个机器人项目中都采用了这个组合方案&#xff0c…

作者头像 李华
网站建设 2026/9/15 1:22:03

Flutter地图组件鸿蒙化适配实战与性能优化

1. 项目背景与核心价值Flutter开发者最近在跨平台开发中遇到一个关键痛点&#xff1a;当应用需要同时兼容Android、iOS和鸿蒙系统时&#xff0c;地图组件的统一处理变得异常复杂。m_map作为Flutter生态中一个功能强大的三方库&#xff0c;提供了嵌套合并、动态路径查找等高级Ma…

作者头像 李华
网站建设 2026/9/15 1:21:38

计算机系统课程作业:汇编编程与缓冲区溢出实践

1. 作业背景与核心要求解析计算机系统课程作为计算机专业的核心基础课&#xff0c;其课后作业往往聚焦于计算机底层原理的实践验证。从"HNU_计算机系统_第二次课后作业"这个标题可以拆解出几个关键信息点&#xff1a;课程层级&#xff1a;这是计算机专业本科二年级左…

作者头像 李华
网站建设 2026/9/15 1:21:25

Agent记忆去重与更新策略实战指南

我实测过太多次Agent记忆出问题的场景了——刚聊完“下周三开会”&#xff0c;转头又问“会议时间定好了吗”&#xff1b;用户明确说“我不吃香菜”&#xff0c;下一轮却推荐了香菜拌牛肉&#xff1b;更离谱的是&#xff0c;同一段对话被存了三次&#xff0c;每次timestamp差20…

作者头像 李华
网站建设 2026/9/15 1:20:07

工业串口通信不稳定五大物理根源与实战整改

1. 工业现场的真实痛点&#xff1a;不是设备坏了&#xff0c;是“通信在装死”你有没有遇到过这样的场景&#xff1a;一台PLC通过RS485总线连接6台温控器&#xff0c;上位机软件每分钟轮询一次数据&#xff0c;前半小时一切正常&#xff0c;第32分钟开始&#xff0c;某台温控器…

作者头像 李华