clickhouse集群安装与实践

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 因项目需要,将阿里云中间件tablestore替换成clickhouse,并将tablestore中的亿级数据迁移到clickhouse

clickhouse集群安装与实践

一、产品介绍

​ ClickHouse是俄罗斯的Yandex于2016年开源的一个用于联机分析(OLAP:Online Analytical Processing)的列式数据库管理系统(DBMS:Database Management System),简称CK , 主要用于在线分析处理查询(OLAP),能够使用SQL查询实时生成分析数据报告。

​ ClickHouse是一个完全的列式数据库管理系统,允许在运行时创建表和数据库,加载数据和运行查询,而无需重新配置和重新启动服务器,支持线性扩展,简单方便,高可靠性,容错。它在大数据领域没有走 Hadoop 生态,而是采用 Local attached storage 作为存储,这样整个 IO 可能就没有 Hadoop 那一套的局限。它的系统在生产环境中可以应用到比较大的规模,因为它的线性扩展能力和可靠性保障能够原生支持 shard + replication 这种解决方案。它还提供了一些 SQL 直接接口,有比较丰富的原生 client。另外就是它比较快。

二、特点

1、列式存储:

行式存储的好处:

想查找某个人所有的属性时,可以通过一次磁盘查找加顺序读取就可以;但是当想查所有人的年龄时,需要不停的查找,或者全表扫描才行,遍历的很多数据都是不需要的。

列式存储的好处

  • 对于列的聚合、计数、求和等统计操作优于行式存储
  • 由于某一列的数据类型都是相同的,针对于数据存储更容易进行数据压缩,每一列选择更优的数据压缩算法,大大提高了数据的压缩比重
  • 数据压缩比更好,一方面节省了磁盘空间,另一方面对于cache也有了更大的发挥空间
  • 列式存储不支持事务

2、DBMS功能:

几乎覆盖了标准 SQL 的大部分语法,包括 DDL 和 DML、,以及配套的各种函数;用户管理及权限管理、数据的备份与恢复

3、多样化引擎:

目前包括合并树、日志、接口和其他四大类20多种引擎。

4、高吞吐写入能力:

ClickHouse采用类LSM Tree的结构,数据写入后定期在后台Compaction。通过类 LSM tree的结构, ClickHouse在数据导入时全部是顺序append写,写入后数据段不可更改,在后台compaction时也是多个段merge sort后顺序写回磁盘。顺序写的特性,充分利用了磁盘的吞吐能力。

5、数据分区与线程及并行:

ClickHouse将数据划分为多个partition,每个partition再进一步划分为多个index granularity(索引粒度),然后通过多个CPU核心分别处理其中的一部分来实现并行数据处理。在这种设计下, 单条 Query 就能利用整机所有 CPU。 极致的并行处理能力,极大的降低了查询延时。

所以, ClickHouse 即使对于大量数据的查询也能够化整为零平行处理。但是有一个弊端就是对于单条查询使用多cpu,就不利于同时并发多条查询。所以对于高 qps 的查询业务并不是强项。

6、关联查询:

ClickHouse 像很多 OLAP 数据库一样,单表查询速度优于关联查询,而且 ClickHouse的两者差距更为明显。

关联查询:clickhouse会将右表加载到内存。

三、ClickHouse引擎

引擎决定了数据的存储位置、存储结构、表的特征(是否修改操作DDL、DDL、是否支持并发操作)

1、数据库引擎

目前支持的数据库引擎有5种:

  • Ordinary:默认引擎,在绝大多数情况下我们都会使用默认引擎,使用时无须刻意声明。在此数据库下可以使用任意类型的表引擎。
  • Dictionary:字典引擎,此类数据库会自动为所有数据字典创建它们的数据表
  • Memory:内存引擎,用于存放临时数据。此类数据库下的数据表只会停留在内存中,不会涉及任何磁盘操作,当服务重启后数据会被清除
  • Lazy:日志引擎,此类数据库下只能使用Log系列的表引擎
  • MySQL:MySQL引擎,将远程的MySQL服务器中的表映射到ClickHouse中,常用语数据的合并。
  • MaterializeMySQL:MySQL数据同步;将MySQL数据全量或增量方式同步到clickhouse中,解决mysql服务并发访问压力过大的问题

五、使用背景

因项目需要,将阿里云中间件tablestore替换成clickhouse,并将tablestore中的亿级数据迁移到clickhouse。

六、集群搭建

1、基础环境

clickhouse集群依赖jdk和Zookeeper,请先安装基础环境;

数据量较大时,建议挂载大容量磁盘;

2、服务器准备

IP 路径
172.23.1.233 /clickhouse
172.23.1.234 /clickhouse
172.23.1.235 /clickhouse

2、安装单机版clickhouse(每台机器都安装)

#设置变量LATEST_VERSION,安装的版本为22.2.2.1(此版本比较稳定)
export LATEST_VERSION=22.2.2.1

#下载安装包到服务器
cd /clickhouse
curl -O https://repo.clickhouse.com/tgz/stable/clickhouse-common-static-22.2.2.1.tgz
curl -O https://repo.clickhouse.com/tgz/stable/clickhouse-common-static-dbg-22.2.2.1.tgz
curl -O https://repo.clickhouse.com/tgz/stable/clickhouse-server-22.2.2.1.tgz
curl -O https://repo.clickhouse.com/tgz/stable/clickhouse-client-22.2.2.1.tgz

#解压包
tar -xzvf clickhouse-common-static-$LATEST_VERSION.tgz
tar -xzvf clickhouse-common-static-dbg-$LATEST_VERSION.tgz
tar -xzvf clickhouse-server-$LATEST_VERSION.tgz
tar -xzvf clickhouse-client-$LATEST_VERSION.tgz

#运行安装命令
sudo clickhouse-common-static-$LATEST_VERSION/install/doinst.sh
sudo clickhouse-common-static-dbg-$LATEST_VERSION/install/doinst.sh
#该步骤可以设置默认用户的密码 修改default用户密码:/etc/clickhouse-server/users.d/default-password.xml
sudo clickhouse-server-$LATEST_VERSION/install/doinst.sh
sudo clickhouse-client-$LATEST_VERSION/install/doinst.sh

3、修改ClickHouse配置为集群版(每台机器都修改)

备份默认配置文件:cp /etc/clickhouse-server/config.xml /etc/clickhouse-server/config.xml.bak

然后编辑默认配置文件 /etc/clickhouse-server/config.xml 并删除集群相关的配置

    • 文件中<remote_servers></remote_servers>标签里的全部内容
    • 文件中标签里的全部内容
    • 文件中标签里的全部内容

添加自定义配置文件:vi /etc/clickhouse-server/config.d/config.xml 内容如下

<yandex>
    <zookeeper>
        <node index="1">
            <host>此处改为ZK的HOST</host>
            <port>2181</port>
        </node>
        <identity>zk_username:zk_password</identity>
        <session_timeout_ms>600000</session_timeout_ms>
    </zookeeper>
 
    <remote_servers>
        <test>
            <shard>
                <internal_replication>true</internal_replication>
                <replica>
                    <host>172.23.1.233</host>
                    <port>9000</port>
                    <user>default</user>
                    <password>123456</password>
                </replica>
            </shard>
            <shard>
                <internal_replication>true</internal_replication>
                <replica>
                    <host>172.23.1.234</host>
                    <port>9000</port>
                    <user>default</user>
                    <password>123456</password>
                </replica>
            </shard>
            <shard>
                <internal_replication>true</internal_replication>
                <replica>
                    <host>172.23.1.235</host>
                    <port>9000</port>
                    <user>default</user>
                    <password>123456</password>
                </replica>
            </shard>
        </test>
    </remote_servers>
 
    <networks>
        <ip>::/0</ip>
    </networks>
    
    <macros>
        <shard>01</shard>
        <replica>node1</replica>
    </macros>
</yandex>

zookeeper 配置

    1. 如果Zookeeper为集群版,直接增加node节点即可

remote_servers 配置

    1. remote_servers下级节点为集群,可配置多个集群
    2. 集群下级节点为分片(shard),可配置多个shard,不同shard不能用同一个ClickHouse实例
    3. 分片下级为副本(replica),可对分片配置多个副本,默认最少0个,不同副本不能用同一个ClickHouse实例
    4. internal_replication 用来控制当数据写入时(必须是Replicated*的表),由分片自己负责副本间的数据复制,否则分布式表的副本数据写入需要由Distributed引擎来负责

macros 配置

    1. 本质上就是针对当前实例的全局变量的定义,可以被某些地方来引用
    2. 此配置需要在集群中全局唯一
    3. 此处的参数会在创建Replicated*的表时被引用
    4. shard的值为当前节点在在集群中的分片编号,需要在集群中唯一
    5. replica是副本的唯一标识,需要在单个分片的多个副本中唯一

七、修改clickhouse数据和日志存储路径

1、默认的数据目录包含在/var/lib/clickhouse中,将该文件夹移动到需要更改的新目录

vim /clickhouse/clickhouse-server-22.2.2.1/etc/clickhouse-server/config.xml
更改全部的/var/lib/clickhouse改为/clickhouse

2、修改启动命令

vim /clickhouse/clickhouse-server-22.2.2.1/install/doinst.sh
更改全部的/var/lib/clickhouse改为/clickhouse

3、修改服务脚本的目录

vim /etc/init.d/clickhouse-server
更改全部的/var/lib/clickhouse改为/clickhouse

4、重新安装服务启动

sudo clickhouse-client-$LATEST_VERSION/install/doinst.sh
sudo /etc/init.d/clickhouse-server restart

八、分布式表创建

1、创建本地表

建表语句基本语法如下:

CREATE TABLE [IF NOT EXISTS] [db.]table_name ON CLUSTER cluster
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
    INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
    INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = engine_name()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...];

选项描述:

  • db:指定数据库名称,如果当前语句没有包含‘db’,则默认使用当前选择的数据库为‘db’。
  • cluster:指定集群名称,目前固定为default。ON CLUSTER 将在每一个节点上都创建一个本地表。
  • type:该列数据类型,例如 UInt32。
  • DEFAULT:该列缺省值。如果INSERT中不包含指定的列,那么将通过表达式计算它的默认值并填充它。
  • MATERIALIZED:物化列表达式,表示该列不能被INSERT,是被计算出来的; 在INSERT语句中,不需要写入该列;在SELECT *查询语句结果集不包含该列。
  • ALIAS :别名列。这样的列不会存储在表中。 它的值不能够通过INSERT写入,同时使用SELECT查询星号时,这些列也不会被用来替换星号。 但是它们可以用于SELECT中,在这种情况下,在查询分析中别名将被替换。
  • 物化列与别名列的区别: 物化列是会保存数据,查询的时候不需要计算,而别名列不会保存数据,查询的时候需要计算,查询时候返回表达式的计算结果

以下选项与表引擎相关,只有MergeTree系列表引擎支持:

  • PARTITION BY:指定分区键。通常按照日期分区,也可以用其他字段或字段表达式。
  • ORDER BY:指定 排序键。可以是一组列的元组或任意的表达式。
  • PRIMARY KEY: 指定主键,默认情况下主键跟排序键相同。因此,大部分情况下不需要再专门指定一个 PRIMARY KEY 子句。
  • SAMPLE BY :抽样表达式,如果要用抽样表达式,主键中必须包含这个表达式。
  • SETTINGS:影响 性能的额外参数。
  • GRANULARITY :索引粒度参数。

说明 :

高可用集群(双副本),要用ReplicatedMergeTree等Replicated系列引擎,否则副本之间不进行数据复制,导致数据查询结果不一致。

{shard},{replica} 参数不需要赋值。

2、创建分布式表

基于本地表创建一个分布式表。

创建分布式表基本语法:

CREATE TABLE  [db.]table_name  ON CLUSTER default
 AS db.local_table_name   ENGINE = Distributed(<cluster>, <database>, <shard table> [, sharding_key])

参数说明:

  • db:数据库名。
  • local_table_name:对应的已经创建的本地表表名。
  • shard table:同上,对应的已经创建的本地表表名。
  • sharding_key:分片表达式。可以是一个字段,例如user_id(integer类型),通过对余数值进行取余分片;也可以是一个表达式,例如rand(),通过rand()函数返回值/shards总权重分片;为了分片更均匀,可以加上hash函数,如intHash64(user_id)。

说明 : db_name 是数据库的名字,需要填写。

九、数据更新场景

因项目需要数据同步,主键存在更新,主键不存在新增,所以在创建分布式表时选择了ReplacingMergeTree。

Clickhouse作为一个OLAP数据库,它对事务的支持非常有限。Clickhouse提供了MUTATION操作(通过ALTER TABLE语句)来实现数据的更新、删除,但这是一种“较重”的操作,它与标准SQL语法中的UPDATE、DELETE不同,是异步执行的,对于批量数据不频繁的更新或删除比较有用。

除了MUTATION操作,Clickhouse还可以通过CollapsingMergeTree、VersionedCollapsingMergeTree、ReplacingMergeTree结合具体业务数据结构来实现数据的更新、删除,这三种方式都通过INSERT语句插入最新的数据,新数据会“抵消”或“替换”掉老数据,但是“抵消”或“替换”都是发生在数据文件后台Merge时,也就是说,在Merge之前,新数据和老数据会同时存在。因此,我们需要在查询时做一些处理,避免查询到老数据。Clickhouse官方文档提供了使用CollapsingMergeTree、VersionedCollapsingMergeTree的指导,相比于CollapsingMergeTree、VersionedCollapsingMergeTree需要标记位字段、版本字段,用ReplacingMergeTree来实现数据的更新删除会更加方便,这里着重介绍一下如何用ReplacingMergeTree来实现数据的更新删除。

#先创建本地表
CREATE TABLE local_user_info_local ON CLUSTER test
(
    id UInt64,
    phone String,
    contrast_date DateTime
)ENGINE = ReplicatedReplacingMergeTree(
          '/clickhouse/tables/local_user_info_local/{shard}',
          '{replica}',contrast_date)
     ORDER BY id
     PARTITION BY toYYYYMM(contrast_date)
     PRIMARY KEY id;

#基于本地表创建分布式表
CREATE TABLE local_user_info ON CLUSTER test AS local_user_info_local
ENGINE = Distributed(test, default, local_user_info_local, intHash64(id));

local_user_info_local为本地表,local_user_info为对应的分布式表。其中local_user_info_local使用ReplicatedReplacingMergeTree表引擎,第三个参数‘contrast_date’表示相同主键的多条数据,只会保留contrast_date最大的一条,我们正是利用ReplacingMergeTree的这一特性来实现数据的更新删除。因此,在选择主键时,我们需要确保主键唯一。这里我们选择id来作为主键。

目录
相关文章
|
30天前
|
消息中间件 分布式计算 关系型数据库
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
38 0
|
23天前
|
数据可视化 数据挖掘 Docker
Docker Desktop 安装 ClickHouse 超级简单教程
Docker Desktop 安装 ClickHouse 超级简单教程
38 1
|
7天前
|
存储 Prometheus 监控
构建高可用性ClickHouse集群:从理论到实践
【10月更文挑战第27天】在数据驱动的时代,构建一个稳定、高效的数据库系统对于企业的业务发展至关重要。作为一名数据工程师,我深知数据库系统的高可用性和可扩展性对于支撑企业应用的重要性。在这篇文章中,我将分享如何构建一个高可用性的ClickHouse集群,从分布式表的设计到数据复制与分片,再到故障恢复机制,确保系统在大规模数据处理中的稳定性和可靠性。
23 0
|
8天前
|
存储 监控 大数据
构建高可用性ClickHouse集群:从单节点到分布式
【10月更文挑战第26天】随着业务的不断增长,单一的数据存储解决方案可能无法满足日益增加的数据处理需求。在大数据时代,数据库的性能、可扩展性和稳定性成为企业关注的重点。ClickHouse 是一个用于联机分析处理(OLAP)的列式数据库管理系统(DBMS),以其卓越的查询性能和高吞吐量而闻名。本文将从我的个人角度出发,分享如何将单节点 ClickHouse 扩展为高可用性的分布式集群,以提升系统的稳定性和可靠性。
20 0
|
29天前
|
SQL 消息中间件 分布式计算
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(一)
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(一)
64 0
|
29天前
|
SQL 大数据
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(二)
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(二)
54 0
|
30天前
|
存储 SQL 分布式计算
大数据-142 - ClickHouse 集群 副本和分片 Distributed 附带案例演示
大数据-142 - ClickHouse 集群 副本和分片 Distributed 附带案例演示
103 0
|
30天前
|
SQL 消息中间件 分布式计算
大数据-141 - ClickHouse 集群 副本和分片 Zk 的配置 Replicated MergeTree原理详解(一)
大数据-141 - ClickHouse 集群 副本和分片 Zk 的配置 Replicated MergeTree原理详解(一)
49 0
|
30天前
|
SQL 大数据
大数据-141 - ClickHouse 集群 副本和分片 Zk 的配置 Replicated MergeTree原理详解(二)
大数据-141 - ClickHouse 集群 副本和分片 Zk 的配置 Replicated MergeTree原理详解(二)
59 0
|
5月前
|
存储 关系型数据库 数据库
【DDIA笔记】【ch2】 数据模型和查询语言 -- 多对一和多对多
【6月更文挑战第7天】该文探讨数据模型,比较了“多对一”和“多对多”关系。通过使用ID而不是纯文本(如region_id代替&quot;Greater Seattle Area&quot;),可以实现统一、避免歧义、简化修改、支持本地化及优化搜索。在数据库设计中,需权衡冗余和范式。文档型数据库适合一对多但处理多对多复杂,若无Join,需应用程序处理。关系型数据库则通过外键和JOIN处理这些关系。文章还提及文档模型与70年代层次模型的相似性,层次模型以树形结构限制了多对多关系处理。为克服层次模型局限,发展出了关系模型和网状模型。
56 6