Talivia架构深度剖析:ClickHouse+PostgreSQL+Redis+Kafka构建高吞吐分析引擎
【免费下载链接】taliviaOpen-source, self-hosted revenue-first analytics for founders: web analytics, Session Replay, revenue attribution, and customer revenue integrations. datafast alternative项目地址: https://gitcode.com/gh_mirrors/ta/talivia
Talivia 是一个开源、可自托管的"收入优先"(Revenue-first)分析平台,其架构用 ClickHouse 承载海量事件数据、PostgreSQL 管理业务实体、Redis 提供缓存与限流、Kafka 实现写入解耦,四者协同构成高吞吐分析引擎。本文带你用通俗的方式看懂这套架构的设计思路,以及每个组件在数据流中扮演的角色。
一、Talivia 是什么?📊
与普通网页统计工具不同,Talivia 的核心定位是把"流量"和"收入"连起来:
- Web Analytics:访客、会话、页面浏览、渠道来源(UTM / ClickID)
- Session Replay:会话回放,还原访客真实操作
- Revenue Attribution:将 Stripe、LemonSqueezy、Polar、Dodo、Yolfi 等支付渠道的收入归因到具体会话
- 高吞吐数据管道:事件采集 → 异步写入 → 预聚合 → 秒级查询
官方主界面预览:
二、总体数据流:一条事件的生命周期
先建立全局视角,一次"访客浏览页面"的数据旅程大致如下:
- 站点内嵌的 Tracking 脚本(src/tracker/index.js)采集事件,回传到 Next.js 的采集路由 src/app/(collect)/p/[slug]/route.ts
- 服务端校验后将事件批量写入ClickHouse的
website_event表;配置了 Kafka 时,事件先投递到 Kafka Topic,由消费端异步落库,把写入压力从 Web 进程剥离 - ClickHouse 的物化视图实时把原始事件预聚合为小时级统计表
- 仪表盘查询直接命中预聚合表;Redis 在中间层缓存热点结果并做接口限流
- 用户、网站、支付账户等"业务元数据"全部由PostgreSQL(Prisma ORM)管理
这套"OLAP 存事件 + OLTP 存业务"的组合,正是高吞吐分析引擎的关键。
三、PostgreSQL:业务数据的"账本" 📁
PostgreSQL 负责存放结构化、关系型、变更频繁的数据:
- 用户、角色、网站、站点协作者、分享链接(Boards / Links / Pixels)
- 支付服务商凭据与订阅状态、收入记录
- 数据库结构定义在 prisma/schema.prisma,迁移脚本按时间排序存放在 prisma/migrations/,例如 20260924181000_oss_installation_identity/
- 历史数据转换脚本放在 db/postgresql/data-migrations/,包括把收入回填到独立 revenue 表的
populate-revenue-table.sql
一句话定位:PostgreSQL 管"谁拥有哪个网站、收了多少钱"这类需要事务一致性的数据,它不背事件大表的性能压力。
四、ClickHouse:高吞吐分析引擎的核心 ⚡
ClickHouse 是 Talivia 的事件存储与查询引擎,客户端封装见 src/lib/clickhouse.ts。它的表设计(db/clickhouse/schema.sql)处处体现"为聚合查询而生"的思路:
4.1 事件主表:MergeTree + 按月分区
website_event表(schema.sql#L2-L69)采用经典三件套:
MergeTree引擎+PARTITION BY toYYYYMM(created_at):按月分区,查询某时间段只扫对应分区,旧数据可整分区快速删除- 排序键按"小时 + 网站 + 访客 + 会话"组织:
(toStartOfHour(created_at), website_id, visitor_id, session_id, created_at),保证同一访客的会话数据物理上连续,去重与聚合都走"顺序读" LowCardinality(String)标注浏览器、操作系统、国家等低基数列,大幅压缩存储- 常用维度(URL 路径、referrer 域名)还建立了Projection(schema.sql#L264-L277),相当于为高频查询预排一份数据副本,查询优化器自动选择
4.2 小时级物化视图:仪表盘秒开的关键 🚀
真正让仪表盘"秒开"的,是website_event_stats_hourly这张AggregatingMergeTree表 + 物化视图(schema.sql#L108-L262):
- 每次有新事件写入
website_event,物化视图实时按"小时 × 网站 × 会话 × 维度"预聚合出浏览量、首末页面、UTM 数组等 - 仪表盘的大多数聚合查询直接读这张小表,而不是扫描原始事件
- 表上声明了
SAMPLE BY cityHash64(session_id),未来数据量增长时可按比例抽样,查询代价可控
这就是典型的预聚合(Pre-aggregation)思想:把写路径上的 CPU 成本换来读路径上的极致速度。
4.3 其它专用表
session_data:ReplacingMergeTree+ EAV 结构,存会话级自定义属性(schema.sql#L90-L105)session_replay:会话回放分块存储,事件负载用CODEC(ZSTD(3))压缩(schema.sql#L315-L330)website_revenue:物化视图从事件数据中自动抽取 revenue / currency 字段,把"收入事件"沉淀为可分析表(schema.sql#L279-L312)
表结构演进通过 db/clickhouse/migrations/ 下编号 SQL 管理,由 scripts/migrate-clickhouse.ts 执行。
五、Kafka:写入解耦的"缓冲带" 📨
Talivia 把 Kafka 设计成可选组件:只有同时配置KAFKA_URL与KAFKA_BROKER时才启用(src/lib/kafka.ts#L14)。
- 生产者以
acks=1发送 JSON 事件,在吞吐与可靠性之间取平衡(src/lib/kafka.ts#L66-L91) - 支持 SASL/SSL 认证,适配托管 Kafka(src/lib/kafka.ts#L16-L51)
- 架构收益:采集端只做"轻投递",落库与重试压力转移到消费端;流量高峰时事件在 Topic 中缓冲,Web 进程不会被拖垮
中小规模部署可以不开 Kafka,直接写 ClickHouse;规模上来后开启 Kafka,代码路径自动切换——这正是该架构"渐进式扩容"的体现。
六、Redis:缓存、限流与轻量计数器
Redis 同样是可选组件(REDIS_URL),封装见 src/lib/redis.ts。它承担三类职责:
- 查询结果缓存:
fetch(key, query, time)模式先查缓存、未命中再查 ClickHouse 并回填,默认 TTL 3600 秒(src/lib/redis.ts#L84-L98),热点仪表盘面板的重复请求几乎零成本 - 接口限流:基于
INCR + EXPIRE的滑动窗口式限流rateLimit()(src/lib/redis.ts#L72-L82),保护采集端点 - 软删除标记:用
DELETED哨兵值缓存"已删除"状态,避免缓存穿透
七、三引擎查询层:一套接口,三种后端
Talivia 最有工程味的设计是查询路由。每个业务查询都提供 Prisma(PostgreSQL)与 SQL(ClickHouse)两套实现,统一由 src/queries/prisma/ 与 src/queries/sql/ 组织。运行时按环境变量选择后端(src/lib/db.ts#L22-L36):
export async function runQuery(queries: any) { if (process.env.CLICKHOUSE_URL) { if (queries[KAFKA]) return queries[KAFKA](); return queries[CLICKHOUSE](); } // 否则回落到 Prisma(PostgreSQL) }这个设计带来两个好处:
- 可降级:没有 ClickHouse 时整个产品依然可用(小规模自托管场景)
- 可对比:同一指标在 OLTP 与 OLAP 两种引擎下都有实现,方便验证数据一致性(项目中大量
*.test.ts覆盖此类语义)
八、收入归因:Talivia 的差异化引擎 💰
"分析 + 收入"的闭环依赖两条管线:
- 支付 Webhook 管道:Stripe、LemonSqueezy、Polar、Dodo、Yolfi 的 Webhook 分别由 src/lib/stripe-webhook.ts、src/lib/lemonsqueezy-webhook.ts 等处理,收入写入 PostgreSQL 的收入表,同时事件进入 ClickHouse 供归因分析
- 归因 Worker:scripts/talivia-attribution-worker.ts 后台作业结合首触/末触模型,把订单关联到访客会话,归因查询逻辑见 src/lib/attribution-query.ts
- 定时任务:生产环境由 src/instrumentation.ts 启动 Cron 调度器(src/lib/cron/),驱动数据回填与清理
九、本地跑起来:五分钟体验架构 ⏱️
官方用 Docker Compose 把最小依赖收敛为"App + PostgreSQL"两个容器(docker-compose.yml),ClickHouse、Kafka、Redis 通过环境变量按需接入。本地开发只需 Node.js 22/24 + pnpm,安装后执行 Prisma 迁移并启动,默认管理员账号为admin。完整的采集端点、实时接口(src/app/api/realtime/)与心跳健康检查(/api/heartbeat)都已内置,方便你观察整条数据链路。
十、总结:这套架构好在哪?
| 组件 | 角色 | 关键设计 |
|---|---|---|
| ClickHouse | 事件 OLAP 引擎 | 按月分区、排序键对齐会话、物化视图预聚合、Projection、ZSTD 压缩 |
| PostgreSQL | 业务 OLTP | 用户/网站/支付等元数据,Prisma 迁移管理 |
| Kafka | 写入解耦 | 可选组件,Topic 缓冲削峰,acks=1 平衡吞吐 |
| Redis | 缓存与限流 | 查询缓存 + TTL、INCR 限流、软删除哨兵 |
- 读写分离到极致:写路径轻(校验 → 投递),读路径快(预聚合 + 缓存)
- 渐进式扩容:PostgreSQL 单机可起步,ClickHouse / Kafka / Redis 按需开启,代码自动切换
- 可验证性:同一指标双引擎实现 + 完善的测试矩阵,架构演进有安全网
理解 Talivia 的架构,本质上就是理解一个通用模式:用 OLAP 吃掉事件洪峰,用 OLTP 守住业务一致性,用消息队列吸收流量毛刺,用缓存守住查询时延——这套组合拳正是"高吞吐分析引擎"的通用答案。
【免费下载链接】taliviaOpen-source, self-hosted revenue-first analytics for founders: web analytics, Session Replay, revenue attribution, and customer revenue integrations. datafast alternative项目地址: https://gitcode.com/gh_mirrors/ta/talivia
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考