Buffer 表引擎
将要写入的数据缓冲到内存中,并定期将其刷新到另一个表。在读取操作期间,数据会同时从缓冲区和另一个表中读取。
Buffer 表引擎的推荐替代方案是启用异步插入。
Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes [,flush_time [,flush_rows [,flush_bytes]]])
引擎参数:
数据库
database
– 数据库名称。您可以使用currentDatabase()
或其他返回字符串的常量表达式。
表
table
– 要将数据刷新到的表。
num_layers
num_layers
– 并行层。从物理上讲,表将表示为num_layers
个独立的缓冲区。
min_time、max_time、min_rows、max_rows、min_bytes 和 max_bytes
从缓冲区刷新数据的条件。
可选引擎参数:
flush_time、flush_rows 和 flush_bytes
在后台刷新数据的条件(省略或为零表示没有flush*
参数)。
如果满足所有min*
条件或至少满足一个max*
条件,则数据将从缓冲区刷新并写入目标表。
此外,如果满足至少一个flush*
条件,则会在后台启动刷新。这与max*
不同,因为flush*
允许您单独配置后台刷新,以避免为INSERT
查询到 Buffer 表增加延迟。
min_time、max_time 和 flush_time
从第一次写入缓冲区开始的时间(以秒为单位)的条件。
min_rows、max_rows 和 flush_rows
缓冲区中行数的条件。
min_bytes、max_bytes 和 flush_bytes
缓冲区中字节数的条件。
在写入操作期间,数据会插入到一个或多个随机缓冲区(使用num_layers
配置)。或者,如果要插入的数据部分足够大(大于max_rows
或max_bytes
),则会直接写入目标表,而无需经过缓冲区。
每个num_layers
缓冲区的刷新条件是单独计算的。例如,如果num_layers = 16
且max_bytes = 100000000
,则最大内存消耗为 1.6 GB。
示例
CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 1, 10, 100, 10000, 1000000, 10000000, 100000000)
创建一个与merge.hits
结构相同的merge.hits_buffer
表,并使用 Buffer 引擎。写入此表时,数据将在内存中缓冲,然后写入“merge.hits”表。将创建一个缓冲区,并且如果满足以下任一条件,则将刷新数据:
- 自上次刷新以来已过去 100 秒(
max_time
),或 - 已写入 100 万行(
max_rows
),或 - 已写入 100 MB 数据(
max_bytes
),或 - 已过去 10 秒(
min_time
)并且已写入 10,000 行(min_rows
)和 10 MB(min_bytes
)数据
例如,如果只写入一行,则 100 秒后,无论如何都会刷新它。但如果写入许多行,则数据将更快刷新。
当服务器停止、使用DROP TABLE
或DETACH TABLE
时,缓冲数据也将刷新到目标表。
您可以在单引号中设置空字符串作为数据库和表名。这表示没有目标表。在这种情况下,当数据刷新条件满足时,缓冲区将简单地清除。这对于在内存中保留数据窗口可能很有用。
从 Buffer 表读取时,数据将同时从缓冲区和目标表(如果有)中处理。请注意,Buffer 表不支持索引。换句话说,缓冲区中的数据将被完全扫描,对于大型缓冲区来说,这可能会很慢。(对于从属表中的数据,将使用它支持的索引。)
如果 Buffer 表中的列集与从属表中的列集不匹配,则将插入两个表中都存在的列的子集。
如果 Buffer 表和从属表中某一列的类型不匹配,则会在服务器日志中输入错误消息,并且缓冲区将被清除。如果在刷新缓冲区时从属表不存在,也会发生这种情况。
如果服务器异常重启,缓冲区中的数据将丢失。
FINAL
和SAMPLE
对于 Buffer 表无法正常工作。这些条件将传递给目标表,但不会用于处理缓冲区中的数据。如果需要这些功能,我们建议仅使用 Buffer 表进行写入,同时从目标表读取。
向 Buffer 表添加数据时,将锁定其中一个缓冲区。如果同时从表中执行读取操作,这会导致延迟。
插入 Buffer 表的数据可能以不同的顺序和不同的块出现在从属表中。因此,Buffer 表难以用于正确写入 CollapsingMergeTree。为了避免问题,您可以将num_layers
设置为 1。
如果目标表是复制的,则在写入 Buffer 表时,复制表的某些预期特性将会丢失。行顺序和数据部分大小的随机更改会导致数据去重停止工作,这意味着无法对复制表进行可靠的“恰好一次”写入。
由于这些缺点,我们只能建议在极少数情况下使用 Buffer 表。
当在一单位时间内从大量服务器接收太多 INSERT 时,并且在插入之前无法缓冲数据,这意味着 INSERT 无法足够快地运行,此时可以使用 Buffer 表。
请注意,即使对于 Buffer 表,一次插入一行数据也没有意义。这只会产生每秒几千行的速度,而插入较大的数据块可以产生超过每秒一百万行的速度。