异步插入 (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
您可以使用 INSERT 查询的 SETTINGS 子句来指定异步插入设置
INSERT INTO YourTable SETTINGS async_insert=1, wait_for_async_insert=1 VALUES (...)
您还可以使用 ClickHouse 编程语言客户端,将异步插入设置指定为连接参数。
例如,当您使用 ClickHouse Java JDBC 驱动程序连接到 ClickHouse Cloud 时,这是在 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 服务器需要减慢写入速度并创建一些反压以确保服务可靠性时继续快速写入。