批量或异步插入数据

本文介绍如何在云数据库ClickHouse中批量或异步插入数据。

批量插入数据

默认情况下,每个发送到云数据库ClickHouse的插入操作都会导致云数据库ClickHouse立即在存储中创建一个包含插入的数据以及其他需要存储的元数据信息。因此,相比较发送包含较少数据的大量插入操作,发送包含更多数据的较少插入操作可以减少写入次数。

通常情况下,建议您每次插入数据时使用至少1000行的较大批次,理想情况下在10000到100000行之间。为实现这一目标,考虑实施缓冲机制,比如使用Buffer表引擎来实现批量插入,或者使用异步插入。异步插入数据的详细信息,请参见异步插入数据

说明

无论插入数据的大小如何,建议您插入数据后保持在每秒一个插入查询(即包含INSERT的查询语句)。因为创建的数据分区会在后台合并成更大的分区(以优化读取查询的数据),每秒发送太多的插入查询可能会导致后台合并无法跟上新分区的数量。然而,当您使用异步插入数据时,可以使用更高速的插入查询速率。异步插入数据的详细信息,请参见异步插入数据

异步插入数据

云数据库ClickHouse适合大批次的数据写入方式,这样可以节省计算周期和磁盘I/O,节省成本。在client端常用的写入方式为批量写入,如果想在ClickHouse Server侧支持批量写入,可以使用异步插入模式。

启动异步写入方式需要启用async_insert设置,具体操作请参见async_insert。默认情况下,云数据库ClickHouse以同步方式写入数据。每个插入操作都会导致云数据库ClickHouse立即创建一个包含插入数据的分区。这是当async_insert设置保持其默认值0时的默认行为:image.png

通过将async_insert设置为1,云数据库ClickHouse首先将传入的插入操作存储到内存缓冲区,然后定期将它们刷新到磁盘上。

有两种可能的情况会导致云数据库ClickHouse将缓冲区刷新到磁盘上:

  • 缓冲区已达到N KB的大小(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(默认值:100,单位:KB)设置时,在数据被写入存储的分区后,数据就可以供查询使用。

通过wait_for_async_insert设置,您可以配置是否希望在数据被插入缓冲区后(wait_for_async_insert = 0)或默认情况下,在数据从缓冲区刷新后写入部分之后(wait_for_async_insert = 1)立即返回插入语句的确认。设置wait_for_async_insert的具体操作,请参见wait_for_async_insert

以下两个图示说明了async_insertwait_for_async_insert的两种设置:image.png

image.png

如何启用异步插入

您可以为特定用户或特定查询启用异步插入:

  • 在用户级别启用异步插入。此示例使用默认用户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企业版时,可以在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=1wait_for_async_insert=1。使用wait_for_async_insert=0非常危险,因为INSERT客户端不知道是否存在错误,且客户端如果在ClickHouse服务器需要减缓写入并产生一些反向压力以确保服务可靠性的情况下,如果继续快速写入可能会导致服务器过载。

说明

在使用异步插入时,默认会禁用自动去重。

手动批处理的优点是,如果相同的插入语句多次发送到云数据库ClickHouse企业版(例如,由于客户端软件中的自动重试导致了一些暂时的网络连接问题),它支持表数据的默认自动去重。