ClickHouse 作为一款高性能的列式 OLAP 数据库,在 Java 开发中常用于 实时分析、大数据聚合、日志处理 等场景。以下是在 Java 中典型的 ClickHouse 使用场景及代码示例:
1. 实时数据分析与报表
场景特点
- 需要 低延迟(毫秒级) 响应复杂聚合查询(如 SUM/COUNT/GROUP BY)。
- 支持 高吞吐查询(如千人同时查看实时 Dashboard)。
Java 实现(JDBC 查询)
java
import java.sql.*;
public class ClickHouseJdbcDemo {
public static void main(String[] args) {
String url = "jdbc:clickhouse://localhost:8123/default";
String user = "default";
String password = "";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
String sql = "SELECT user_id, SUM(order_amount) " +
"FROM orders " +
"WHERE event_date >= '2023-10-01' " +
"GROUP BY user_id " +
"LIMIT 10";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getLong(1) + ": " + rs.getDouble(2));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
优化点:
- 使用
MergeTree
引擎 加速时间范围查询。 - 利用
ORDER BY
优化 GROUP BY 性能(ClickHouse 会利用排序数据加速聚合)。
2. 日志存储与分析(ELK 替代方案)
场景特点
- 每日 TB 级日志(如 Nginx、App 日志)的 高速写入 + 实时查询。
- 替代 Elasticsearch(ES)降低存储成本,提高聚合查询性能。
Java 实现(批量写入)
java
import ru.yandex.clickhouse.ClickHouseConnection;
import ru.yandex.clickhouse.ClickHouseDataSource;
import ru.yandex.clickhouse.settings.ClickHouseProperties;
public class ClickHouseBatchInsert {
public static void main(String[] args) {
String url = "jdbc:clickhouse://localhost:8123/logs";
ClickHouseProperties props = new ClickHouseProperties();
props.setUser("default");
props.setPassword("");
try (ClickHouseConnection conn = new ClickHouseDataSource(url, props).getConnection()) {
String sql = "INSERT INTO log_events (timestamp, user_id, action) VALUES (?, ?, ?)";
PreparedStatement stmt = conn.prepareStatement(sql);
// 批量写入 1000 条日志
for (int i = 0; i < 1000; i++) {
stmt.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
stmt.setInt(2, i % 100);
stmt.setString(3, "click_" + i);
stmt.addBatch(); // 加入批处理
}
stmt.executeBatch(); // 执行批量写入
} catch (SQLException e) {
e.printStackTrace();
}
}
}
优势:
- 写入速度极快(每秒百万级日志)。
- 存储成本低(列式压缩,比 ES 节省 5~10 倍空间)。
3. 用户行为分析(Flink + ClickHouse)
场景特点
- 实时计算 UV(独立用户)、PV(访问量)、转化率等指标。
- 替代 Hive + Spark 的离线计算,实现 秒级延迟。
Java + Flink 实时写入
java
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
public class FlinkToClickHouse {
public static void main(String[] args) {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
// 定义 ClickHouse Sink 表
String sinkDDL = "CREATE TABLE ch_sink (" +
" user_id INT," +
" action STRING," +
" event_time TIMESTAMP(3)" +
") WITH (" +
" 'connector' = 'jdbc'," +
" 'url' = 'jdbc:clickhouse://localhost:8123/default'," +
" 'table-name' = 'user_actions'," +
" 'username' = 'default'," +
" 'password' = ''" +
")";
tableEnv.executeSql(sinkDDL);
tableEnv.executeSql("INSERT INTO ch_sink SELECT user_id, action, event_time FROM kafka_source");
}
}
ClickHouse 优化:
- 使用
ReplacingMergeTree
自动去重(如用户多次点击只保留最新记录)。 TTL
(Time To Live) 自动清理过期数据。
4. 实时监控与告警
场景特点
- 处理 IoT 设备/Metrics 数据(如 CPU、内存、QPS)。
- 实时计算 P99 延迟、错误率,触发告警。
Java 查询 P99 延迟
java
String sql = "SELECT quantile(0.99)(latency) FROM service_metrics " +
"WHERE time > now() - INTERVAL 5 MINUTE";
// 如果 P99 > 500ms,触发告警
ClickHouse 优势:
quantile
函数 快速计算百分位数(比 MySQL/PostgreSQL 快 100 倍)。MATERIALIZED VIEW
自动预计算指标。
5. 广告/推荐系统分析
场景特点
- 分析用户点击、转化数据,优化推荐算法。
- 需要 JOIN 多张表(用户画像 + 行为日志)。
Java 实现(JOIN 查询)
java
String sql = "SELECT u.user_id, u.age, COUNT(c.click_id) " +
"FROM user_profiles u " +
"JOIN click_events c ON u.user_id = c.user_id " +
"WHERE c.event_date = '2023-10-01' " +
"GROUP BY u.user_id, u.age";
优化方案:
- 使用
JOIN
+ORDER BY
优化关联查询性能。 - 利用
DISTRIBUTED
表 实现分布式计算(适合超大规模数据)。
ClickHouse vs. 其他数据库
场景 | ClickHouse 优势 | 替代方案 |
---|---|---|
实时分析(OLAP) | 列存 + 向量化引擎,比 MySQL 快 100x | PostgreSQL(慢)、Doris(类似) |
日志分析 | 比 ES 存储成本低,聚合更快 | Elasticsearch(全文检索强) |
大数据 JOIN | 适合宽表,JOIN 性能优于 Hive | Spark SQL(更通用但延迟高) |
Java 集成最佳实践
-
使用 JDBC 驱动 :
xml<dependency> <groupId>ru.yandex.clickhouse</groupId> <artifactId>clickhouse-jdbc</artifactId> <version>0.3.2</version> </dependency>
-
批处理写入 :
- 用
PreparedStatement.addBatch()
提升写入性能。
- 用
-
异步查询 :
- 结合
CompletableFuture
实现非阻塞查询。
- 结合
总结
ClickHouse 在 Java 中的典型使用场景:
- 实时分析(JDBC 查询)
- 日志存储(高速写入 + 压缩存储)
- Flink 实时计算(替代 Spark 离线任务)
- 监控告警(P99 计算)
- 广告分析(多表 JOIN)
适用于 高吞吐、低延迟分析,但不适合高频单行查询(如 OLTP)。