首页
/ Hyperswitch Analytics 数据管道实战:Kafka + ClickHouse + OpenSearch(olap Profile)的部署与配置

Hyperswitch Analytics 数据管道实战:Kafka + ClickHouse + OpenSearch(olap Profile)的部署与配置

2026-09-05 17:11:43作者:戚魁泉Nursing

本篇指南基于 Hyperswitch 仓库内的官方文档 crates/analytics/docs/README.md,系统讲解如何用一条 Docker Compose 命令拉起 Kafka、ClickHouse、OpenSearch 三件套 OLAP 数据管道,如何切换 analytics.sourceevents.source 配置让分析查询走 ClickHouse、事件写入走 Kafka,如何开启外汇(Forex)汇率转换,以及如何在 Dashboard 中打开数据类功能、在 OpenSearch Dashboards 中完成索引模式配置。读完本文,你可以独立完成 Hyperswitch 本地 OLAP 环境的搭建、验证与排障,并能理解仓库中 crates/analytics 分析引擎与这些组件之间的实际调用关系。

一、架构总览:事件流从 Hyperswitch 到存储层

原文档给出了整条数据链路的架构图。Hyperswitch 主服务产生事件后先进入 Kafka 作为事件流 Broker;ClickHouse 侧则通过 Kafka Engine 表消费这些 topic,再由物化视图(Materialized View)落入真正的存储表:

     +------------------------+
     |       Hyperswitch      |
     +------------------------+
                |
                v
     +------------------------+
     |         Kafka          |
     |  (Event Stream Broker) |
     +------------------------+
                |
                v
     +------------------------+
     |  ClickHouse            |
     |  +------------------+  |
     |  | Kafka Engine     |  |
     |  |    Table         |  |
     |  +------------------+  |
     |            |           |
     |            v           |
     |  +------------------+  |
     |  | Materialized     |  |
     |  |    View (MV)     |  |
     |  +------------------+  |
     |            |           |
     |            v           |
     |  +------------------+  |
     |  | Storage Table    |  |
     |  +------------------+  |
     +------------------------+

这条链路在仓库源码中有完整的落点,可以逐一印证:

  • ClickHouse 建表脚本crates/analytics/docs/clickhouse/scripts/ 目录下共有 15 个 SQL 脚本,覆盖 payment_attemptspayment_intentsrefundsdisputespayoutsauthenticationsapi_eventsconnector_eventsfraud_checkrouting_eventssdk_eventsoutgoing_webhook_eventsprism_connector_eventsaccount_updater_events 等事件域。以 payment_attempts.sql 为例,脚本先建一张 Kafka Engine 表 payment_attempt_queue,再建存储表并挂 MV:
CREATE TABLE payment_attempt_queue (
    `payment_id` String,
    `merchant_id` String,
    `attempt_id` String,
    `status` LowCardinality(String),
    `amount` Nullable(UInt32),
    `currency` LowCardinality(Nullable(String)),
    `connector` LowCardinality(Nullable(String)),
    -- ... 其余字段省略
) ENGINE = Kafka SETTINGS kafka_broker_list = 'kafka0:29092',
kafka_topic_list = 'hyperswitch-payment-attempt-events',
kafka_group_name = 'hyper',
kafka_format = 'JSONEachRow',
kafka_handle_error_mode = 'stream';

可以看到 Kafka Engine 表的 kafka_broker_list 指向 kafka0:29092(即 compose 网络内 Kafka 的内部监听器),kafka_topic_list 与 Hyperswitch 配置中的 topic 名一一对应,消费组固定为 hyper,反序列化格式为 JSONEachRow。同一脚本中还定义了 CREATE MATERIALIZED VIEW ... TO <storage_table> 将队列数据写入存储表,以及一张 parse_errors 表用于承接解析失败的消息——这正是架构图里“Kafka Engine Table → MV → Storage Table”三段式的实现。

  • 分析引擎源码crates/analytics/src/ 下与数据源相关的实现分为 clickhouse.rsopensearch.rssqlx.rs 三条查询路径,并按事件域拆分为 payments/refunds/disputes/payouts 相关模块、auth_events/frm/sdk_events/ 等子模块(每个子模块包含 core.rsfilters.rsmetrics.rsaccumulator.rs)。也就是说,配置里的 analytics.source = "clickhouse" 决定的是这批分析 SQL 最终打到哪个存储后端。

二、启动容器:一条命令拉起 olap Profile

使用 Docker Compose 的 olap profile 启动全部 OLAP 组件:

docker compose --profile olap up -d

执行该命令后启动的完整服务集合(依据 docker-compose.yml 中挂载 olap profile 的服务定义)包括:

服务 镜像 暴露端口 说明
kafka0 confluentinc/cp-kafka:7.0.5 9092(宿主机)、29092(网络内) KRaft 单节点模式,启动时执行 monitoring/kafka-script.sh 初始化脚本
kafka-ui provectuslabs/kafka-ui:latest 8090 可视化查看 topic、分区、消费者与事件
clickhouse-server clickhouse/clickhouse-server:24.3 8123 HTTP 接口,/play 提供在线 playground
opensearch opensearchproject/opensearch:2 9200 单节点发现模式,初始管理密码 0penS3arc#
opensearch-dashboards opensearchproject/opensearch-dashboards:2 5601 数据查询与看板界面
vector timberio/vector:latest-debian 3103 等 日志/指标转发,读取 config/vector.yaml,环境变量 KAFKA_HOST 指向 kafka0:29092

两个值得注意的细节:

  1. ClickHouse 初始化脚本的自动注入:compose 中把 ./crates/analytics/docs/clickhouse/scripts 挂载到容器的 /docker-entrypoint-initdb.d。这意味着第一次启动 ClickHouse 时,上面提到的全部 Kafka Engine 表、MV、存储表会被自动建好,无需手工执行任何 SQL。
  2. Kafka 双监听器KAFKA_ADVERTISED_LISTENERS 同时暴露 PLAINTEXT://kafka0:29092(容器网络内,供 ClickHouse 消费)与 PLAINTEXT_HOST://localhost:9092(宿主机访问,供 Hyperswitch 本地进程写入)。这解释了为什么 ClickHouse 脚本里的 broker 地址是 kafka0:29092,而 Hyperswitch 配置里写的是 localhost:9092

三、Kafka 与 ClickHouse 的验证方式

Kafka-UI

Kafka-UI 是检查 Kafka 的可视化工具,访问 http://localhost:8090 即可查看各 topic、分区、消费者以及实际生成的事件内容,是验证 events.source = "kafka" 是否真正写入数据的第一选择。

ClickHouse Playground

ClickHouse 起来后有两种交互方式。其一,直接访问 ClickHouse 服务所在的 URL(默认 http://localhost:8123/play)使用内置 playground;其二,进入容器手动执行客户端:

# 本地终端
docker compose exec clickhouse-server bash

# clickhouse-server 容器 shell 内
clickhouse-client --user default

# clickhouse-client shell 内
SHOW TABLES;

SHOW TABLES 应当能看到与脚本对应的 payment_attemptspayment_attempt_queuepayment_attempts_mv(MV)、*_parse_errors 等对象。若某条链路没有数据,可优先检查对应的 parse_errors 表,其中记录了反序列化失败的原始消息。

四、配置 Analytics 与 Events Source

要让 Hyperswitch 真正使用 ClickHouse 和 Kafka,需要在配置文件中切换 analytics.sourceevents.source。修改 config/development.tomlconfig/docker_compose.toml 中对应段落:

[analytics]
source = "clickhouse"

[events]
source = "kafka"

仓库当前的默认值(以 config/docker_compose.toml 第 1272 行附近与第 1308 行附近为准)是:

[analytics]
source = "sqlx"            # 默认走 PostgreSQL 查询
forex_enabled = false

[events]
source = "logs"            # 默认事件只走日志,不写 Kafka

即默认形态下分析查询直接查主数据库(sqlx),事件不落 Kafka。改成 clickhouse / kafka 后,保存文件并重启应用即可生效。

Kafka topic 与 ClickHouse 索引名对照

[events.kafka] 段落(config/docker_compose.toml 第 1253–1270 行)定义了全部出站 topic,与 ClickHouse 建表脚本消费的 topic 完全对应:

[events.kafka]
brokers = ["localhost:9092"]
fraud_check_analytics_topic = "hyperswitch-fraud-check-events"
intent_analytics_topic = "hyperswitch-payment-intent-events"
attempt_analytics_topic = "hyperswitch-payment-attempt-events"
refund_analytics_topic = "hyperswitch-refund-events"
api_logs_topic = "hyperswitch-api-log-events"
connector_logs_topic = "hyperswitch-outgoing-connector-events"
outgoing_webhook_logs_topic = "hyperswitch-outgoing-webhook-events"
dispute_analytics_topic = "hyperswitch-dispute-events"
audit_events_topic = "hyperswitch-audit-events"
payout_analytics_topic = "hyperswitch-payout-events"
consolidated_events_topic = "hyperswitch-consolidated-events"
authentication_analytics_topic = "hyperswitch-authentication-events"
routing_logs_topic = "hyperswitch-routing-api-events"
revenue_recovery_topic = "hyperswitch-revenue-recovery-events"
external_service_call_topic = "hyperswitch-external-service-call-events"
account_updater_topic = "hyperswitch-account-updater-events"

其中 attempt_analytics_topic 的值 hyperswitch-payment-attempt-events 正是 payment_attempts.sql 中 Kafka Engine 表订阅的 topic,两处配置形成闭环。

OpenSearch 侧的索引配置

事件同时可写入 OpenSearch。config/development.toml[opensearch] 默认 enabled = false,指向 https://localhost:9200,基础认证用户 admin[opensearch.indexes] 定义了与 ClickHouse 相同语义的一套索引名(payment_attemptspayment_intentsrefundsdisputespayouts 及各自的 sessionizer_* 变体)。启用时把 enabled 置为 true 并按需调整 host(compose 网络内为 https://opensearch:9200,如 config/docker_compose.toml 第 1318 行所示)。

分析查询连接串

[analytics.clickhouse] 段落给出 ClickHouse 连接参数(config/docker_compose.toml 第 1276–1280 行):

[analytics.clickhouse]
username = "default"
# password = ""
host = "http://localhost:8123"
database_name = "default"

本地开发时保持 localhost:8123 即可;若 Hyperswitch 与 ClickHouse 同处 compose 网络,则应改为容器内可达的地址。

五、配置 Forex(汇率转换)API

分析模块可选开启汇率转换(forex_enabled),用于把多币种金额统一换算后做聚合统计。默认关闭:

[analytics]
forex_enabled = true # 默认 false

开启后需要向两个汇率服务商申请 API key,并填入配置文件:

  1. 主服务(Primary):注册免费账号获取主服务 API key,在服务商 dashboard 中该 key 以 app_id 名称展示。
  2. 备用服务(Fallback):注册免费账号获取备用 API key,在 dashboard 中该 key 以 access key 名称展示。

然后在 config/development.tomlconfig/docker_compose.toml 中填写:

[forex_api]
api_key = ""            # 主服务 key
fallback_api_key = ""  # 备用服务 key

[forex_api] 段还包含若干缓存相关参数(参考 config/docker_compose.toml 第 78–83 行),用于控制汇率数据的缓存与锁行为:

[forex_api]
api_key = ""
fallback_api_key = ""
data_expiration_delay_in_seconds = 21600   # 汇率数据缓存有效期(6 小时)
redis_lock_timeout_in_seconds = 100        # 拉取汇率时 Redis 锁的超时
redis_ttl_in_seconds = 172800              # 缓存条目 TTL(2 天)

常见报错:缓存锁无法获取

如果配置完成后日志出现如下错误:

ERROR router::services::api: error: {"error":{"type":"api","message":"Failed to fetch currency exchange rate","code":"HE_00"}}
│
├─▶ Failed to fetch currency exchange rate
│
╰─▶ Could not acquire the lock for cache entry

原因是 Redis 中残留了一个过期的缓存锁 key。在 Redis shell 中删除该 key 即可恢复:

redis-cli del "{forex_cache}_lock"

删除锁后重新发起请求,汇率拉取即可正常进入“加锁—请求 API—写缓存”的流程。所有 Forex 相关修改同样需要保存配置并重启应用才生效。

六、在 Dashboard 中启用数据功能

Dashboard 的数据类功能(审计、系统指标、全局搜索等)由 config/dashboard.toml[default.features] 控制。按原文档的示例打开:

[default.features]
audit_trail=true
system_metrics=true
global_search=true

对照仓库当前的 config/dashboard.toml[default.features] 中除上述三项外还有一批与分析数据消费直接相关的开关,可按需一并评估:

audit_trail = true            # 审计追踪(默认已开)
global_search = false         # 全局搜索
transaction_view = true
dispute_analytics = false     # 争议分析
authentication_analytics = false  # 3DS 认证分析
new_analytics = false         # 新版分析页
new_analytics_smart_retries = false
new_analytics_refunds = false
new_analytics_filters = false
routing_analytics = false     # 路由分析
sample_data_analytics = false

这些功能的数据来源正是本文前面配置的 ClickHouse/OpenSearch 管道:例如 new_analyticsrouting_analyticsdispute_analytics 对应的查询最终会经由 crates/analytics/src/ 中的分析模块(payments/routing_events/disputes/ 等)从已开启的存储后端读取聚合结果。若存储侧未启用(analytics.source = "sqlx" 且无 Kafka 写入),这些页面将没有实时数据可查。

七、在 OpenSearch Dashboards 中查看数据

事件写入 OpenSearch 后,按以下步骤在 Dashboards(http://localhost:5601)中完成首次配置:

  1. 进入 OpenSearch Dashboard 首页,点击 Management 标签下的 Dashboards Management
  2. 选择 Index Patterns
  3. 点击 Create index pattern
  4. 输入与你的索引匹配的模式名并点击 Next Step(例如 hyperswitch-payment-attempt-events,与 [opensearch.indexes]payment_attempts 的取值一致);
  5. 选择用于时间范围查询的时间字段;
  6. 保存该 index pattern。

之后切换到 OpenSearch Dashboards 标签下的 Discover 页面,选择刚创建的 index pattern 即可查询、过滤实际落入的事件数据,作为整条管道“Hyperswitch → Kafka → OpenSearch”的最终验证手段。

八、排查清单与仓库内参考路径

现象 排查点
ClickHouse 无数据 确认 [events] source = "kafka" 已生效;Kafka-UI(8090)看 topic 是否有消息;SHOW TABLES 后查对应 *_parse_errors
ClickHouse 报 broker 连不上 ClickHouse 脚本写的是 kafka0:29092,仅当 ClickHouse 与 Kafka 处于同一 compose 网络时可达
分析页面查不到数据 确认 [analytics] source = "clickhouse"[analytics.clickhouse] 连接串指向同一个实例
Forex 报 Could not acquire the lock for cache entry redis-cli del "{forex_cache}_lock" 后重试
OpenSearch 查不到事件 确认 [opensearch] enabled = true、host/账号密码正确,索引名与 [opensearch.indexes] 一致
Dashboard 数据功能缺失 检查 config/dashboard.toml[default.features] 开关

核心参考路径汇总:

小结

本文完整继承了 crates/analytics/docs/README.md 的实操脉络——docker compose --profile olap up -d 一键拉起 Kafka/ClickHouse/OpenSearch、analytics.source = "clickhouse"events.source = "kafka" 两个关键开关、Forex API 的接入与 {forex_cache}_lock 排障、Dashboard 功能开关与 OpenSearch index pattern 配置——并结合仓库源码补充了链路细节:15 个 ClickHouse 初始化脚本如何以 Kafka Engine 表 + 物化视图实现事件落库、[events.kafka] 中 16 个 topic 与存储表的一一对应关系、[forex_api] 缓存参数与 Redis 锁机制、以及 [default.features] 中各分析功能开关与 analytics crate 查询模块的对应关系。按本文操作,你可以在本地完整跑通 Hyperswitch 的 OLAP 分析数据管道,并具备从 topic、存储表、解析错误表到 Dashboard 页面的逐层验证能力。

登录后查看全文
热门项目推荐
相关项目推荐