Clickhouse中有多个小插件

时间:2016-11-14 15:13:55

标签: clickhouse

我在clickhouse中有一个事件表(MergeTree),并希望同时运行很多小插入。但是,服务器变得过载并且没有响应。而且,一些插入物丢失了。 clickhouse错误日志中有很多记录:

01:43:01.668 [ 16 ] <Error> events (Merger): Part 201 61109_20161109_240760_266738_51 intersects previous part

有没有办法优化此类查询?我知道我可以使用批量插入来处理某些类型的事件。基本上,运行一个带有许多记录的插入,clickhouse处理得非常好。但是,某些事件(例如点击或打开)无法以这种方式处理。

另一个问题:为什么clickhouse决定存在类似记录,何时不存在?插入时有类似的记录,它们与索引中的字段相同,但其他字段不同。

我还会不时收到以下错误:

Caused by: ru.yandex.clickhouse.except.ClickHouseUnknownException: ClickHouse exception, message: Connect to localhost:8123 [ip6-localhost/0:0:0:0:0:0:0:1] timed out, host: localhost, port: 8123; Connect to ip6-localhost:8123 [ip6-localhost/0:0:0:0:0:0:0:1] timed out
    ... 36 more

主要是在项目构建期间运行针对clickhouse数据库的测试时。

5 个答案:

答案 0 :(得分:5)

将大量小插入处理到(非复制)MergeTree时,这是已知问题。

这是一个错误,我们需要调查并修复。

对于变通方法,您应该按照建议大批量发送插入:大约每秒一批:https://clickhouse.yandex/reference_en.html#Performance%20on%20data%20insertion

答案 1 :(得分:4)

我遇到过类似的问题,虽然没有那么糟糕 - 每秒约20次插入导致服务器达到高负载,内存消耗和CPU使用率。我创建了一个缓冲表,用于缓冲内存中的插入,然后定期刷新到&#34; real&#34;磁盘表。就像魔术一样,一切都很顺利:loadavg,内存和CPU使用率都降到了正常水平。好处是你可以对缓冲表运行查询,并从内存和磁盘中获取匹配的行 - 因此客户端不受缓冲的影响。见https://clickhouse.yandex/docs/en/table_engines/buffer.html

答案 2 :(得分:1)

Clickhouse为此具有特殊的表格类型-缓冲区。它存储在内存中,并允许许多小的插入而没有问题。每秒大约有200种不同的插入效果-效果很好。

缓冲区表:

CREATE TABLE logs.log_buffer (rid String, created DateTime, some String, d Date MATERIALIZED toDate(created)) ENGINE = Buffer('logs', 'log_main', 16, 5, 30, 1000, 10000, 1000000, 10000000);

主表:

CREATE TABLE logs.log_main (rid String, created DateTime, some String, d Date) ENGINE = MergeTree(d, sipHash128(rid), (created, sipHash128(rid)), 8192);

手册中的详细信息:https://clickhouse.yandex/docs/en/operations/table_engines/buffer/

答案 3 :(得分:0)

或者,您可以使用类似https://github.com/nikepan/clickhouse-bulk的东西:它将缓冲多个插入并根据用户策略将它们全部刷新。

答案 4 :(得分:0)

clickhouse MergeEngines 的设计并不意味着同时进行小写操作。据我所知,MergeTree 将写入表的数据 parts 合并到基于分区中,然后重新组织 parts 以获得更好的聚合读取。如果我们经常做小写,你会遇到另一个例外 Merge

Error: 500: Code: 252, e.displayText() = DB::Exception: Too many parts (300). Merges are processing significantly slow

当您尝试理解为什么会抛出上述异常时,您的想法会更加清晰。 CH需要合并数据,并且可以存在多少部分是有上限的!并且批处理中的每个写入都作为一个新部分添加,然后最终与分区表合并。

SELECT
    table, count() as cnt
FROM system.parts 
WHERE database = 'dbname' GROUP BY `table` order by cnt desc

上面的查询可以帮助你监控部分,在写的时候观察这些部分是如何增加并最终合并的。

我最好的选择是缓冲数据集并定期将其刷新到数据库,但这意味着没有实时分析。

使用缓冲区很好,但请考虑以下几点:

  • 如果服务器异常重启,缓冲区中的数据会丢失。
  • FINAL 和 SAMPLE 不能正确用于缓冲表。这些条件传递给目标表,但不用于处理缓冲区中的数据
  • 向缓冲区添加数据时,其中一个缓冲区被锁定。 (所以没有读取)
  • 如果目标表被复制,则在写入缓冲表时会丢失复制表的某些预期特征。 (无重复数据删除)

请通读一遍,这是一个特例引擎:https://clickhouse.tech/docs/en/engines/table-engines/special/buffer/