22.10? (не помню точно).
И появилась такая проблема - заливаем данные батчом через distributed таблицу на одной из нод кластера в data таблицы кластера. Данные оперативно передаются на принимающую ноду за 20 минут со скоростью под 10Гбит/с в 200 потоков, а далее начинают распределяться по нодам кластера в data таблицы. Раньше этот процесс распределения занимал около 1-1.5 часов, а после обновления вырос до 7.5-8 часов.
Предполагаю что появился какой-то лимит/настройка, только знать бы какой. Как можно в такой конфигурации ускорить процесс передачи данных по кластеру? Лить данные напрямую в data таблицы пока не планировали, в целом устраивает простота загрузки для etl процесса.
https://clickhouse.com/docs/en/operations/server-configuration-parameters/settings#background_distributed_schedule_pool_size background_distributed_schedule_pool_size: 256 попробуйте поставить в настройках сервера в config.d
Спасибо, попробуем. Также думаю включить отправку файлов батчами (distributed_directory_monitor_batch_inserts) и понаблюдаю за файлами на отправку в директории /var/lib/clickhouse/data/database/table/
там метрики есть в system.metircs кол-во не отправленных distibuted файлов
подняли background_distributed_schedule_pool_size, но возможно он уперся в background_pool_size и его также нужно поднять. Но проблема в чем-то еще - число BackgroundDistributedSchedulePoolTask при загрузке данных не растет, и даже упало с 3 до 1, а при этом DistributedFilesToInsert выросло значительно. Что может мешать поднимать дополнительные фоновые задачи на раздачу данных по кластеру? metric |value | -------------------------------------|------------| BackgroundDistributedSchedulePoolTask| 1| BackgroundDistributedSchedulePoolSize| 16| DistributedSend | 1| StorageDistributedThreads | 0| StorageDistributedThreadsActive | 0| DistributedInsertThreads | 0| DistributedInsertThreadsActive | 0| DistributedBytesToInsert |167842821978| BrokenDistributedBytesToInsert | 0| DistributedFilesToInsert | 39563| BrokenDistributedFilesToInsert | 0|
SYSTEM START DISTIRBUTED SENDS может остановил кто что...
Напишу здесь результаты postmortem, возможно кому-то пригодится ) Процессы-писатели отдавали на принимающую ноду с distributed таблицей порядка 150Гб данных, по времени загрузка шла около 20 минут. Далее distributed таблица раскидывала данные по нодам кластера, включая эту же ноду. Вылетало 2 вида ошибок - wait timeout в 120с для процесса-писателя и too many parts на конечных дата нодах. Полечили повышением таймаута для писателей (подняли до 600 секунд), явным включением async_insert по дата нодам и повышением лимитов по буферу для асинхронной вставки - время ожидания подняли до 60 секунд и размер поставили с запасом в 500Мб. В общем что-то поменялось в версиях клика в 2023 году, и пришлось повозиться с настройками чтобы процессы загрузки отрабатывали как прежде... name |value | -----------------------------|---------| async_insert_deduplicate |1 | async_insert |1 | wait_for_async_insert |1 | wait_for_async_insert_timeout|600 | async_insert_max_data_size |500000000| async_insert_busy_timeout_ms |60000 |
too many parts, на 23.x надо еще умудриться схватить... там костылей вагон для того чтобы это хендлить правильно может оно у вас там именно вставка стала другой? размер батча на вставку банально снизился? а вы clickhouse бросились тюнить... system.part_log есть ? смотрите целевую таблицу на rows и event_type='NewPart' до апдейта и после апдейта...
размер исходного батча на вставку был 500К записей, сейчас подняли до 1М в system.part_log для целевой таблицы картина до и после обновления не сильно поменялась - в среднем по 1500 строк на парт, порядка 1.5М записей с типом NewPart до обновления и стало 0.5М-1М записей после обновления (тут сложно вычленять упавшие по внешнему таймауту загрузки)
эти 500 к сплитуются по шардам... и в итоговую таблицу будет меньше размер чанка
1500 строк на парт, не вяжется с 500к записей на один инсерт в initiator node
я привел статистику для MergeTree таблицы на одной дата ноде
и надо смотреть не среднее. а quantiles(0.5,0.9)(rows)
согласен, но ведь Distributed каким-то образом делает распределение данных по кластеру на основе функции шардирования
ну так если на вход distributed 500к строк... за ОДИН INSERT (размер батча) и у вас допустим 5 шардов... то это никак не может быть тогда в целевой ноде всего 1500 строк на новый парт...
квантили такие:1000 - 2500 были
сколько шардов? если 5 шардов. то значит вставляете не по 500к а по 50k на порядок меньше...
4 шарда
в моем понимании distributed движок кэширует входящие данные во временные файлы (DistributedFilesToInsert) и затем из них формирует новые батчи для отправки на шарды, при этом данные группирует согласно функции шардирования
значит вставляете от 4000 до 10000 в один INSERT SELECT event_date, hostName() h, quantiles(0.5,0.9)(writen_rows) FROM clusterAllReplicas('cluster_name',system.query_log) WHERE is_initial_query AND has(tables,'db.distributed_table') AND event_type='QueryFinish' GROUP BY event_date, h ORDER BY h, event_date written_rows смотрите
нет, это не кеширование это сплитование по функции шардирования сразу во время вставки. в .bin файлы формата Native с раскладкой по каталогам и в дальнейшем обычный INSERT INTO ... FORMAT Native на целевой шард, в зависимости от internal_replication на одну реплику или на несколько...
честно показывает 500К и 500К записей до обновления, и после обновления стало так: [0.0,500000.0] [0.0,2000000.0] 2млн - видимо там коллега поставил 2 а не 1млн
репликации у нас нет а какой объем он передает на шард? сразу 1 файл отдает или дробит на батчи?
откуда 0.0 на 50% персентиле? https://fiddle.clickhouse.com/e800e37a-2afc-46b5-97ed-3625b724ea3f WHERE event_type='QueryFinish' забыли?
один файл .bin за один INSERT на целевой шард... но если вы 2 000 000 строк вставляете ... то это по 500 000 строк в одном .bin файле должно быть... а не по 1500 ... где то у вас что-то не сходится...
type='QueryFinish' не забыл, в логе и правда много записей с written_rows=0 возможно это упавшие передачи, которые в итоге ничего не записали?
оно тогда не может быть is_initial_query и QueryFinish если written_rows =0 то что упало оно с другим статусом завершается... ну то есть у вас клиент мог недождаться ответа и отключиться... но тогда все равно ошибка при попытке записать в клиентский сокет результат ответа... и статус не QueryFinish покажите пример из лога с SELECT * FROM system.query_log WHERE ... AND written_rows=0 AND event_date=today() LIMIT 1 FORMAT Vertical
нужно было еще условие добавить and query_kind='Insert'
а да, забыл... ну и что с персентилями стало?
Обсуждают сегодня