前言:Apache ShardingSphere 作为践行 Database Plus 理念的数据服务平台,其包含数据分片、读写分离、数据加密、影子库等多种数据管理功能。
当 Apache ShardingSphere 应用于实际生产中,用户往往需要对其 SQL 链路进行监控,特别是在数据分片场景中,出现慢查询或执行异常时更加需要对 SQL 进行链路追踪协助分析排查问题,此时清晰了解 SQL 改写情况、执行情况就显得至关重要。
ShardingSphere-Agent 提供了链路追踪功能,帮助用户在使用 ShardingSphere-JDBC 或 ShardingSphere-Proxy 时进行调用链路分析 。本篇以 ShardingSphere-Proxy 为例,为大家讲解如何使用 ShardingSphere-Agent 实现链路追踪。
实现原理
基础概念
🌟 Span:基本工作单元,一次链路调用创建一个 span,使用唯一的 id 进行标识,span 中可以有其他的数据,比如描述信息,时间戳,key-value 对等自定义信息。
🌟 Trace:类似树结构的 span 集合,表示的是一条调用链路,存在唯一标识。在 ShardingSphere-Proxy 中对应一条逻辑 SQL 的完整执行链路。
Span | 描述 |
| 表示一条逻辑 SQL 执行的完整流程,并且可以查看执行逻辑 SQL 的耗时 |
| 解析阶段,可以查看 SQL 的解析耗时,和逻辑 SQL语句。(当使用 PreparedStatement 时无此 span ) |
| 执行阶段,此阶段会执行改写后的 SQL,可以查看执行耗时。(如果 SQL 无需在后端物理库执行,则无此 span) |
实战指南
ShardingSphere-Proxy 准备
✅ 下载 Proxy, 下载地址查看官网 [1]
✅ 在 MySQL 物理库下创建 demo_ds_0、demo_ds_1 作为后续使用的存储节点 ds_0、ds_1。
✅ 启动 Proxy,使用 MySQL 客户端工具连接到 Proxy,创建逻辑库 sharding_db,并使用 DistSQL 在该库下注册存储节点。(DistSQL(Distributed SQL)是 Apache ShardingSphere 特有的操作语言。它与标准 SQL 的使用方式完全一致,用于提供增量功能的 SQL 级别操作能力,详细使用可以参考 DistSQL 官网文档 [2])


创建表 t_order


上报到 Zipkin
部署 Zipkin,参考官网 [3]
配置 agent.yaml 导出数据到 Zipkin
plugins:
tracing:
OpenTelemetry:
props:
otel.service.name: "shardingsphere" # 配置的 service name
otel.traces.exporter: "zipkin" # 使用 zipkin exporter
otel.exporter.zipkin.endpoint: "http://localhost:9411/api/v2/spans" # zipkin 接收数据地址
otel-traces-sampler: "always_on" # 采样设置
otel.metrics.exporter: "none" # 关闭 OpenTelemetry metric 采集复制
停止 Proxy 后重新启动 Proxy 和 Agent(--agent 表示开启 Agent)
./bin/stop.sh
./bin/start.sh --agent复制
复制
使用 MySQL 客户端工具连接到 Proxy,并依次执行如下 insert、select、update、delete 语句。

访问 http://127.0.0.1:9411/zipkin/ (Zipkin UI 地址),此时可以查看到有 4 条链路数据,和执行的 SQL 数量一致。

insert into t_order_0 (order_id, user_id, address_id, status) VALUES (4, 4, 4, 'OK')
insert into t_order_2 (order_id, user_id, address_id, status) VALUES (2, 2, 2, 'OK')复制


insert into t_order_1 (order_id, user_id, address_id, status) VALUES (1, 1, 1, 'OK')
insert into t_order_3 (order_id, user_id, address_id, status) VALUES (3, 3, 3, 'OK')复制
复制




由于 t_order 表分为了 4 片,并且插入了 order_id 为 1 到 4 的数据,所以最终会在表 t_order_0、t_order_1、t_order_2、t_order_3 中各插入一条数据,也就会有 4 条 /shardingsphere/executesql/ span。最终显示的 SQL 链路和实际执行的结果一致,可以通过 span 清晰了解每个步骤执行的耗时,也可以通过 /shardingsphere/executesql/ span 知道逻辑 SQL 的具体执行情况。



上报到 Jaeger
部署 Jaeger,参考官网 [4]
部署 Proxy
agent.yaml 配置
plugins:
tracing:
OpenTelemetry:
props:
otel.service.name: "shardingsphere" # 配置的 service name
otel.traces.exporter: "jaeger" # 使用 jaeger exporter
otel.exporter.otlp.traces.endpoint: "http://localhost:14250" # jaeger 接收数据地址
otel.traces.sampler: "always_on" # 采样设置
otel.metrics.exporter: "none" # 关闭 OpenTelemetry metric 采集复制
停止 Proxy 后重新启动 Proxy 和 Agent(--agent 表示开启 Agent)
./bin/stop.sh
./bin/start.sh --agent 复制
登录 Proxy 在 sharding_db 库下执行 SQL 语句(和上报到 Zipkin 示例中执行的语句一致)
由于执行的 SQL 语句和上报到 Zipkin 示例中相同,所以链路数据也应是一致的,下面以 insert 语句的链路为例进行说明。

insert into t_order_0 (order_id, user_id, address_id, status) VALUES (4, 4, 4, 'OK')
insert into t_order_2 (order_id, user_id, address_id, status) VALUES (2, 2, 2, 'OK')复制
复制

insert into t_order_1 (order_id, user_id, address_id, status) VALUES (1, 1, 1, 'OK')
insert into t_order_3 (order_id, user_id, address_id, status) VALUES (3, 3, 3, 'OK')复制

采样率
plugins:
tracing:
OpenTelemetry:
props:
otel.service.name: "shardingsphere"
otel.metrics.exporter: "none"
otel.traces.exporter: "zipkin"
otel.exporter.zipkin.endpoint: "http://localhost:9411/api/v2/spans"
otel-traces-sampler: "traceidratio"
otel.traces.sampler.arg: "0.01"复制
复制
结语
🔗 参考
[1] ShardingSphere-Proxy 下载地址:https://shardingsphere.apache.org/document/current/cn/downloads/
[2] DistSQL 文档:https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/distsql/
[3] Zipkin 官网:https://zipkin.io/pages/quickstart.html
[4] Jaeger 官网:https://www.jaegertracing.io
[5] OpenTelemetry Exporters文档:https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure
[6] GitHub issue 列表:https://github.com/apache/shardingsphere/issues
[7] 中文社区:https://community.sphere-ex.com/复制