Help us learn about your current experience with the documentation. Take the survey.

ClickHouse 使用与表设计简介

与 PostgreSQL 的区别

intro 页面很好地概述了 ClickHouse。

ClickHouse 与传统的 OLTP(在线事务处理)数据库(如 PostgreSQL)有很多不同。底层架构有些差异,处理过程比传统数据库更依赖 CPU。 ClickHouse 是一个以日志为中心的数据库,不可变性是其关键组成部分。这种方法的优点已有充分记录;更多信息请参见 不可变数据存储的兴起。然而,这也使得更新变得更加困难。有关提供 UPDATE/DELETE 支持的操作,请参见 ClickHouse 文档。值得注意的是,这些操作应该是非频繁的。

在表设计时,这种区别很重要。要么:

  • 不需要更新(最佳情况)
  • 如果需要更新,则不应在查询执行期间运行。

ACID 兼容性

ClickHouse 对事务支持有稍微不同的概述,其中保证仅适用于插入到特定表的数据块。详细信息请参见 事务(ACID)支持 文档。

应避免在单个写入中进行多次插入,因为跨多个表的事务支持仅在物化视图中得到覆盖。

ClickHouse 致力于为分析查询提供一流的支持。像聚合这样的操作非常快速,并且有几个功能可以增强这些能力。 ClickHouse 有一些很好的博客文章涵盖了 聚合的详细信息

主索引、排序索引和字典

强烈建议阅读 “ClickHouse 主索引的实用介绍” 以了解 ClickHouse 中的索引。

特别是 ClickHouse 中的数据库索引设计如何与像 PostgreSQL 这样的事务数据库中的索引 不同

主索引设计在查询性能中扮演着非常重要的角色,应该仔细设计。几乎所有查询都应该依赖主索引,因为全数据扫描注定会花费更长时间。

阅读 查询中的主键和索引 文档,了解索引如何影响 MergeTree 表引擎(ClickHouse 的默认表引擎)中的查询性能。

ClickHouse 中的二级索引与其他系统中的索引不同。它们也称为数据跳过索引,因为它们用于跳过数据块。有关数据跳过索引的文档,请参见 文档

ClickHouse 还提供 “字典”,可以用作外部索引。字典从内存加载,可用于在查询运行时查找值。

数据类型与分区

ClickHouse 提供 SQL 兼容的 数据类型 和一些专门的数据类型,如:

在表设计时出现的一个关键设计方面是分区键。分区可以是任意表达式,但通常是时间间隔,如月、日或周。ClickHouse 采用最佳努力方法,通过使用最小的分区集来最小化读取的数据。

建议阅读:

分片与复制

分片是一种允许将数据拆分到多个 ClickHouse 节点以增加吞吐量和减少延迟的功能。分片功能使用由本地表支持的分布式引擎。分布式引擎是一个不存储任何数据的"虚拟"表。它用作插入和查询数据的接口。

参见 ClickHouse 文档 和关于 复制与分片 的这一部分。ClickHouse 可以使用 Zookeeper 或通过称为 ClickHouse Keeper 的组件使用自己的兼容 API 来维护共识。

节点设置完成后,它们对客户端可能不可见,读写查询可以发送到任何节点。

在大多数情况下,集群通常从固定数量的节点(~分片)开始。重新平衡分片 操作繁重,需要严格测试。

MergeTree 表引擎支持复制,有关如何定义复制的详细信息,请参见文档中的 复制部分。 ClickHouse 依赖分布式协调组件(Zookeeper 或 ClickHouse Keeper)来跟踪仲裁中的参与节点。复制是异步的且多主架构。插入可以发送到任何节点,它们可能会在其他节点上以一些延迟出现。如果需要,可以使用粘性到特定节点来确保读取观察到最新写入的数据。

物化视图

ClickHouse 的一个标志性特征是物化视图。功能上,它们类似于 ClickHouse 的插入触发器。

我们建议阅读官方文档中的 视图 部分,以更好地了解它们的工作原理。

引用 文档

ClickHouse 中的物化视图实现更像插入触发器。 如果视图查询中有某些聚合,它只应用于新插入的数据批次。 源表现有数据的任何更改(如更新、删除、删除分区等)都不会改变物化视图。

安全且合理的默认设置

ClickHouse 实例应遵循以下安全建议:

用户

文件:users.xmlconfig.xml

主题 安全要求 原因
user_name/password 用户名不得为空。密码必须使用 password_sha256_hex不得为空。 plaintextpassword_double_sha1_hex 不安全。如果未指定用户名,则使用 default 且无密码
access_management 使用服务器 配置文件 users.xmlconfig.xml。避免 SQL 驱动的工作流。 SQL 驱动的工作流意味着至少有一个用户拥有 access_management,这可以通过配置文件避免。考虑到 “您不能同时通过两种配置方法管理同一个访问实体。”,这些文件也更容易审计和监控。
user_name/networks 必须设置至少一个 <ip><host><host_regexp>。不要使用 <ip>::/0</ip> 来开放任何网络的访问。 网络控制。(谨慎信任 原则)
user_name/profile 使用配置文件在多个用户上设置相似属性并设置限制(从用户界面)。 最小权限 原则和限制。
user_name/quota 尽可能为用户设置配额。 限制一段时间内的资源使用或跟踪资源使用情况。
user_name/databases 限制数据访问,避免拥有完全访问权限的用户。 最小权限 原则。

网络

文件:config.xml

主题 安全要求 原因
mysql_port 除非绝对必要,否则禁用 MySQL 访问:
<!-- <mysql_port>9004</mysql_port> -->
关闭不必要的端口和功能暴露。(纵深防御 原则)
postgresql_port 除非绝对必要,否则禁用 PostgreSQL 访问:
<!-- <mysql_port>9005</mysql_port> -->
关闭不必要的端口和功能暴露。(纵深防御 原则)
http_port/https_port & tcp_port/tcp_port_secure 配置 SSL-TLS,并禁用非 SSL 端口:
<!-- <http_port>8123</http_port> -->
<!-- <tcp_port>9000</tcp_port> -->
并启用安全端口:
<https_port>8443</https_port>
<tcp_port_secure>9440</tcp_port_secure>
加密传输中的数据。(纵深防御 原则)
interserver_http_host 如果 ClickHouse 配置为集群,则禁用 interserver_http_host,改用 interserver_https_host (<interserver_https_port>9010</interserver_https_port>)。 加密传输中的数据。(纵深防御 原则)

存储

主题 安全要求 原因
权限 ClickHouse 默认以 clickhouse 用户运行。永远不需要以 root 运行。对文件夹使用最小权限原则:/etc/clickhouse-server/var/lib/clickhouse/var/log/clickhouse-server。这些文件夹必须属于 clickhouse 用户和组,并且没有其他系统用户可以访问它们。 默认密码、端口和规则是"开放门"。(安全失败并使用安全默认值 原则)
加密 如果处理 RED 数据,请对日志和数据使用加密存储。在 Kubernetes 上,使用的 StorageClass 必须加密。GKEEKS 已经对所有静态数据进行了加密。在这种情况下,使用自己的密钥是最佳选择,但不是必需的。 加密静态数据。(纵深防御

日志

主题 安全要求 原因
logger Logerrorlog 必须clickhouse 定义并可写入。 确保日志被存储。
SIEM 如果托管在 GitLab.com 上,ClickHouse 实例或集群必须日志报告到我们的 SIEM(内部链接)。 GitLab 记录关键信息系统活动
日志敏感数据 如果可能记录敏感数据,则必须使用查询屏蔽规则。参见 示例屏蔽规则 列级加密 可能会在日志中泄露敏感数据(密钥)。

示例屏蔽规则

<query_masking_rules>
    <rule>
        <name>隐藏 SSN</name>
        <regexp>(^|\D)\d{3}-\d{2}-\d{4}($|\D)</regexp>
        <replace>000-00-0000</replace>
    </rule>
    <rule>
        <name>隐藏加密/解密参数</name>
        <regexp>
           ((?:aes_)?(?:encrypt|decrypt)(?:_mysql)?)\s*\(\s*(?:'(?:\'|.)+'|.*?)\s*\)
        </regexp>
        <replace>(???)</replace>
    </rule>
</query_masking_rules>