ClickHouse基础、实践、调优全视角解析这几篇来自公众号:大数据技术与架构 ClickHouse基础&实践&调优全视角解析一文
Clickhouse 是一个高性能且开源的数据库管理系统,主要用于在线分析处理 (OLAP) 业务。它采用列式存储结构,可使用 SQL 语句实时生成数据分析报告,另外它还支持索引,分布式查询以及近似计算等特性,凭借其优异的表现,ClickHouse 在各大互联网公司均有广泛地应用。
Why ClickHouse
首先我们来看一下OLAP 场景下的关键特征。
- 大多数数据库访问都是读请求。
- 数据总是以批量形式写入数据库(每次写入大于 1000 行)。
- 已添加的数据一般无需修改。
- 每次查询都从数据库中读取大量的行,但是同时又仅需少量的列。
- 数据表多为宽表,即每个表均包含着大量的列。
- 查询量一般较少(非高并发,通常每台服务器每秒约有数百个查询或更少)。
- 对于简单查询,允许的延迟大约为 50 毫秒(响应时间要迅速)。
- 列中的数据相对较小,一般为数字或短字符串。
- 处理单个查询时需要高吞吐量(每个服务器每秒高达数十亿行)。
- 事务不是必须的。
- 对数据一致性要求低。
- 查询结果明显小于源数据,换句话说,数据被过滤或聚合后能够被存放在单台服务器的内存中。
可以看到,OLAP 业务场景与其它流行的业务场景如 OLTP 等有很大的不同,使用 OLTP 数据库或 Key-Value 数据库去处理分析查询业务将会获得非常差的性能,而且没有任何意义。
另外,相比于行式数据库,列式数据库则更适用于 OLAP 场景,因为对于大多数的查询而言,列式数据库的处理速度要至少比行式数据库快 100 倍。二者的性能差别很大,列式数据库明显占优,可以从以下几方面来解释:
- 对于分析类查询,通常只需要读取数据表中的一小部分列,使用列式数据库可以很轻松地实现,而使用行式数据库却必须要读取全部的列,这就带来了性能的损失。
- 列式数据库按列存储数据,使得数据更容易被压缩,可以降低 I/O 传输的体积,从而使查询速度加快。
- 由于 I/O 体积的降低,可以使得更多的查询数据被系统缓存,进一步加快了查询的速度。
- 另外,执行一个查询一般需要处理大量的行,在整个列向量上执行所有操作将比在每一行上执行所有操作更加高效,而且还可以更加充分地利用 CPU 资源,从而提升了查询的性能。
ClickHouse 特性
相比于其它的列式数据库,ClickHouse 的以下特性决定了它更适用于 OLAP 业务场景。
1.数据压缩:ClickHouse 会自动对插入的数据进行压缩,这对于性能的提升起到了至关重要的作用。 2.磁盘存储:ClickHouse 被设计为工作在传统磁盘上,这意味着数据存储的成本较低。 3.多核心并行处理:ClickHouse 会利用服务器的一切必要资源,从而以最自然的方式并行化处理大规模查询。 4.分布式查询:在 ClickHouse 中,数据可以保存在不同的分片 (shard) 上,查询可以在所有分片上并行处理。 5.支持 SQL:ClickHouse 的查询语言大部分情况下是与 SQL 标准兼容的,更容易上手。 6.向量引擎:ClickHouse 采用了列向量引擎技术,可以更为高效地使用 CPU 资源。 7.实时数据更新:ClickHouse 使用 MergeTree 引擎对数据进行增量排序,数据可以持续不断地写入到表中并进行合并,而且在整个过程中不会存在任何加锁行为。 8.支持索引:ClickHouse 按照排序键对数据进行排序并支持主键索引,可以使其在几十毫秒内完成对特定值或特定范围的查找。 9.支持近似计算:ClickHouse 提供了许多在允许牺牲数据精度的情况下对查询进行加速的方法。
下图显示了 ClickHouse 与其它主流列式数据库的性能对比。可以看到,对于大多数查询而言,ClickHouse 的响应速度更快,这也是选择 ClickHouse 作为 OLAP 数据处理的主要原因。
ClickHouse 配置文件
在使用 ClickHouse 之前,我们需要修改 ClickHouse 配置文件中的一些默认配置,比如数据存储路径,集群信息以及用户信息等,这样可以更好地对 ClickHouse 进行管理控制,以满足我们的业务需求。
01配置说明
1.ClickHouse 支持多配置文件管理,主配置文件为 config.xml,默认位于 /etc/clickhouse-server 目录下,其余的配置文件均需包含在 /etc/clickhouse-server/config.d 目录下。
2.ClickHouse 的所有配置文件均是 XML 格式的,而且在每个配置文件中都需要有相同的根元素,通常为。
3.主配置文件中的一些配置可以通过 replace 或 remove 属性被其子配置文件所覆盖,如子配置文件中的表示将使用该配置来替换主配置文件中的 zookeeper 选项。如果两个属性都未指定,则会递归组合各配置文件的内容并替换重复子项的值。
4.另外,配置文件中还可以定义 substitution 替换,如果一个配置包含 incl 属性,则替换文件中相应的配置将被使用。默认情况下替换文件的路径为 /etc/metrika.xml,可以通过 include_from 配置项进行设置。如果待替换的配置不存在,ClickHouse 会记录错误日志,为了避免这种情况,可以指定配置项的 optional 属性来表示该替换是可选的,如。
5.在启动时,ClickHouse 会根据已有的配置文件生成相应的预处理文件,这些文件中包含了所有已完成替换和覆盖的配置项,它们被统一放置于 preprocessed 目录下,你可以从这些文件中查看最终的配置项是否正确。另外 ClickHouse 会跟踪配置文件的更改,对于某些配置如集群配置以及用户配置等,更改后会自动生效,无需重启 ClickHouse 服务,而对于其它配置项的更改可能需要重启服务才能生效。
6.对于集群中的全部 ClickHouse 节点,除部分配置(如 macros)外,其它所有的配置最好都保持一致,以便于统一管理及使用。
02数据路径配置
1.数据路径下既存储数据库和表的元数据信息(位于 metadata 目录)也存储表的真实数据(位于 data 目录)。元数据是指建库和建表的语句,亦即数据库和表的结构信息,每次 ClickHouse 启动时会根据元数据信息去加载相应的数据库和表。
2.数据路径的配置如下所示,其对应的 XML 标签为。
<path>/path/to/clickhouse/</path>
3.当单个物理盘无法存储全部的数据时,可以考虑将不同的数据库存储在不同的物理盘上,然后在 /path/to/clickhouse/data/ 目录下创建软连接指向其它物理盘上的数据库目录。
03日志配置
1.ClickHouse 的日志文件中记录了各种类型的事件日志,包括数据的插入和查询的日志以及一些配置和数据合并相关的日志等。一般我们会通过日志文件找出 ClickHouse 报错的具体原因,以便解决问题。
2.日志的配置如下所示,其对应的 XML 标签为。
<logger>
<level>trace</level>
<log>/path/to/clickhouse-server/clickhouse-server.log</log>
<errorlog>/path/to/clickhouse-server/clickhouse-server.err.log</errorlog>
<size>1000M</size>
<count>10</count>
</logger>
3.level 表示事件的日志级别,可以配置为 trace,debug,information,warning,error 等值。
4.log 表示主日志文件路径,该日志文件中包含所有 level 级别以上的事件日志。
5.errorlog 表示错误日志文件路径,该日志文件仅包含错误日志,便于问题排查。
6.size 表示日志大小,当日志文件达到指定 size 后,ClickHouse 会进行日志轮转。
7.count 表示日志轮转的最大数量。
8.需要注意,因为事件日志是由多线程异步写入到日志文件中的,所以不同事件之间的日志会产生交错,不利于按顺序进行日志排查。但 ClickHouse 为每个事件都提供了唯一的 ID 来标识,我们可以根据此 ID 来跟踪事件状态的变化。
04集群配置
1.集群的配置主要用于分布式查询,在创建分布式表 (Distributed) 时会用到。2.集群配置文件的示例如下所示,其对应的 XML 标签为。
<yandex>
<remote_servers>
<cluster_name>
<shard>
<weight>1</weight>
<internal_replication>false</internal_replication>
<replica>
<host>hostname1/ip1</host>
<port>9000</port>
</replica>
</shard>
<shard>
<weight>1</weight>
<internal_replication>false</internal_replication>
<replica>
<host>hostname2/ip2</host>
<port>9000</port>
</replica>
</shard>
</cluster_name>
</remote_servers>
</yandex>
3.cluster_name 表示集群名称,shard 表示集群的分片(即 ClickHouse 节点),集群会有多个 shard,每个 shard 上都存有全部数据的一部分。
4.weight 表示数据写入的权重,当有数据直接写入集群时会根据该权重来将数据分发给不同的 ClickHouse 节点,可以理解为权重轮询负载均衡。
5.replica 表示每个 shard 的副本,默认为 1 个,可以设置多个,表示该 shard 有多个副本。正常情况下,每个副本都会存有相同的数据。
6.internal_replication 表示副本间是否为内部复制,当通过集群向分片插入数据时会起作用,参数的默认值为 false,表示向该分片的所有副本中写入相同的数据(副本间数据一致性不强,无法保证完全同步),true 表示只向其中的一个副本写入数据(副本间通过复制表来完成同步,能保证数据的一致性)。
7.在实际情况下,我们一般不会通过集群进行数据写入,而是将数据直接写入到各 ClickHouse 节点。一来通过集群进行分发数据会带来二次的网络延迟,降低了数据的写入速度,二来当数据量较多时,由于网络带宽限制,数据分发节点会成为数据传输的瓶颈,从而拉低了整体的数据写入效率。
8.可以定义多个集群,以应对不同的查询需要。每次添加新的集群配置后,无需重启 ClickHouse 服务,该配置会即时生效。
05字典配置
1.字典就是一种键->值映射关系,一般在数据查询时使用。相比于多表 JOIN 的查询操作,使用字典查询会更加高效。 2.字典文件的位置需要由 config.xml 文件中的 dictionaries_config 配置项设置。
<dictionaries_config>dictionaries/*_dictionary.xml</dictionaries_config>
上述配置表示 ClickHouse 会从与 config.xml 文件同级的 dictionaries 目录下加载以 _dictionary.xml 为后缀的全部字典文件。
3.字典配置文件的示例如下所示,其对应的 XML 标签为
<dictionaries>
<dictionary>
<name>products</name>
<source>
<odbc>
<table>products</table>
<connection_string>DSN=some-db-server</connection_string>
</odbc>
</source>
<lifetime>
<min>300</min>
<max>360</max>
</lifetime>
<layout>
<flat/>
</layout>
<structure>
<id>
<name>product_id</name>
</id>
<attribute>
<name>title</name>
<type>String</type>
<null_value></null_value>
</attribute>
</structure>
</dictionary>
</dictionaries>
4.name 表示字典名称。
5.source 表示字典的数据来源,数据来源有多种类型,可以是本地的文本文件,HTTP 接口或者其它各种数据库管理系统。
6.layout 表示字典在内存中的存储方式。一般推荐使用 flat,hashed 和 complex_key_hashed 存储方式,因为它们提供了最佳的查询处理速度。
7.structure 表示字典的结构,亦即键值对的信息。key 表示字典的键值,它可以由多个属性组成。attribute 表示字典的值,也可以有多个
8.lifetime 表示字典的更新频率,单位为秒。
9.创建完字典后,我们就可以通过 SELECT dictGetTYPE) 语句来查询字典中指定 key 值对应的 value 了。其中 TYPE 表示具体的数据类型,比如获取字符串类型的值可以使用 dictGetString。
10.除了使用配置文件来创建字典外,还可以使用 SQL 语句来生成字典。但相对而言,使用配置文件会更加直观便捷。
06用户配置
1.config.xml 可以指定单独的文件来对用户信息进行配置,用户配置文件的路径通过 users_config 配置项指定,默认为 users.xml。
<users_config>users.xml</users_config>
2.与 config.xml 文件类似,用户配置也可以被切分为不同的文件以便于管理,这些文件需要保存到 users.d 目录下。 3.ClickHouse 的默认用户为 default,密码为空。 4.用户配置的示例如下所示,其对应的 XML 标签为
$ cat /etc/clickhouse-server/users.d/user_name.xml
<clickhouse>
<users>
<user_name>
<profile>analytics</profile>
<networks>
<ip>::/0</ip>
</networks>
<password_sha256_hex>...</password_sha256_hex>
<quota>analytics</quota>
</alice>
</users>
</clickhouse>
5.user_name 表示待添加的用户名。 6.password 表示明文密码,不推荐使用该方式设置密码。 7.password_sha256_hex 表示经过 sha256 hash 后的密码,推荐使用该方式设置密码,密码的生成方式如下所示。
echo -n "$PASSWORD" | sha256sum | tr -d '-'
8.networks 表示允许连接到 ClickHouse 节点的网络地址列表,可以为 IP 地址或 Hostname。::/0 表示该用户可以从任何网络地址连接到 ClickHouse 节点
9.profile 表示对用户的一系列设置,用以控制用户的行为,如设置该用户具有只读权限等。它是以单独的 XML 标签存在于 users.xml 文件中的。配置的示例如下所示:
<!-- Settings profiles -->
<profiles>
<!-- Default settings -->
<default>
<!-- The maximum number of threads when running a single query. -->
<max_threads>8</max_threads>
</default>
<!-- Settings for quries from the user interface -->
<profile_name>
<!-- Maximum memory usage for processing single query, in bytes. -->
<max_memory_usage>30000000000</max_memory_usage>
<!-- How to choose between replicas during distributed query processing. -->
<load_balancing>in_order</load_balancing>
<readonly>1</readonly>
</profile_name>
</profiles>
profile 的名称可以任意,不同的用户可以配置相同的 profile。另外需要注意,default profile 必须存在,它会在 ClickHouse 启动时作为默认的设置使用。
10.quota 表示用户配额设置,用来限制用户一段时间内的资源使用,如 1 小时内的查询数不超过 1024 等。它同样是以单独的 XML 标签存在于 users.xml 文件中的。配置的示例如下所示:
<!-- Quotas -->
<quotas>
<!-- Quota name. -->
<default>
<!-- Restrictions for a time period. You can set many intervals with different restrictions. -->
<interval>
<!-- Length of the interval. -->
<duration>3600</duration>
<!-- Unlimited. Just collect data for the specified time interval. -->
<queries>0</queries>
<errors>0</errors>
<result_rows>0</result_rows>
<read_rows>0</read_rows>
<execution_time>0</execution_time>
</interval>
</default>
</quotas>
配额限制与 profile 中限制的主要区别在于,它可以对一段时间内运行的一组查询设置限制,而不是限制单个查询
11.除了使用配置文件管理用户,还可以基于 SQL 语句来创建、修改或删除用户。但相对而言,使用配置文件会更加直观便捷。
07ZooKeeper 配置
1.zookeeper 配置允许 ClickHouse 与一个 ZooKeeper 集群进行交互。ClickHouse 主要使用 ZooKeeper 来存储复制表的元数据,当不使用复制表和 distributed DDL 时,该配置可以忽略。
2.ZooKeeper 配置文件的示例如下所示,其对应的 XML 标签为。
<zookeeper>
<node index="1">
<host>example1</host>
<port>2181</port>
</node>
<node index="2">
<host>example2</host>
<port>2181</port>
</node>
<session_timeout_ms>30000</session_timeout_ms>
<operation_timeout_ms>10000</operation_timeout_ms>
<!-- Optional. Chroot suffix. Should exist. -->
<root>/path/to/zookeeper/node</root>
<!-- Optional. Zookeeper digest ACL string. -->
<identity>user:password</identity>
</zookeeper>
3.node 表示一个 ZooKeeper 节点,可以设置多个。当尝试连接到 ZooKeeper 集群时,index 属性指定了各节点的连接顺序。
4.session_timeout_ms client会话最大超时时间(毫秒)
5.operation_timeout_ms 一个操作最大超时时间(毫秒)
6.root clickhouse 用的znode根路径 ,可选
7.identity zookeeper 用户名密码授权 ,可选
08Macros 配置
1.macros 配置主要用来替换复制表的参数,在创建复制表时需要用到,当不使用复制表时,该配置可以忽略。
2.Macros 配置文件的示例如下所示,其对应的 XML 标签为:
<macros replace="true">
<shard>01</shard>
<replica>hostname/ip</replica>
</macros>
09Prometheus 配置
1.该配置用来供 Prometheus 获取 ClickHouse 的指标信息。
2.Prometheus 配置的示例如下所示,其对应的 XML 标签为:
<prometheus>
<endpoint>/metrics</endpoint>
<port>9363</port>
<metrics>true</metrics>
<events>true</events>
<asynchronous_metrics>true</asynchronous_metrics>
</prometheus>
3.endpoint 表示指标接口的 URI。 4.port 表示指标服务所使用的端口。 5.metrics,events 和 asynchronous_metrics 都是标志项,代表是否暴露相应的指标信息。 6.配置完成后,即可访问 http://ip:port/metrics 来查看所有的 ClickHouse 指标信息了。
10MergeTree 配置
1.该配置用来对使用 MergeTree 系列引擎的表进行微调。需要注意,除非你对该配置有充分的了解,否则不建议修改。
2.MergeTree 配置的示例如下所示,其对应的 XML 标签为。
<merge_tree>
<!-- If more than this number active parts in single partition, throw 'Too many parts ...' exception. -->
<parts_to_throw_insert>300</parts_to_throw_insert>
</merge_tree>
3.更多 MergeTree 相关配置可以参见源码中的 MergeTreeSettings.h 头文件。
11其他常用配置
1.时区配置
<timezone>Asia/Shanghai</timezone>
2.最大连接数配置
<max_connections>4096</max_connections>
3.并发查询数配置
<max_concurrent_queries>200</max_concurrent_queries>
4.ClickHouse 最大内存使用量配置
<max_server_memory_usage>0</max_server_memory_usage>
5.可删除表的最大数据量配置
<max_table_size_to_drop>0</max_table_size_to_drop>
单位为字节,默认值为 50 G,当表中数据大小超过该限制时,不能使用 DROP 语句去删除该表(防止误操作)。如果设置为 0,表示没有任何限制。如果你仍然想删除某个数据量超限的表而不想修改上述配置并重启 ClickHouse 时,可以在 ClickHouse 的数据目录下创建一个标志文件 /path/to/clickhouse/flags/force_drop_table 表示可以强制删除该表,然后执行 DROP 语句即可删表成功
需要注意上述标志文件在执行完一次 DROP 语句后会被自动删除以防止再次执行意外的 DROP 操作,因此执行创建标志文件和执行 DROP 语句的系统用户(非 ClickHouse 用户)应该保持一致,以避免在执行完 DROP 语句后,用户没有权限删除标志文件,从而导致后续操作失误并造成数据损失。
6.更多的配置可参见其官方文档,然后再按需调整。
来源公众号:大数据技术与架构 ClickHouse基础&实践&调优全视角解析