ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。ClickHouse不单单是一个数据库, 它是一个数据库管理系统。
官方文档:https://clickhouse.com/docs/zh
GitHub地址:https://github.com/ClickHouse/ClickHouse
默认情况下,ClickHouse使用Atomic数据库引擎。它提供了可配置的table engines和SQL dialect。目前支持的数据库引擎有以下几种:
关于更多,请查看官方文档:https://clickhouse.com/docs/zh/engines/database-engines/
表引擎(即表的类型)决定了:
表引擎类型
适用于高负载任务的最通用和功能最强大的表引擎。这些引擎的共同特点是可以快速插入数据并进行后续的后台数据处理。 MergeTree系列引擎支持数据复制(使用Replicated* 的引擎版本),分区和一些其他引擎不支持的其他功能。该类型的引擎:
MergeTree、ReplacingMergeTree、SummingMergeTree、AggregatingMergeTree、CollapsingMergeTree、VersionedCollapsingMergeTree、GraphiteMergeTree
这些引擎是为了需要写入许多小数据量(少于一百万行)的表的场景而开发的。具有最小功能的轻量级引擎。当您需要快速写入许多小表(最多约100万行)并在以后整体读取它们时,该类型的引擎是最有效的。该类型的引擎:
TinyLog、StripeLog、Log
ClickHouse 提供了多种方式来与外部系统集成,包括表引擎。像所有其他的表引擎一样,使用CREATE TABLE或ALTER TABLE查询语句来完成配置。 支持的集成引擎:
Kafka、MySQL、ODBC、JDBC、HDFS
等。
特定功能的引擎有如下几种:Distributed、MaterializedView、Dictionary、Merge、File、Null、Set、Join、URL、View、Memory、Buffer
Clickhouse的集群架构是和其他的数据集群有一定的区别,他的集群能力是表级别的,而我们熟知的大数据体系,比如hadoop系列的集群都是服务级别的。例如,一个hdfs集群,所有文件都会切片、备份;而Clickhouse集群中,建表时也可以自己决定用不用,也就是说其实Clickhouse单节点就能存活。
Parser和Interpreter是非常重要的两组接口:Parser分析器是将sql语句已递归的方式形成AST语法树的形式,并且不同类型的sql都会调用不同的parse实现类。而Interpreter解释器则负责解释AST,并进一步创建查询的执行管道。Interpreter解释器的作用就像Service服务层一样,起到串联整个查询过程的作用,它会根据解释器的类型,聚合它所需要的资源。首先它会解析AST对象;然后执行"业务逻辑" ( 例如分支判断、设置参数、调用接口等 );最终返回IBlock对象,以线程的形式建立起一个查询执行管道。
表引擎是ClickHouse的一个显著特性,clickhouse有很多种表引擎。不同的表引擎由不同的子类实现。表引擎是使用IStorage接口的,该接口定义了DDL ( 如ALTER、RENAME、OPTIMIZE和DROP等 ) 、read和write方法,它们分别负责数据的定义、查询与写入。
数据的序列化和反序列化工作由DataType负责。根据不同的数据类型,IDataType接口会有不同的实现类。DataType虽然会对数据进行正反序列化,但是它不会直接和内存或者磁盘做交互,而是转交给Column和Filed处理。
Column和Field是ClickHouse数据最基础的映射单元。作为一款百分之百的列式存储数据库,ClickHouse按列存储数据,内存中的一列数据由一个Column对象表示。Column对象分为接口和实现两个部分,在IColumn接口对象中,定义了对数据进行各种关系运算的方法,例如插入数据的insertRangeFrom和insertFrom方法、用于分页的cut,以及用于过滤的filter方法等。而这些方法的具体实现对象则根据数据类型的不同,由相应的对象实现,例如ColumnString、ColumnArray和ColumnTuple等。在大多数场合,ClickHouse都会以整列的方式操作数据,但凡事也有例外。如果需要操作单个具体的数值 ( 也就是单列中的一行数据 ),则需要使用Field对象,Field对象代表一个单值。与Column对象的泛化设计思路不同,Field对象使用了聚合的设计模式。在Field对象内部聚合了Null、UInt64、String和Array等13种数据类型及相应的处理逻辑。
ClickHouse内部的数据操作是面向Block对象进行的,并且采用了流的形式。虽然Column和Filed组成了数据的基本映射单元,但对应到实际操作,它们还缺少了一些必要的信息,比如数据的类型及列的名称。于是ClickHouse设计了Block对象,Block对象可以看作数据表的子集。Block对象的本质是由数据对象、数据类型和列名称组成的三元组,即Column、DataType及列名称字符串。Column提供了数据的读取能力,而DataType知道如何正反序列化,所以Block在这些对象的基础之上实现了进一步的抽象和封装,从而简化了整个使用的过程,仅通过Block对象就能完成一系列的数据操作。在具体的实现过程中,Block并没有直接聚合Column和DataType对象,而是通过ColumnWith TypeAndName对象进行间接引用。
IP | hostname | 角色 |
---|---|---|
192.168.182.110 | local-168-182-110 | node1、zookeeper |
192.168.182.111 | local-168-182-111 | node2、zookeeper |
192.168.182.112 | local-168-182-112 | node3、zookeeper |
192.168.182.113 | local-168-182-110 | node4 |
官网下载:https://www.oracle.com/java/technologies/downloads/
官网下载需要登录,这里提供一个百度云下载地址:
链接:https://pan.baidu.com/s/1-rgW-Z-syv24vU15bmMg1w
提取码:8888
cd /opt/software/
# 解压
tar -xf jdk-8u212-linux-x64.tar.gz -C /opt/server/
# 在文件加入环境变量/etc/profile
export JAVA_HOME=/opt/server/jdk1.8.0_212
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# source加载
source /etc/profile
# 查看jdk版本
java -version
其它节点
scp -r /opt/server/jdk1.8.0_212 local-168-182-111:/opt/server/
scp -r /opt/server/jdk1.8.0_212 local-168-182-112:/opt/server/
# 设置环境变量
# 在文件加入环境变量/etc/profile
export JAVA_HOME=/opt/server/jdk1.8.0_212
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# source加载
source /etc/profile
# 查看jdk版本
java -version
想了解更多zookeeper,可以参考我之前的文章:分布式开源协调服务——Zookeeper
zookeeper在clickhouse中主要用在副本表数据的同步(ReplicatedMergeTree引擎)以及分布式表(Distributed)的操作上。
mkdir /opt/software && cd /opt/software
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.0/apache-zookeeper-3.8.0-bin.tar.gz --no-check-certificate
mkdir -p /opt/server/ && tar -xf apache-zookeeper-3.8.0-bin.tar.gz -C /opt/server/
vi /etc/profile
export ZOOKEEPER_HOME=/opt/server/apache-zookeeper-3.8.0-bin/
export PATH=$ZOOKEEPER_HOME/bin:$PATH
source /etc/profile
cd $ZOOKEEPER_HOME
cp conf/zoo_sample.cfg conf/zoo.cfg
mkdir $ZOOKEEPER_HOME/data
cat >conf/zoo.cfg<<EOF
# tickTime:Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。tickTime以毫秒为单位。session最小有效时间为tickTime*2
tickTime=2000
# Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这个目录里。不要使用/tmp目录
dataDir=/opt/server/apache-zookeeper-3.8.0-bin/data
# 端口,默认就是2181
clientPort=2181
# 集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量),超过此数量没有回复会断开链接
initLimit=10
# 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)
syncLimit=5
# 最大客户端链接数量,0不限制,默认是0
maxClientCnxns=60
# zookeeper集群配置项,server.1,server.2,server.3是zk集群节点;hadoop-node1,hadoop-node2,hadoop-node3是主机名称;2888是主从通信端口;3888用来选举leader
server.1=local-168-182-110:2888:3888
server.2=local-168-182-111:2888:3888
server.3=local-168-182-112:2888:3888
EOF
echo 1 > $ZOOKEEPER_HOME/data/myid
scp -r $ZOOKEEPER_HOME local-168-182-111:/opt/server/
scp -r $ZOOKEEPER_HOME local-168-182-112:/opt/server/
# 也需要添加环境变量和修改myid,local-168-182-111的myid设置2,local-168-182-112的myid设置3
cd $ZOOKEEPER_HOME
# 启动
./bin/zkServer.sh start
# 查看状态
./bin/zkServer.sh status
单机版安装很简单,可以参考官方文档:https://clickhouse.com/docs/zh/getting-started/install
【方案一】
在每个节点创建一个数据表,作为一个数据分片,使用ReplicatedMergeTree表引擎实现数据副本,而分布表作为数据写入和查询的入口。这是最常见的集群实现方式。
yum install -y yum-utils
yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo
yum install -y clickhouse-server clickhouse-client
修改配置文件路径权限
chmod -R 755 /etc/clickhouse-server/
修改/etc/clickhouse-server/config.xml
,是本地和远程可登陆
<listen_host>0.0.0.0listen_host>
修改/etc/clickhouse-server/users.xml
,配置密码,其它参数可以根据业务场景进行配置,在64行左右
<password>123456password>
【温馨提示】如果是部署单机版,现在已经配置好了,启动就OK了,这里是部署集群模式,所以还得继续配置。
clickhouse⾼可⽤配置主要⽤到metrika.xml,默认路径:/etc/metrika.xml。如果想调整文件路径,需要在/etc/clickhouse-server/config.xml
文件中使用 include_from
来调整(注意位置)。
<clickhouse>
<include_from>/etc/metrika.xmlinclude_from>
<remote_servers incl="clickhouse_remote_servers" />
<zookeeper incl="zookeeper" optional="true" />
<macros incl="macros" optional="true" />
<compression incl="clickhouse_compression" optional="true" />
clickhouse>
【温馨提示】当然也可以直接在
/etc/clickhouse-server/config.xml
文件里配置,不配置额外的metrika.xml,但是最好还是配置metrika.xml,这样看起来比较简洁。
创建 /etc/metrika.xml
配置文件,内容如下:
<yandex>
<clickhouse_remote_servers>
<ck_cluster_2022>
<shard>
<weight>1weight>
<internal_replication>falseinternal_replication>
<replica>
<host>local-168-182-110host>
<port>9000port>
<user>defaultuser>
<password>123456password>
replica>
<replica>
<host>local-168-182-111host>
<port>9000port>
<user>defaultuser>
<password>123456password>
replica>
shard>
<shard>
<weight>1weight>
<internal_replication>falseinternal_replication>
<replica>
<host>local-168-182-113host>
<port>9000port>
<user>defaultuser>
<password>123456password>
replica>
<replica>
<host>local-168-182-112host>
<port>9000port>
<user>defaultuser>
<password>123456password>
replica>
shard>
ck_cluster_2022>
clickhouse_remote_servers>
<zookeeper>
<node index="1">
<host>local-168-182-110host>
<port>2181port>
node>
<node index="2">
<host>local-168-182-111host>
<port>2181port>
node>
<node index="3">
<host>local-168-182-112host>
<port>2181port>
node>
zookeeper>
<macros>
<shard>01shard>
<replica>local-168-182-110-01-1replica>
macros>
<networks>
<ip>::/0ip>
networks>
<clickhouse_compression>
<case>
<min_part_size>1073741824min_part_size>
<min_part_size_ratio>0.01min_part_size_ratio>
<method>lz4method>
case>
clickhouse_compression>
yandex>
【温馨提示】或者把配置文件放在
/etc/clickhouse/conf.d/
下也可以,会和config.xml里面配置合并
其它节点配置
scp /etc/clickhouse-server/config.xml local-168-182-111:/etc/clickhouse-server/
scp /etc/clickhouse-server/users.xml local-168-182-111:/etc/clickhouse-server/
scp /etc/metrika.xml local-168-182-111:/etc/
scp /etc/clickhouse-server/config.xml local-168-182-112:/etc/clickhouse-server/
scp /etc/clickhouse-server/users.xml local-168-182-112:/etc/clickhouse-server/
scp /etc/metrika.xml local-168-182-112:/etc/
scp /etc/clickhouse-server/config.xml local-168-182-113:/etc/clickhouse-server/
scp /etc/clickhouse-server/users.xml local-168-182-113:/etc/clickhouse-server/
scp /etc/metrika.xml local-168-182-113:/etc/
【温馨提示】记得修改/etc/metrika.xml文件里的
clickhouse.macros
<macros>
<shard>01shard>
<replica>local-168-182-110-01-1replica>
macros>
<macros>
<shard>01shard>
<replica>local-168-182-111-01-2replica>
macros>
<macros>
<shard>02shard>
<replica>local-168-182-112-02-2replica>
macros>
<macros>
<shard>02shard>
<replica>local-168-182-113-02-1replica>
macros>
systemctl restart clickhouse-server ; systemctl status clickhouse-server
clickhouse-client -u default --password 123456 --port 9000 -h local-168-182-110 --multiquery
select * from system.clusters;
登录web界面
http://local-168-182-110:8123/play
主要字段说明:
cluster: 集群的命名
shard_num: 分片的编号
shard_weight: 分片的权重
replica_num: 副本的编号
host_name: 机器的host名称
host_address: 机器的ip地址
port: clickhouse集群的端口
is_local: 是否为你当前查询本地
user: 创建用户
【温馨提示】clickhouse安装后,默认的数据目录在
/var/lib/clickhouse
,如果需要修改,修改/etc/rc.d/init.d/clickhouse-server
这个文件
# 卸载及删除安装文件(需root权限)
yum list installed | grep clickhouse
yum remove -y clickhouse-server clickhouse-client
rm -rf /var/lib/clickhouse
rm -rf /etc/clickhouse-*
rm -rf /var/log/clickhouse-server
【方案二】
在每个节点创建一个数据表,作为一个数据分片,分布表同时负责分片和副本的数据写入工作。这种实现方案下,不需要使用复制表,但分布表节点需要同时负责分片和副本的数据写入工作,它很有可能称为写入的单点瓶颈。
ZooKeeper不是一个严格的要求:在某些简单的情况下,您可以通过将数据写入应用程序代码中的所有副本来复制数据。 这种方法是不建议的,在这种情况下,ClickHouse将无法保证所有副本上的数据一致性。 因此需要由您的应用来保证这一点。
【方案三】
在每个节点创建一个数据表,作为一个数据分片,同时创建两个分布表,每个分布表(Distributed)节点只纳管一半的数据。副本的实现仍需要借助
ReplicatedMergeTree
类表引擎。
创建库表
【方案四】
在每个节点创建两个数据表,同一数据分片的两个副本位于不同节点上,每个分布式表纳管一般的数据。这种方案可以在更少的节点上实现数据分布与冗余,但是部署上略显繁琐。
【总结】
CH(ClickHouse)
的分片与副本功能完全靠配置文件实现,无法自动管理,所以当集群规模较大时,集群运维成本较高后续会针以上几个方案使用案例讲解,请小伙伴耐心等待,有疑问的小伙伴欢迎给我留言哦~