返回博客
NestJSKafkaClickHouse数据分析

Kafka + ClickHouse 高性能分析实践 — 使用 NestJS 搭建模块化数据分析平台实践

RaytonX
1 min read

本文将介绍如何基于 NestJS 框架,搭建一个模块清晰、职责分明的数据分析平台。整体架构拆分为四大模块:

  1. 数据库封装模块(database:封装 ClickHouse、Kafka、RabbitMQ 等中间件连接
  2. API 服务模块(api:提供数据查询与分析任务提交接口
  3. 定时任务模块(scheduler:定期触发聚合分析任务
  4. 消费者模块(consume:处理 Kafka/RabbitMQ 异步数据写入

模块设计详解

1. API 模块

负责对外提供 HTTP 接口,核心功能包括:

  • 接收用户数据上报请求
  • 提交异步分析任务
  • 查询分析结果与任务状态

此模块通常作为网关服务部署,暴露统一接口入口。

2. Database 模块

封装所有数据库/中间件相关连接,统一提供如下服务:

  • ClickHouse:高性能列式数据库,用于分析型数据写入与查询
  • Kafka:高吞吐消息队列,用于异步任务投递
  • RabbitMQ:轻量级消息队列,用于短流程异步任务
  • MongoDB:用于存储配置或原始数据

DatabaseModule 设置为全局模块,便于跨模块复用连接池、日志与重试策略。

3. Scheduler 模块

用于执行定时任务,例如:

  • 每小时聚合用户活跃度
  • 每天清理过期数据、生成快照等任务

基于 @nestjs/schedule 模块实现,结合分布式锁避免多实例冲突。

4. Consumer 模块

后台服务,负责消费 Kafka 或 RabbitMQ 的消息,执行相应操作:

  • Kafka 中的数据上报消息解析后写入 ClickHouse
  • RabbitMQ 中的任务消息解析后执行计算逻辑

消费者通常为长驻进程,支持水平扩展。

服务配置与运行方式

模块独立入口设计

为保证服务解耦,每个模块配置独立启动入口:

  • API 服务:src/main.ts
  • 定时任务:src/main.scheduler.ts
  • 消费者服务:src/main.consumer.ts

package.json 配置示例

// package.json
{
  "scripts": {
    "build": "nest build",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "cross-env NODE_ENV=production node dist/src/main",
    "start:scheduler:dev": "nest start --entryFile main.scheduler --watch",
    "start:scheduler:prod": "cross-env NODE_ENV=production node dist/src/main.scheduler",
    "start:consumer:dev": "nest start --entryFile main.consumer --watch",
    "start:consumer:prod": "cross-env NODE_ENV=production node dist/src/main.consumer",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
  }
}

启动服务示例

# 启动 API 服务
pnpm start:dev

# 启动定时任务服务
pnpm start:scheduler:dev

# 启动消费者服务
pnpm start:consumer:dev

实践建议

  • 定时任务模块和消费者模块 不暴露 HTTP 接口,应部署为常驻进程服务
  • 使用 Redis 分布式锁 控制定时任务单点执行,避免并发冲突
  • API 和消费者模块可无状态部署,实现 水平扩展

总结

通过模块化架构 + NestJS 框架,我们可以快速构建一个高性能、易维护、可扩展的数据分析平台。结合 Kafka、ClickHouse、RabbitMQ 等组件,实现了数据的高效写入、定时分析、实时处理。