异步插入 (async_insert)
将数据以大批量插入 ClickHouse 是最佳实践。它节省了计算周期和磁盘 I/O,因此也节省了资金。如果您的用例允许您在 ClickHouse 外部对插入进行批处理,那么这是一种选择。如果您希望 ClickHouse 创建批处理,则可以使用此处描述的异步 INSERT 模式。
将异步插入用作在客户端对数据进行批处理和通过启用 async_insert 设置将插入速率保持在每秒大约一个插入查询的替代方案。这会导致 ClickHouse 在服务器端处理批处理。
默认情况下,ClickHouse 正在同步写入数据。发送到 ClickHouse 的每个插入都会导致 ClickHouse 立即创建一个包含插入数据的块。这是 async_insert 设置设置为其默认值 0 时,默认的行为。
通过将 async_insert 设置为 1,ClickHouse 首先将传入的插入存储到内存缓冲区中,然后再定期将其刷新到磁盘。
有两种可能的情况会导致 ClickHouse 将缓冲区刷新到磁盘
- 缓冲区大小已达到 N 字节(N 可通过 async_insert_max_data_size 配置)。
- 自上次缓冲区刷新以来已至少经过 N 毫秒(N 可通过 async_insert_busy_timeout_ms 配置)。
每次满足上述任何条件时,ClickHouse 都会将其内存缓冲区刷新到磁盘。
数据写入存储中的一个块后,即可用于读取查询。请记住这一点,以便了解您希望何时修改 async_insert_busy_timeout_ms
(默认设置为 1 秒)或 async_insert_max_data_size
(默认设置为 10 MiB)设置。
使用 wait_for_async_insert 设置,您可以配置是否希望插入语句在数据插入缓冲区后立即返回确认(wait_for_async_insert = 0)或者,默认情况下,在数据从缓冲区刷新后写入块后返回确认(wait_for_async_insert = 1)。
以下两个图示说明了 async_insert 和 wait_for_async_insert 的两种设置。
启用异步插入
可以为特定用户或特定查询启用异步插入。
在用户级别启用异步插入。此示例使用用户
default
,如果您创建其他用户,则替换该用户名。ALTER USER default SETTINGS async_insert = 1
您可以使用插入查询的 SETTINGS 子句指定异步插入设置。
INSERT INTO YourTable SETTINGS async_insert=1, wait_for_async_insert=1 VALUES (...)
您也可以在使用 ClickHouse 编程语言客户端时将异步插入设置指定为连接参数。
例如,以下是如何在使用 ClickHouse Java JDBC 驱动程序连接到 ClickHouse 云时在 JDBC 连接字符串中执行此操作。
"jdbc:ch://HOST.clickhouse.cloud:8443/?user=default&password=PASSWORD&ssl=true&custom_http_params=async_insert=1,wait_for_async_insert=1"
我们强烈建议在使用异步插入时使用 async_insert=1,wait_for_async_insert=1。使用 wait_for_async_insert=0 风险很大,因为您的 INSERT 客户端可能不知道是否存在错误,并且还会在 ClickHouse 服务器需要降低写入速度并在一定程度上增加背压以确保服务可靠性的情况下,可能导致潜在的过载。
手动批处理(请参阅 上面的部分)的优点是,如果(完全)相同的插入语句多次发送到 ClickHouse 云,例如,由于客户端软件中的自动重试(由于某些临时网络连接问题),它支持 内置的自动重复数据删除 表数据。