【发布时间】:2021-11-07 19:44:11
【问题描述】:
我正在编写一个应用程序来绘制财务数据并与此类数据的实时馈送进行交互。由于任务的性质,实时市场数据可能会以一次一笔交易的方式非常频繁地接收。我在本地使用数据库,我是唯一的用户。只有一个程序(我的中间件)会将数据插入数据库。我主要关心的是延迟——我想尽可能地减少它。出于这个原因,我想避免使用队列(从某种意义上说,我希望 Buffer Table 来完成这个角色)。 Clickhouse 为我计算的许多分析预计也是实时的(尽可能)。我有三个问题:
- 澄清缓冲区表文档中的一些限制/警告
- 阐明查询的工作原理(常规查询 + 物化视图)
- 当我在刷新数据时查询数据库时会发生什么
问题 1)澄清缓冲区表文档中的一些限制/警告
根据 Clickhouse 文档,我了解到许多小型 INSERT 至少可以说是次优的。在研究该主题时,我发现缓冲区引擎 [1] 可以用作解决方案。这对我来说很有意义,但是当我阅读 Buffer 的文档时,我发现了一些警告:
请注意,一次插入一行数据是没有意义的,即使对于 Buffer 表也是如此。这只会产生每秒几千行的速度,而插入更大的数据块每秒可以产生超过一百万行(参见“性能”部分)。
每秒几千行对我来说绝对没问题,但是我担心其他性能问题 - 如果我确实一次将数据提交到缓冲区表中的一行,我是否应该预期 CPU/内存会出现峰值?如果我理解正确,一次将一行提交到 MergeTree 表会导致合并作业的大量额外工作,但如果使用 Buffer Table 应该不是问题,对吗?
如果服务器异常重启,缓冲区中的数据会丢失。
我了解这指的是停电或计算机崩溃等情况。如果我正常关机或者正常停止clickhouse服务器,是否可以期待buffer把数据刷到目标表?
问题 2) 阐明查询的工作原理(常规查询 + 物化视图)
从缓冲区表中读取数据时,会同时处理来自缓冲区和目标表(如果有的话)的数据。 请注意,缓冲区表不支持索引。换句话说,缓冲区中的数据被完全扫描,这对于大缓冲区可能会很慢。 (对于从属表中的数据,将使用其支持的索引。)
这是否意味着我可以对目标表使用查询并期望自动包含缓冲区表数据?还是反过来 - 我查询缓冲区表并且目标表包含在后台?如果其中任何一个为真(并且我不需要手动聚合两个表),这是否也意味着物化视图将被填充?哪个表应该触发物化视图——磁盘表还是缓冲表?或者两者兼而有之?
我非常依赖物化视图,需要实时更新(或尽可能接近)。实现该目标的最佳策略是什么?
问题 3) 在刷新数据时查询 db 会发生什么?
我主要关心的两个问题是:
- 在刷新发生的确切时间运行查询 - 是否存在重复记录或遗漏记录的风险?
- 在什么时候填充目标表的物化视图(我想这取决于触发 MV 的是目标表还是缓冲表)?刷新缓冲区对我如何构建 MV 很重要吗?
感谢您的宝贵时间。
[1]https://clickhouse.tech/docs/en/engines/table-engines/special/buffer/
【问题讨论】: