一、简介
官方文档写的很详细,可以下简略阅读官方文档,简单来讲,ClickHouse 是一个高性能、高可用性、分布式列式数据库管理系统,便于对大量数据进行查询和分析数据,笔者公司是用来做日志的存储并方便给运维人员查询,之前用mysql查询一次日志要很久
二、安装
1. 安装前准备
安装clickhouse需要依赖jdk和zookeeper,可以参考笔者之前的文章,JDK1.8安装和zookeeper的安装和简单使用,我之前启动的zookeeper是三个节点,这里打算在三台机器同时安装,每台分为两个副本,因此需要同时打开三个命令行窗口,并开启同时输入
2. 安装,配置修改,启动
tar -zxvf clickhouse-common-static-21.9.7.2.tgz -C /home/gmy/tools/clickhouse/
tar -zxvf clickhouse-common-static-dbg-21.9.7.2.tgz -C /home/gmy/tools/clickhouse/
tar -zxvf clickhouse-server-21.9.7.2.tgz -C /home/gmy/tools/clickhouse/
tar -zxvf clickhouse-client-21.9.7.2.tgz -C /home/gmy/tools/clickhouse/
首先从简单的开始安装,分别进入clickhouse-common-static、clickhouse-common-static-dbg和clickhouse-client文件夹下的install文件夹下,执行安装,./doinst
其次进行最重要的server的安装,由于每台机器要启动两个副本,所以需要修改许多配置,进入clickhouse-server文件夹下的/etc/clickhouse-server
文件夹,编辑配置文件,vi config.xml
,主要注意如下配置
端口
<http_port>8123</http_port>
<tcp_port>9000</tcp_port>
<mysql_port>9004</mysql_port>
<postgresql_port>9005</postgresql_port>
<interserver_http_port>9009</interserver_http_port>
日志存储
<log>/app/data/clickhouse/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/app/data/clickhouse/log/clickhouse-server/clickhouse-server.err.log</errorlog>
开放连接
<!-- <listen_host>::</listen_host> -->
<listen_host>::</listen_host>
数据存储
<path>/app/data/clickhouse/data/</path>
<tmp_path>/app/data/clickhouse/tmp/</tmp_path>
<user_files_path>/app/data/clickhouse/user_files/</user_files_path>
<path>/app/data/clickhouse/access/</path>
<top_level_domains_path>/app/data/clickhouse/top_level_domains/</top_level_domains_path>
<format_schema_path>/app/data/clickhouse/format_schemas/</format_schema_path>
zookeeper设置
<zookeeper>
<node>
<host>192.168.136.128</host>
<port>2181</port>
</node>
<node>
<host>192.168.136.128</host>
<port>2182</port>
</node>
<node>
<host>192.168.136.128</host>
<port>2183</port>
</node>
</zookeeper>
集群设置,共三分片六副本
<ck_cluster>
<shard>
<replica>
<host>10.1.198.191</host>
<port>9000</port>
<user>default</user>
<password>root</password>
</replica>
<replica>
<host>10.1.198.192</host>
<port>29000</port>
<user>default</user>
<password>root</password>
</replica>
</shard>
<shard>
<replica>
<host>10.1.198.192</host>
<port>9000</port>
<user>default</user>
<password>root</password>
</replica>
<replica>
<host>10.1.198.193</host>
<port>29000</port>
<user>default</user>
<password>root</password>
</replica>
</shard>
<shard>
<replica>
<host>10.1.198.193</host>
<port>9000</port>
<user>default</user>
<password>root</password>
</replica>
<replica>
<host>10.1.198.191</host>
<port>29000</port>
<user>default</user>
<password>root</password>
</replica>
</shard>
</ck_cluster>
宏名称设置
<macros>
<!--层级-->
<layer>web_logs</layer>
<!--分片-->
<shard>01</shard>
<!--副本-->
<replica>rep-01-01</replica>
</macros>
然后复制一份做从配置,cp -p config.xml config-slave.xml
,并注意修改端口、存储位置、分片信息等
<http_port>28123</http_port>
<tcp_port>29000</tcp_port>
<mysql_port>29004</mysql_port>
<postgresql_port>29005</postgresql_port>
<interserver_http_port>29009</interserver_http_port>
宏名称设置
<macros>
<!--层级-->
<layer>web_logs</layer>
<!--分片-->
<shard>03</shard>
<!--副本-->
<replica>rep-03-02</replica>
</macros>
在 ClickHouse 中,macros标签可以用于定义宏(Macros),可以在表的定义中使用这些宏,从而方便地对表进行管理和维护。
其中,layer、shard 和 replica 是 ClickHouse 中用于管理集群中表的三个重要参数,它们的含义如下:
-
layer:层级,用于将集群中的表按照逻辑层次进行划分。一般来说,一个 ClickHouse 集群中可以有多个层级,每个层级可以包含多个表,层级之间一般是相互独立的。例如,可以将不同的应用程序或业务逻辑划分到不同的层级中,以方便管理和维护。
-
shard:分片,用于将同一个表的数据按照一定的规则进行分割存储到不同的节点中。一般来说,一个分片可以被多个副本(Replica)所复制,以提高数据的可用性和可靠性。在 ClickHouse 中,分片可以通过哈希、按时间范围或按数据范围等方式进行划分。
-
replica:副本,用于将同一个分片的数据在不同节点之间进行复制。在 ClickHouse 中,一个分片可以被多个副本所复制,这些副本可以分布在不同的节点上,以提高数据的可用性和可靠性。
我们三台机器的两个副本,一共六个副本,配置成如图下所示:
保证如果有一台机器挂掉了,另外两台依旧提供完整的服务。
最后修改配置,编辑配置文件 vi user.xml
,主要打开创建用户的配置
<!-- User can create other users and grant rights to them. -->
<access_management>1</access_management>
切换到/etc/clickhouse-server/systemd/system
目录,复制一份服务cp -p clickhouse-server.service clickhouse-server-slave.service
,编辑slave从服务启动脚本,将config和pid配置修改成从服务;切换到/lib/systemd/system
下,同上操作,目的是为了可以直接使用systemctl启动服务
接下来,安装clickhouse-server,分别安装主节点和从节点的,首先安装主节点
其次用config-slave.xml覆盖config.xml文件,再次安装从节点
接下来进行启动
systemctl daemon-reload
systemctl start clickhouse-server.service
systemctl status clickhouse-server.service
systemctl start clickhouse-server-slave.service
systemctl status clickhouse-server-slave.service
3. 测试使用
clickhouse-client --host 192.168.136.131 --port 9000 --database default --user default --password 'root'
select * from system.clusters;
插入测试数据
本地表:在某个clickhouse节点(单个实例)中创建的表为本地表,其中{layer} {shard} {replica}是config.xml中配置的名字
CREATE TABLE IF NOT EXISTS default.test ON CLUSTER 'ck_cluster'(id Int32, name String)ENGINE = ReplicatedMergeTree('/clickhouse/database/tables/{layer}-{shard}/test ', '{replica}') ORDER BY id PARTITION BY id PRIMARY KEY id;
分布式表:分布式表本身不存储数据,但是可以在多个分片上进行分布式并行查询,查询时会根据每个分片上副本的健康程度选择其中的一个副本进行查询
CREATE TABLE IF NOT EXISTS default.test_all ON CLUSTER 'ck_cluster' AS default.test ENGINE = Distributed(ck_cluster, default, test, hiveHash(id));
数据:
insert into `default`.test values(1,'张三');
insert into `default`.test values(2,'李四');
insert into `default`.test values(3,'王五');
insert into `default`.test values(4,'赵六');
insert into `default`.test values(5,'沈七');
insert into `default`.test values(6,'王八');
首先我们查询单库test表,可以查看到当前副本的数据,如下:
然后查询分布式表,可以查看到全部副本的数据,如下:
三、springboot集成
1. 依赖引入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.28</version>
</dependency>
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.3.2</version>
</dependency>
2. 配置
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.url = jdbc:clickhouse://192.168.136.128:8123/default?useSSL=false
spring.datasource.driver-class-name = ru.yandex.clickhouse.ClickHouseDriver
spring.datasource.username = default
spring.datasource.password = root
3. 示例
package com.example.clickhouse.clickhouse.ctrl;
import com.example.clickhouse.clickhouse.service.TestService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TestService testService;
@Data
public class Test{
private String logId;
private String serviceClass;
private String date;
}
@RequestMapping("/write")
public String write(){
Test test = new Test();
test.setLogId("7");
test.setServiceClass("**********");
test.setDate("2022-10-10 10:56:04");
testService.insert(test);
return "插入成功";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.clickhouse.clickhouse.mapper.TestMapper">
<insert id="insert">
insert into `default`.uc_service_log("log_id","service_class","log_date") values(#{logId},#{serviceClass},#{date})
</insert>
</mapper>