目录
1. ClickHouse 简介
什么是 ClickHouse?
ClickHouse 的优势和特点
适用场景
2. 安装 ClickHouse
3. ClickHouse 的基本概念
4. ClickHouse 的基本操作
创建数据库和表、插入和查询数据
使用 MergeTree 引擎处理时序数据
管理分区
创建带有分区的 MergeTree 表
添加新分区
删除旧分区
查询现有分区
合并分区
5. ClickHouse 与 Spring Boot 集成
6. 注意事项和常见问题
注意事项
常见问题
结语
1. ClickHouse 简介
什么是 ClickHouse?
ClickHouse 是一个用于实时数据分析的开源列式数据库,最初由俄罗斯的 Yandex 开发。它以高性能和卓越的可扩展性著称,专门用于高性能数据分析。它被设计用于大规模数据集的高速查询和分析,特别适用于 OLAP(联机分析处理)工作负载。
clickHouse官网:Fast Open-Source OLAP DBMS - ClickHouse
ClickHouse 的优势和特点
-
列式存储:ClickHouse 采用列式存储,将数据按列存储在磁盘上,有助于压缩数据以及优化分析查询性能。
-
高性能:ClickHouse 针对大数据量和高吞吐量进行了优化,能够在秒级内查询和分析数十亿行数据。
-
分布式架构:支持水平扩展和集群部署,能够处理大规模数据,并提供高可用性。
-
并行处理:能够同时利用多个 CPU 核心进行并行计算,提高查询处理速度。
-
实时数据分析:ClickHouse 支持实时数据导入和实时查询,适用于需要快速分析实时数据的场景。
-
灵活的查询语言:支持 SQL 查询语言,提供了丰富的查询功能,包括聚合、分组、排序等。
-
可扩展性:可轻松集成到现有的数据处理管道中,支持多种数据格式。
ClickHouse 被广泛应用于数据分析领域,特别适用于大数据量下的实时分析和报表生成等场景。其高性能和高度优化的列式存储特性使其成为处理大规模数据分析任务的理想选择。
适用场景
ClickHouse 是一个针对大规模数据分析和时序数据处理优化的开源列式数据库管理系统。下面列举一些较为常用的场景:
-
时序数据分析:
- ClickHouse 专注于时序数据,非常适用于处理时间序列数据,比如日志、传感器数据、监控数据等。
- 能够高效处理需要按时间序列进行快速查询和分析的大规模数据。
-
实时数据仓库(Real-time Data Warehouse):
- ClickHouse 可以作为实时数据仓库,支持高并发、高吞吐量的查询,适用于快速响应实时数据的分析查询需求。
-
分布式分析:
- 适用于大规模数据分析场景,支持分布式部署和高度扩展性,能够处理PB级别的数据规模。
-
大规模数据分析和报表:
- 用于生成报表、数据可视化以及对海量数据进行查询和分析。
-
日志和事件数据处理:
- 适用于处理大量日志和事件数据,支持对日志和事件数据进行快速的聚合、筛选和分析。
-
高性能时序数据存储:
- ClickHouse 的列式存储、数据压缩和查询优化,使其在存储大量时序数据时表现出色。
-
数据仓库存储:
- 作为数据仓库存储系统,适用于存储和分析大量结构化数据,支持复杂的数据查询。
-
大数据分析平台:
- 在大数据分析平台中作为存储层,为大数据计算提供支持。
2. 安装 ClickHouse
ubuntu 安装参考这篇:【入门篇】ClickHouse 的安装与配置_clickhouse 安装-CSDN博客
centos安装参考这篇:Linux(Centos7)下安装部署clickhouse(详细版)
3. ClickHouse 的基本概念
-
表(Table)
ClickHouse 中的表是数据存储的基本单元,使用列式存储。 -
列族(Column Family)
ClickHouse 的表可以按列族进行组织,相似类型的列可以组合在一起进行物理存储和压缩。 -
分区(Partition)
ClickHouse 支持根据分区键将数据分割成不同的分区,便于管理和查询。 -
引擎(Storage Engine)
ClickHouse 支持多种存储引擎,用于控制数据的存储方式和处理方法。 -
MergeTree
ClickHouse 最常用的存储引擎之一,专门用于处理时序数据的引擎。 -
MergeTree 索引(Index)
ClickHouse 使用 MergeTree 索引来加速查询操作。
4. ClickHouse 的基本操作
创建数据库和表、插入和查询数据
-- 创建数据库
CREATE DATABASE IF NOT EXISTS my_db;
-- 创建表
CREATE TABLE IF NOT EXISTS my_db.my_table
(
event_date Date,
event_time DateTime,
user_id Int32,
clicks Int32
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, event_time);
-- 插入数据
INSERT INTO my_db.my_table (event_date, event_time, user_id, clicks)
VALUES ('2023-12-31', '2023-12-31 23:59:59', 1, 10);
-- 查询数据
select * from my_db.my_table;
使用 MergeTree 引擎处理时序数据
在 ClickHouse 中,MergeTree 引擎非常适合处理时序数据,例如日志、性能指标数据、时间序列数据等。它是 ClickHouse 提供的一种用于存储有序数据并快速执行范围查询的引擎。以下是使用 MergeTree 引擎处理时序数据的示例:
-
创建带有 MergeTree 引擎的表
首先要创建一个带有 MergeTree 引擎的表。指定 ORDER BY
和 PARTITION BY
子句。
CREATE TABLE IF NOT EXISTS tb_metric(
timestamp DateTime,
value Float64
) ENGINE = MergeTree()
ORDER BY (timestamp)
PARTITION BY toYYYYMM(timestamp);
在这个示例中,创建了一个名为 tb_metric
的表,包含 timestamp
和 value
两个字段。表使用 MergeTree()
引擎,按照 timestamp
字段进行排序,并按年份和月份进行分区。
-
插入时序数据
INSERT INTO your_table (timestamp, value)
VALUES ('2023-12-01 10:00:00', 25.5),
('2023-12-01 10:05:00', 26.2),
('2023-12-01 10:10:00', 24.8),
...
-
查询时序数据
使用 MergeTree 引擎后,可以执行范围查询以获取特定时间范围内的数据。
SELECT *
FROM tb_metric
WHERE timestamp BETWEEN '2023-12-01 00:00:00' AND '2023-12-01 23:59:59';
该语句会检索tb_metric 表中 '2023-12-01' 这一天的所有数据,比如指标数据每分钟采集一次并进行存储,这个表的数据量会巨大,那么这个时候用此方式检索会比较快。
管理分区
在 ClickHouse 中,MergeTree 引擎支持对分区进行管理。分区管理可以根据时间范围、日期、月份等策略进行,以实现数据的有效存储和查询。以下是管理 MergeTree 表分区的基本操作:
创建带有分区的 MergeTree 表
和上面一样创建带有分区的 MergeTree 表,指定分区键和分区策略:
CREATE TABLE IF NOT EXISTS tb_metric(
timestamp DateTime,
value Float64
) ENGINE = MergeTree()
ORDER BY (timestamp)
PARTITION BY toYYYYMM(timestamp);
添加新分区
当数据到达新的时间范围时,需要为表添加新分区。ClickHouse 提供了 ALTER TABLE ... ATTACH PARTITION
语句来添加新分区:
ALTER TABLE your_table ATTACH PARTITION 202312;
删除旧分区
当不再需要某个时间段内的数据时,可以使用 ALTER TABLE ... DETACH PARTITION
语句删除旧分区:
ALTER TABLE your_table DETACH PARTITION 202301;
查询现有分区
要查看表中的所有分区,可以执行以下查询显示名为 tb_metric 的表的所有分区信息:
SELECT partition_id, partition
FROM system.parts
WHERE table = 'tb_metric';
合并分区
如果需要将两个分区合并为一个较大的分区以优化性能,可以使用 ALTER TABLE ... FREEZE PARTITION
来合并分区:
ALTER TABLE tb_metric FREEZE PARTITION 202310, 202311;
合理管理分区对于 ClickHouse 中处理大量时序数据是非常重要的,可以帮助优化查询性能和数据存储。
5. ClickHouse 与 Spring Boot 集成
ClickHouse JDBC 连接
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.3.1</version> <!-- 替换为最新的 ClickHouse JDBC 版本 -->
</dependency>
配置数据源
spring.datasource.url=jdbc:clickhouse://your_clickhouse_host:port/default
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=ru.yandex.clickhouse.ClickHouseDriver
示例代码
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class ClickHouseDAO {
private final JdbcTemplate jdbcTemplate;
public ClickHouseDAO(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<Object[]> executeQuery(String query) {
return jdbcTemplate.query(query, (rs, rowNum) -> {
// 处理结果集,返回数据
// 例如:return new Object[] { rs.getString("column1"), rs.getInt("column2") };
});
}
public int executeUpdate(String query) {
return jdbcTemplate.update(query);
}
}
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class ClickHouseController {
private final ClickHouseDAO clickHouseDAO;
public ClickHouseController(ClickHouseDAO clickHouseDAO) {
this.clickHouseDAO = clickHouseDAO;
}
@GetMapping("/query")
public List<Object[]> executeQuery() {
String query = "SELECT * FROM your_table";
return clickHouseDAO.executeQuery(query);
}
@GetMapping("/update")
public int executeUpdate() {
String query = "INSERT INTO your_table (column1, column2) VALUES ('value1', 123)";
return clickHouseDAO.executeUpdate(query);
}
}
或者使用mybatis的动态数据源
mysql的数据源配置:
# mysql 个性化配置, 不同的环境,需要配置不同的链接信息,只需要将这段信息复制到具体环境的配置文件中进行修改即可
spring:
datasource:
dynamic:
#默认数据源
primary: mysql
#严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
mysql:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.101.34:3306/refiner_dev?serverTimezone=CTT&characterEncoding=utf8&useUnicode=true&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&allowPublicKeyRetrieval=true
username: root
password: MySQL@123
ck的数据源配置:
spring:
datasource:
dynamic:
datasource:
clickhouse:
driver-class-name: ru.yandex.clickhouse.ClickHouseDriver
url: jdbc:clickhouse://192.168.101.35:8123/test
username: default
password: clickhouse
当需要使用clickhouse进行数据库表查询时,在service类或者mapper上指定@DS注解就可以用mybatis操作mysql一样使用ck了。
6. 注意事项和常见问题
在使用 ClickHouse 时,以下是一些注意事项和可能遇到的常见问题:
注意事项
-
数据模型设计: ClickHouse 适用于大规模数据分析和处理,设计数据模型时需考虑存储引擎、分区和数据类型,以最大程度地利用其性能。
-
硬件和性能: ClickHouse 需要大量的内存和计算资源来执行查询,因此在部署时需要考虑硬件资源。
-
数据复制和备份: 定期进行数据备份,并考虑数据的冗余备份,以防止数据丢失。
-
数据导入和导出: 使用优化的方法将数据导入到 ClickHouse 中,并选择合适的格式进行数据导出。
-
索引和优化: ClickHouse 使用不同的索引类型来优化查询,了解索引的使用方法可以提高查询性能。
-
版本和更新: 定期更新 ClickHouse 到最新版本,以获得新的功能、性能改进和 bug 修复。
常见问题
-
性能问题: 性能问题可能与查询的复杂性、硬件资源不足、数据模型设计不佳或查询优化有关。针对性能问题,需要对查询进行优化,增加硬件资源或重新设计数据模型。
-
数据丢失: 当 ClickHouse 节点出现故障或网络问题时,可能会导致数据丢失。为了避免数据丢失,需要实施数据备份和冗余策略。
-
连接问题: 网络故障或配置错误可能导致 ClickHouse 无法连接或无法访问。检查网络配置、防火墙设置以及连接字符串是否正确。
-
内存问题: ClickHouse 在处理大量数据时可能会出现内存问题。通过配置适当的内存参数和优化查询来解决内存问题。
-
版本兼容性: 当迁移到新版本的 ClickHouse 时,可能会遇到与之前版本不兼容的问题。在升级之前,查阅官方文档以了解可能的不兼容性变化。
-
异常处理: ClickHouse 查询中可能会出现各种异常,如语法错误、连接超时等。编写健壮的代码来处理这些异常情况,确保应用程序的稳定性和可靠性。
结语
clickHouse 是一个强大的列式分布式数据库管理系统,具有出色的性能、高效的列存储、适应大规模数据处理等特点。它在数据分析、时序数据处理和大规模数据查询方面表现优异。通过其优异的压缩算法和并行查询能力,ClickHouse 能够快速处理大规模数据,并支持复杂的查询和分析操作。其分布式架构使其能够轻松扩展以适应不同规模和需求的数据。
在使用 ClickHouse 时,需要考虑数据模型设计、分区策略、数据导入和查询优化等方面。针对特定的业务场景,可以选择合适的存储引擎和优化策略,以实现更高效的数据处理和查询操作。