Перейти к основному содержимому
Перейти к основному содержимому

Движок таблицы 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

database – имя базы данных. Вы можете использовать currentDatabase() или другое постоянное выражение, возвращающее строку.

table

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 ГБ.

Пример:

CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 1, 10, 100, 10000, 1000000, 10000000, 100000000)

Создание таблицы merge.hits_buffer с той же структурой, что и merge.hits, и использование движка Buffer. При записи в эту таблицу данные буферизуются в ОЗУ и позже записываются в таблицу 'merge.hits'. Создается один буфер, и данные сбрасываются, если выполнено хотя бы одно из условий:

  • Прошло 100 секунд с момента последнего сброса (max_time) или
  • Записано 1 миллион строк (max_rows) или
  • Записано 100 МБ данных (max_bytes) или
  • Прошло 10 секунд (min_time) и записано 10 000 строк (min_rows) и 10 МБ (min_bytes) данных

Например, если была записана всего одна строка, после 100 секунд она будет сброшена, независимо от остальных условий. Но если было записано много строк, данные будут сброшены раньше.

Когда сервер останавливается с помощью DROP TABLE или DETACH TABLE, буферизованные данные также сбрасываются в целевую таблицу.

Вы можете задать пустые строки в одинарных кавычках для имени базы данных и таблицы. Это указывает на отсутствие целевой таблицы. В этом случае при достижении условий для сброса буфер просто очищается. Это может быть полезно для поддержания окна данных в памяти.

При чтении из таблицы Buffer данные обрабатываются как из буфера, так и из целевой таблицы (если такая имеется). Обратите внимание, что таблица Buffer не поддерживает индекс. Другими словами, данные в буфере полностью сканируются, что может быть медленно для больших буферов. (Для данных в подчиненной таблице будет использован поддерживаемый индекс).

Если набор колонок в таблице Buffer не совпадает с набором колонок в подчиненной таблице, вставляется подмножество колонок, которые существуют в обеих таблицах.

Если для одной из колонок в таблице Buffer и подчиненной таблице типы не совпадают, сообщение об ошибке записывается в журнал сервера, и буфер очищается. То же самое происходит, если подчиненная таблица не существует, когда буфер сбрасывается.

примечание

Запуск ALTER на таблице Buffer в релизах, выпущенных до 26 октября 2021 года, приведет к ошибке Несоответствие структуры блока (см. #15117 и #30565), поэтому единственным вариантом будет удалить таблицу Buffer и затем воссоздать её. Убедитесь, что эта ошибка исправлена в вашем релизе, прежде чем пробовать запустить ALTER на таблице Buffer.

Если сервер перезапускается аномально, данные в буфере теряются.

FINAL и SAMPLE не работают корректно для таблиц Buffer. Эти условия передаются в целевую таблицу, но не используются для обработки данных в буфере. Если эти функции необходимы, мы рекомендуем использовать таблицу Buffer только для записи, а при чтении — из целевой таблицы.

При добавлении данных в таблицу Buffer один из буферов блокируется. Это вызывает задержки, если одновременно выполняется операция чтения из таблицы.

Данные, вставленные в таблицу Buffer, могут оказаться в подчиненной таблице в другом порядке и в разных блоках. Из-за этого таблицу Buffer сложно использовать для корректной записи в CollapsingMergeTree. Чтобы избежать проблем, вы можете установить num_layers равным 1.

Если целевая таблица реплицируется, некоторые ожидаемые характеристики реплицируемых таблиц теряются при записи в таблицу Buffer. Случайные изменения порядка строк и размеров частей данных приводят к тому, что дедупликация данных перестает работать, что означает, что нельзя осуществить надежную запись 'ровно один раз' в реплицируемые таблицы.

Из-за этих недостатков мы можем рекомендовать использование таблицы Buffer лишь в редких случаях.

Таблица Buffer используется, когда слишком много INSERT-запросов поступает от большого количества серверов за единицу времени, и данные не могут быть буферизированы перед вставкой, что означает, что INSERT-запросы не могут выполняться достаточно быстро.

Обратите внимание, что нет смысла вставлять данные по одной строке, даже для таблиц Buffer. Это приведет только к скорости в несколько тысяч строк в секунду, в то время как вставка больших блоков данных может обеспечить более миллиона строк в секунду.