Clickhouse数据写入机制
Clickhouse数据写入方式
clickhouse数据写入方式由async_insert 和 wait_for_async_insert 两个参数控制
async_insert 作用于服务端
-
async_insert 默认为0,表示同步插入数据,每次插入数据都会在服务端生成一个分区目录(part),如图1所示
-
async_insert = 1,表示异步插入数据,服务端会攒够一定数据量的数据才会生成一个分区目录,并把数据写入分区目录(part)如图2所示,注意:这部分数据只有在数据写入分区目录之后才会被客户端查询到,
图1
wait_for_async_insert作用于客户端
- wait_for_async_insert 默认为1 ,等服务端把数据写入分区目录之后,才认为本次数据写入成功,如图2
- wait_for_async_insert = 0,数据传输到服务端之后,不等服务端把数据写入分区目录,立即返回成功,如图3
图2
图3
Clickhouse数据写入方式配置方法
- 用户级别设置,如下案例设置default用户使用异步方式写入数据
ALTER USER default SETTINGS async_insert = 1
- 插入数据时设置,如下案例表示本次插入数据使用异步方式写入数据,并且客户端等待服务端完成数据写入
INSERT INTO YourTable SETTINGS async_insert=1, wait_for_async_insert=1 VALUES (...)
- JDBC链接时设置,如下案例如下案例,改jdbc所有插入数据使用异步方式写入数据,并且客户端不等待服务端完成数据写入,这样能提升数据写入效率,但是当服务端异常重启有丢失数据的风险,由于写入过快影响服务端稳定性
"jdbc:ch://HOST.clickhouse.cloud:8443/?user=default&password=PASSWORD&ssl=true&custom_http_params=async_insert=1,wait_for_async_insert=0"
问题
1、当异步写入时,满足什么条件Clickhouse服务端会把内存数据刷写到磁盘?
当满足以下3个条件中任意一个时就会刷写磁盘:
- 缓存中数据大小超过 async_insert_max_data_size ,单位字节,默认值100000
- 距离本批次数据插入的第一个插入语句时间 async_insert_busy_timeout_ms,单位毫秒,默认值 200
- 本批次数据插入最大的插入次数 async_insert_max_query_number,单位 次,默认值:450,该参数只有在async_insert_deduplicate =1的情况下才会生效
总结
- 异步插入数据能够减少小批量频繁写入分区目录数
- 异步插入数据 先缓存在内存里,此时客户端不能立即查询到内存的数据。满足一定条件,刷写到磁盘之后数据才对客户端可见
参考资料
https://clickhouse.com/docs/en/optimize/asynchronous-inserts#enabling-asynchronous-inserts
https://clickhouse.com/docs/knowledgebase/are_materialized_views_inserted_asynchronously