Рекомендации по загрузке и настройке производительности
Загрузка данных — одна из важнейших возможностей Apache Doris. Эффективность загрузки напрямую определяет своевременность аналитики в реальном времени и стабильность системы. Опираясь на типичные бизнес-сценарии, эта статья сначала предлагает рекомендации, которые можно сразу применить на практике, а затем подробно рассматривает внутренние механизмы загрузки и подход к настройке, чтобы помочь вам:
- Выбрать подходящий способ загрузки с учётом особенностей бизнеса
- Принимать обоснованные решения при проектировании таблиц, пакетной обработке, распределении по бакетам, настройке памяти и параллелизма
- Избежать распространённых проблем, таких как частые загрузки небольших объёмов данных, усиление записи и Memtable OOM
- Найти баланс между задержкой и пропускной способностью, соответствующий потребностям бизнеса
Быстрая навигация
| Задача | Рекомендация | Раздел |
|---|---|---|
| Выбор способа загрузки | Выбирайте с учётом источника данных и требований к работе в реальном времени | Выбор подходящего способа загрузки |
| Модель таблицы | Отдавайте предпочтение модели Duplicate Key | Модель таблицы и индексы |
| Партиционирование и распределение по бакетам | Поддерживайте размер одного Tablet в пределах от 1 до 10 GB | Настройка партиционирования и распределения по бакетам |
| Случайное распределение по бакетам | Включите load_to_single_tablet для повышения пропускной способности | Оптимизация загрузки при случайном распределении по бакетам |
| Частые загрузки небольших объёмов данных | Объединяйте данные в пакеты на стороне клиента и используйте Group Commit | Стратегия пакетной загрузки |
| Число партиций на одну загрузку | Ограничивайте его небольшим значением, чтобы не создавать слишком много Memtable | Загрузка партиций и контроль памяти |
| Загрузка большого объёма данных | Разбивайте данные на пакеты размером не более 100 GB каждый | Пакетная загрузка больших объёмов данных |
| Параллелизм Broker Load | Разбивайте сжатые файлы или файлы колоночных форматов для параллельной загрузки | Параллелизм Broker Load |
| Параллелизм Stream Load | Поддерживайте параллелизм на каждом BE ниже 128 | Параллелизм Stream Load |
Выбор подходящего способа загрузки
Doris предоставляет несколько способов загрузки с общим основным процессом, каждый из которых оптимизирован для определённых сценариев. Выбирайте способ с учётом источника данных и бизнес-требований:
| Способ загрузки | Протокол | Режим выполнения | Типичные источники данных | Сценарии применения |
|---|---|---|---|---|
| Stream Load | HTTP | Синхронный | Локальные файлы, потоки данных | Запись в реальном времени (например, отправка данных приложениями) |
| Broker Load | SQL | Асинхронный | HDFS, S3 и другие внешние хранилища | Пакетная загрузка больших объёмов данных |
| Routine Load | SQL | Асинхронный потоковый | Kafka | Синхронизация данных из очередей сообщений в реальном времени с поддержкой Exactly-Once |
| Insert Into / Select | SQL | Синхронный/асинхронный | Таблицы Doris, Hive, MySQL, S3 TVF | Задачи ETL, интеграция внешних данных |
| MySQL Load | MySQL LOAD DATA | Синхронный | Локальные файлы CSV | Небольшие тесты или миграция для пользователей MySQL (FE перенаправляет запрос как Stream Load) |
Рекомендации по загрузке
В следующих разделах рассматриваются распространённые задачи загрузки данных и приводятся рекомендации, которые можно сразу применить на практике.
Модель таблицы и индексы
Выбор модели таблицы
Отдавайте предпочтение модели Duplicate Key:
- Она хранит только исходные данные, без агрегации и дедупликации, поэтому путь загрузки наиболее короткий.
- Она превосходит другие модели по производительности как загрузки, так и запросов.
- Модель Aggregate требует агрегации по столбцам Key, а модель Unique Key — дедупликации. Обе модели добавляют вычисления (сортировку, дедупликацию) на стороне BE на этапе MemTable и увеличивают потребление CPU и памяти.
Выбирайте модель Aggregate или Unique Key только тогда, когда действительно нужна агрегация или дедупликация по Key. Подробнее см. в разделе Модель данных.
Управление индексами
Индексы (например, bitmap-индексы и инвертированные индексы) необходимо синхронно обновлять во время загрузки, что увеличивает затраты на обслуживание записи. Рекомендации:
- Создавайте индексы только для полей, которые часто используются в запросах.
- Избегайте избыточных индексов, чтобы сократить объём построения и проверки индексов на BE при записи, снизить потребление CPU и памяти и повысить пропускную способность загрузки.
Настройка партиционирования и распределения по бакетам
Партиционирование и распределение по бакетам определяют распределение данных между узлами BE и степень параллелизма, напрямую влияя на производительность загрузки и запросов.
Размер одного Tablet: 1-10 GB
Поддерживайте размер одного Tablet в пределах от 1 до 10 GB:
| Размер Tablet | Влияние |
|---|---|
| Слишком маленький | Низкая эффективность агрегации, повышенная нагрузка на управление метаданными |
| Слишком большой | Затрудняет перенос и восстановление реплик |
| 1-10 GB (рекомендуется) | Обеспечивает баланс между загрузкой, запросами и управлением репликами |
Формула числа бакетов: bucket count = total data size / (1-10 GB). Дополните её подходящим ключом распределения по бакетам (например, столбцом со случайными значениями), чтобы избежать перекоса данных, сбалансировать нагрузку между узлами BE и повысить эффективность параллельной записи.
Подробнее см. в разделе Распределение данных.
Проектирование партиций: снижение нагрузки на распределение и память
Выбирайте партиционирование в соответствии с характером бизнес-запросов (например, по времени или региону), чтобы во время загрузки данные распределялись только по целевым партициям и не требовалось обрабатывать метаданные и файлы остальных партиций. Кроме того:
- Одновременная запись в несколько партиций активирует большое число Tablet. Каждый Tablet занимает собственную MemTable, что значительно увеличивает нагрузку на память BE.
- При нехватке памяти запускается преждевременный Flush, который создаёт множество небольших файлов Segment и приводит к частой Compaction и усилению записи.
Ограничивая число активных партиций (например, загружая данные по дням), можно сократить число одновременно активных Tablet, снизить нагрузку на память, формировать более крупные файлы Segment и уменьшить нагрузку от Compaction, тем самым повышая эффективность параллельной записи и производительность последующих запросов.
Оптимизация загрузки при случайном распределении по бакетам
При случайном распределении по бакетам можно включить режим загрузки в один Tablet, задав load_to_single_tablet=true:
- Данные записываются непосредственно в один Tablet, минуя распределение между несколькими Tablet. Это устраняет затраты CPU на вычисления для распределения по Tablet, а также затраты на передачу по RPC между BE.
- Сосредоточение записи в одном Tablet уменьшает число создаваемых небольших файлов Segment и позволяет избежать усиления записи из-за частой Compaction.
- Это значительно повышает параллелизм и пропускную способность загрузки больших объёмов данных.
Подробнее см. в разделе Случайное распределение по бакетам.
Стратегия пакетной загрузки
Каждая загрузка представляет собой отдельную транзакцию, которая включает запись в FE Edit Log (фиксацию изменений метаданных) и сброс MemTable на BE на диск (создание файлов Segment). Частые загрузки небольших пакетов (размером порядка KB) приводят к следующим последствиям:
- Частые записи в FE Edit Log увеличивают дисковый I/O на FE.
- Частые сбросы MemTable на BE создают множество небольших файлов Segment.
- Частая Compaction приводит к сильному усилению записи.
Эти последствия можно смягчить, сочетая объединение данных в пакеты на стороне клиента и сервера:
| Способ объединения в пакеты | Сценарии применения | Рекомендация |
|---|---|---|
| Объединение в пакеты на стороне клиента | Пакетная запись, которой управляет клиент | Перед запуском загрузки накапливайте на клиенте от сотен MB до нескольких GB данных. Замена множества небольших транзакций одной крупной снижает частоту записей в FE Edit Log и сбросов MemTable на BE, позволяя избежать фрагментации хранилища и затрат ресурсов на последующую Compaction. |
| Объединение в пакеты на стороне сервера (Group Commit) | Загрузки небольших объёмов данных с высоким параллелизмом | Включите Group Commit, чтобы сервер объединял несколько небольших пакетов, поступивших за короткий интервал, в одну транзакцию. Полученная крупная транзакция создаёт более крупные файлы Segment и снижает нагрузку от фоновой Compaction. Это особенно подходит для сценариев частой загрузки небольших пакетов, например журналов и данных IoT. |
Загрузка партиций и контроль памяти
Во время загрузки BE сначала записывает данные в MemTable в оперативной памяти (по умолчанию 200 MB). Когда MemTable заполняется, она асинхронно сбрасывается на диск с созданием файлов Segment. У каждого Tablet в памяти есть одна активная MemTable, поэтому число партиций, охватываемых одной загрузкой, напрямую влияет на потребление памяти:
- Слишком большое число партиций приводит к большому числу активных Tablet, а значит, и активных MemTable, что увеличивает потребление памяти.
- При слишком высоком потреблении памяти запускается преждевременный сброс, чтобы избежать OOM процесса.
- Преждевременные сбросы создают множество небольших файлов, что ещё сильнее снижает производительность загрузки.
Чтобы обеспечить стабильную пропускную способность загрузки:
- Загружайте партиции по порядку: например, загружайте данные по дням, чтобы сосредоточить запись в одной партиции, сократить распределение данных по разным MemTable и число сбросов, а также снизить фрагментацию памяти и нагрузку на I/O.
- Строго контролируйте число партиций, охватываемых одной загрузкой, чтобы избежать преждевременных сбросов из-за слишком большого числа MemTable.
Пакетная загрузка больших объёмов данных
Если файлов много и объём данных очень велик, загружайте данные пакетами, чтобы снизить затраты на повторные попытки и избежать резких пиков нагрузки на память и диски BE:
| Источник данных | Рекомендуемый способ загрузки | Рекомендуемый размер пакета |
|---|---|---|
| Удалённые файлы, например в HDFS или объектном хранилище | Broker Load | Каждый пакет не более 100 GB |
| Большие локальные файлы | Инструмент Doris streamloader (автоматическое разбиение на пакеты) | Автоматически определяется инструментом |
Параллелизм Broker Load
Стратегия параллельной загрузки зависит от типа файлов:
- Сжатые файлы / файлы Parquet / ORC: перед загрузкой разбивайте их на несколько файлов меньшего размера, чтобы обеспечить параллельную загрузку.
- Несжатые файлы CSV и JSON: Doris автоматически разбивает файлы внутри системы и загружает их параллельно.
О стратегии параллельной загрузки см. в разделе Параметры настройки Broker Load.
Параллелизм Stream Load
Параллелизм Stream Load ограничивается параметрами пулов потоков BE. Соблюдайте следующие пороговые значения:
| Параметр / порог | Рекомендуемое значение | Описание |
|---|---|---|
| Параллелизм на каждом BE (рекомендуемая верхняя граница) | Не более 128 | Определяется параметром BE webserver_num_workers. Превышение может исчерпать потоки веб-сервера и снизить производительность загрузки. |
| Параллелизм на каждом BE (жёсткое ограничение) | Не должен превышать 512 | Определяется параметром doris_max_remote_scanner_thread_pool_thread_num. Превышение может привести к зависанию процесса BE. |
Выбор параллелизма для сценариев с низкой задержкой
Для сценариев с низкой задержкой, таких как мониторинг в реальном времени:
- Умеренно снижайте параллелизм, чтобы избежать конкуренции за ресурсы.
- Сочетайте это с асинхронным режимом (
async_mode) Group Commit, чтобы объединять небольшие транзакции и сокращать задержку их фиксации.
Подробно о внутренних механизмах загрузки Doris
Понимание следующих механизмов поможет принимать более обоснованные решения по настройке в сложных сценариях.
Принципы проектирования
Загрузка данных в Doris опирается на распределённую архитектуру, в которой основную роль играют узлы Frontend (FE) и Backend (BE):
- FE: отвечает за управление метаданными, разбор запросов, планирование задач и координацию транзакций.
- BE: отвечает за непосредственное хранение данных, вычисления и операции записи.
Механизм загрузки данных рассчитан на разнообразные бизнес-потребности: запись в реальном времени, потоковую синхронизацию, пакетную загрузку и интеграцию внешних источников данных. Его основные принципы:
| Цель проектирования | Реализация |
|---|---|
| Согласованность и атомарность | Каждая задача загрузки является транзакцией, что обеспечивает атомарную запись данных и исключает частичную запись. Механизм Label гарантирует отсутствие потерь и дублирования данных. |
| Гибкость | Поддерживаются различные источники данных (локальные файлы, HDFS, S3, Kafka и другие) и форматы (CSV, JSON, Parquet, ORC и другие) для разных сценариев. |
| Эффективность | Распределённая архитектура обеспечивает параллельную обработку данных: несколько узлов BE обрабатывают данные одновременно, повышая пропускную способность. |
| Простота | Предоставляются облегчённые возможности ETL для очистки и преобразования данных во время загрузки, что снижает зависимость от внешних инструментов. |
| Гибкое моделирование | Поддерживаются модели Duplicate Key, Unique Key и Aggregate Key, позволяющие выполнять агрегацию или дедупликацию данных во время загрузки. |
Общий процесс загрузки
Независимо от способа загрузки (Stream Load, Broker Load, Routine Load и другие) основной процесс практически одинаков:
-
Отправка задачи загрузки
- Вы отправляете запрос на загрузку через клиент (например, HTTP, JDBC или клиент MySQL), указывая источник данных (например, локальный файл, топик Kafka или путь к файлу HDFS), целевую таблицу, формат файла и параметры загрузки (например, разделитель и допустимый уровень ошибок).
- Для каждой задачи можно указать уникальную Label, чтобы идентифицировать задачу и обеспечить идемпотентность (предотвращение повторной загрузки). Например, в Stream Load значение Label задаётся через HTTP-заголовок.
- Doris Frontend (FE) принимает запрос, проверяет права доступа и наличие целевой таблицы, а затем разбирает параметры загрузки.
-
Распределение задачи и координация
- FE анализирует распределение данных (на основе правил партиционирования и распределения по бакетам таблицы), формирует план загрузки и выбирает узел Backend (BE) в качестве Coordinator для координации всей задачи.
- Если запрос отправлен непосредственно на BE (как в Stream Load), этот BE может выступать в роли Coordinator, но ему всё равно нужно получить метаданные (например, схему таблицы) от FE.
- План загрузки распределяет данные между несколькими узлами BE, обеспечивая параллельную обработку для повышения эффективности.
-
Чтение и распределение данных
- Coordinator BE читает данные из источника (например, получает сообщения из Kafka, читает файлы из S3 или непосредственно принимает поток данных по HTTP).
- Doris разбирает формат данных (например, разделяет поля CSV или разбирает JSON) и поддерживает задаваемые пользователем облегчённые операции ETL, в том числе:
- Предварительную фильтрацию: фильтрация исходных данных для снижения затрат на обработку.
- Сопоставление столбцов: настройка соответствия между исходными столбцами и столбцами целевой таблицы.
- Преобразование данных: обработка данных с помощью выражений.
- Последующую фильтрацию: фильтрация преобразованных данных.
- После разбора Coordinator BE распределяет данные между несколькими нижестоящими Executor BE согласно правилам партиционирования и распределения по бакетам.
-
Запись данных
- Данные распределяются между несколькими узлами BE и записываются в таблицы в оперативной памяти (MemTables) с сортировкой по столбцам Key. Для моделей Aggregate или Unique Key Doris выполняет агрегацию или дедупликацию по Key (с использованием SUM, REPLACE и других операций).
- Когда MemTable заполняется (по умолчанию 200 MB) или задача завершается, данные асинхронно записываются на диск, формируя колоночные файлы Segment, которые составляют Rowset.
- Каждый BE независимо обрабатывает назначенные ему данные и после завершения записи сообщает свой статус узлу Coordinator.
-
Фиксация транзакции и публикация
- Coordinator инициирует фиксацию транзакции (Commit) на FE. После того как FE подтверждает успешную запись большинства реплик, он уведомляет BE о необходимости опубликовать версию данных (Publish Version). Когда Publish на BE успешно завершается, FE помечает транзакцию как VISIBLE, и данные становятся доступны для запросов.
- При сбое FE запускает откат, чтобы удалить временные данные и обеспечить согласованность данных.
-
Возврат результата
- Синхронные способы (например, Stream Load и Insert Into) непосредственно возвращают результат загрузки, включая статус успеха или сбоя и сведения об ошибках (например, ErrorURL).
- Асинхронные способы (например, Broker Load) возвращают ID задачи и Label. С помощью
SHOW LOADможно просмотреть ход выполнения, число строк с ошибками и подробные сведения. - Операции записываются в журналы аудита, чтобы их можно было отследить впоследствии.
Пересылка MemTable
Пересылка MemTable — оптимизация, появившаяся в Apache Doris 2.1.0 и значительно повышающая производительность загрузок INSERT INTO...SELECT:
- Узкое место традиционного процесса: узел Sink должен кодировать данные в формат Block и передавать их нижестоящим узлам через Ping-pong RPC. Это требует нескольких циклов кодирования и декодирования и увеличивает накладные расходы.
- Оптимизация: узел Sink непосредственно обрабатывает MemTable, формирует данные Segment и передаёт их через Streaming RPC. Это сокращает затраты на кодирование и декодирование и время ожидания передачи, а также обеспечивает более точный механизм обратного давления по памяти.
- Прирост производительности: официальные тесты показывают, что время загрузки сокращается до 36% от исходного в сценариях с одной репликой и до 54% в сценариях с тремя репликами, а общая производительность повышается более чем на 100%.
- Область применения: в настоящее время эта возможность поддерживается только в режиме развёртывания с совмещёнными хранением и вычислениями.
Загрузка в архитектуре с разделением вычислений и хранения
В архитектуре с разделением вычислений и хранения оптимизация загрузки сосредоточена на отделении хранения данных от управления транзакциями:
- Хранение данных
- BE не хранит данные постоянно. После Flush MemTable созданные файлы Segment загружаются непосредственно в общее хранилище (например, S3 или HDFS). Высокая доступность и низкая стоимость объектного хранилища позволяют поддерживать эластичное масштабирование.
- Локальный File Cache на BE асинхронно кэширует часто используемые данные, повышая долю попаданий в кэш при запросах с помощью стратегий TTL и Warmup.
- Метаданные (например, метаданные Tablet и Rowset) хранятся посредством Meta Service в FoundationDB, а не в локальной RocksDB на BE.
- Обработка транзакций
- Управление транзакциями перенесено с FE в Meta Service, что устраняет узкое место записи в FE Edit Log.
- Meta Service управляет транзакциями через стандартные интерфейсы (
beginTransaction,commitTransaction) и опирается на возможности глобальных транзакций FoundationDB для обеспечения согласованности. - BE Coordinator взаимодействует непосредственно с Meta Service для записи состояния транзакций и использует атомарные операции для обработки конфликтов и освобождения ресурсов по тайм-ауту. Это упрощает логику синхронизации и повышает пропускную способность загрузок небольших пакетов с высоким параллелизмом.
Баланс между задержкой и пропускной способностью
В реальных бизнес-сценариях часто требуется находить баланс между задержкой и пропускной способностью загрузки данных:
- Меньшая задержка: позволяет раньше увидеть актуальные данные, но меньшие пакеты записи и более высокая частота записи приводят к более частой фоновой Compaction. Это увеличивает потребление CPU, I/O и памяти, а также нагрузку на управление метаданными.
- Более высокая пропускная способность: увеличение объёма данных на одну загрузку и сокращение числа загрузок значительно снижают нагрузку на метаданные и затраты на фоновую Compaction, повышая общую производительность системы. Однако задержка между записью данных и их доступностью для запросов увеличивается.
Поэтому, соблюдая требования бизнеса к задержке, по возможности увеличивайте объём данных на одну загрузку, чтобы повысить пропускную способность и снизить накладные расходы системы.
Результаты тестирования
Сквозная задержка Flink
В тесте используется Flink Connector в режиме пакетной записи; оцениваются сквозная задержка и пропускная способность загрузки. Интервал формирования пакетов задаётся параметром Flink Connector sink.buffer-flush.interval. Подробнее об использовании Flink Connector см. в разделе Flink-Doris-Connector.
Конфигурация оборудования:
- 1 FE: CPU с 8 ядрами, 16 GB памяти
- 3 BE: CPU с 16 ядрами, 64 GB памяти
Набор данных:
- Данные TPCH lineitem
Производительность загрузки при разных интервалах формирования пакетов и уровнях параллелизма:
| Интервал формирования пакетов (с) | Параллелизм загрузки | Число бакетов | Пропускная способность (строк/с) | Средняя сквозная задержка (с) | Сквозная задержка P99 (с) |
|---|---|---|---|---|---|
| 0.2 | 1 | 32 | 6073 | 0.211 | 0.517 |
| 1 | 1 | 32 | 31586 | 0.71 | 1.39 |
| 10 | 1 | 32 | 67437 | 5.65 | 10.90 |
| 20 | 1 | 32 | 93769 | 10.962 | 20.682 |
| 60 | 1 | 32 | 125000 | 32.46 | 62.17 |
| 0.2 | 10 | 32 | 9300 | 0.38 | 0.704 |
| 1 | 10 | 32 | 34633 | 0.75 | 1.47 |
| 10 | 10 | 32 | 82023 | 5.44 | 10.43 |
| 20 | 10 | 32 | 139731 | 11.12 | 22.68 |
| 60 | 10 | 32 | 171642 | 32.37 | 61.93 |
Влияние числа бакетов на производительность загрузки:
| Интервал формирования пакетов (с) | Параллелизм загрузки | Число бакетов | Пропускная способность (строк/с) | Средняя сквозная задержка (с) | Сквозная задержка P99 (с) |
|---|---|---|---|---|---|
| 1 | 10 | 4 | 34722 | 0.86 | 2.28 |
| 1 | 10 | 16 | 34526 | 0.8 | 1.52 |
| 1 | 10 | 32 | 34633 | 0.75 | 1.47 |
| 1 | 10 | 64 | 34829 | 0.81 | 1.51 |
| 1 | 10 | 128 | 34722 | 0.83 | 1.55 |
Тест Group Commit
Для частых загрузок небольших пакетов рекомендуется включать Group Commit: это значительно повышает производительность загрузки. Результаты тестов производительности Group Commit см. в разделе Производительность Group Commit.
Часто задаваемые вопросы
Вопрос 1: Как выбрать подходящий способ загрузки?
Выбирайте с учётом источника данных и требований к работе в реальном времени: используйте Stream Load для отправки локальных файлов в реальном времени; Broker Load — для крупных пакетов в HDFS/S3; Routine Load — для потоковых данных из Kafka; Insert Into / Select — для ETL между внешними таблицами или таблицами Doris; MySQL Load — для сценариев, требующих совместимости с MySQL.
Вопрос 2: Почему частые загрузки небольших пакетов сильно влияют на производительность?
Частые загрузки небольших объёмов данных заставляют Doris часто выполнять Compaction, что приводит к сильному усилению записи. Накапливайте на клиенте от нескольких MB до нескольких GB данных либо включите Group Commit для объединения в пакеты на стороне сервера.
Вопрос 3: Что делать, если при загрузке создаётся много небольших файлов и нагрузка от Compaction высока?
Включите Group Commit для объединения небольших транзакций либо перед загрузкой накапливайте на клиенте от сотен MB до нескольких GB данных. Одновременно пересмотрите схему партиционирования и распределения по бакетам, чтобы избежать слишком большого числа активных Tablet.
Вопрос 4: Почему одна загрузка не должна охватывать слишком много партиций?
Каждый Tablet содержит в памяти одну активную Memtable. Когда суммарный объём памяти, занятый активными Memtable, становится слишком большим, запускается преждевременный сброс для предотвращения OOM. Это создаёт множество небольших файлов и снижает производительность загрузки. Ограничение числа партиций в одной загрузке помогает решить эту проблему.
Вопрос 5: Всегда ли лучше увеличивать объём данных на одну загрузку?
Нет. Размер каждого пакета не должен превышать 100 GB. Слишком большой пакет увеличивает затраты на повторные попытки и нагрузку на память и диски BE. Для больших локальных файлов можно использовать инструмент streamloader, который автоматически разбивает данные на пакеты.
Вопрос 6: Почему рекомендуется размер Tablet 1-10 GB?
Слишком маленький Tablet снижает эффективность агрегации и увеличивает нагрузку на управление метаданными; слишком большой Tablet требует больше затрат на перенос и восстановление реплик. 1-10 GB — эмпирический диапазон, обеспечивающий баланс между загрузкой, запросами и управлением репликами.
Вопрос 7: Как настроить параллелизм Stream Load?
Параллелизм Stream Load на одном BE не должен превышать 128 (ограничивается параметром webserver_num_workers) и должен быть ниже 512 (ограничивается параметром doris_max_remote_scanner_thread_pool_thread_num); иначе процесс BE может зависнуть.
Вопрос 8: В каких сценариях работает пересылка MemTable?
Она работает только для INSERT INTO...SELECT в режиме развёртывания с совмещёнными хранением и вычислениями. Время загрузки с одной репликой сокращается до 36% от исходного, а с тремя репликами — до 54%. Режим с разделением вычислений и хранения пока не поддерживает эту оптимизацию.
Вопрос 9: Как избежать перекоса данных?
Задайте разумное число бакетов (размер одного Tablet после сжатия — 1-10 GB) и выберите подходящий ключ распределения по бакетам. При случайном распределении по бакетам можно включить load_to_single_tablet=true, чтобы снизить накладные расходы на распределение.
Устранение неполадок
| Симптом | Возможная причина | Диагностика и решение |
|---|---|---|
| Низкая пропускная способность загрузки, частая Compaction | Частые загрузки небольших пакетов вызывают усиление записи | Объединяйте данные в пакеты на стороне клиента или включите Group Commit |
| При загрузке создаётся много небольших файлов | Одна загрузка охватывает слишком много партиций, вызывая преждевременный сброс Memtable | Сократите число партиций на одну загрузку; загружайте партиции по порядку |
| Большая задержка до появления загруженных данных в запросах | Успешная запись не подтверждена большинством реплик, медленный Publish | Используйте SHOW LOAD для просмотра статуса задачи; проверьте работоспособность BE и при необходимости увеличьте тайм-аут публикации |
| BE OOM или частый Flush | Слишком много одновременно активных партиций/Tablet, данные распределены по множеству MemTable | Загружайте партиции по порядку; сократите число бакетов; снизьте параллелизм |
| Высокая нагрузка на FE Edit Log | Частые загрузки небольших пакетов, слишком много транзакций | Включите Group Commit или объединяйте данные в пакеты на стороне клиента; проверьте, не слишком ли высок параллелизм |
| Compaction не успевает обрабатывать данные, запросы замедляются | Слишком много небольших файлов, сильное усиление записи | Увеличьте объём данных на одну загрузку; настройте распределение по бакетам; при необходимости скорректируйте параметры Compaction |
| Нестабильность загрузки при разделении вычислений и хранения | Ограничение QPS объектного хранилища | Контролируйте параллелизм; увеличьте объём данных в пакете; уточните квоту QPS на стороне объектного хранилища |
| Загрузка сообщает о строках с ошибками | Несоответствие формата данных, ошибка сопоставления столбцов | Изучите примеры ошибок по возвращённому ErrorURL; скорректируйте сопоставление столбцов, разделители или допустимый уровень ошибок |
| Процесс BE зависает | Параллелизм Stream Load на одном BE превышает 512 | Снизьте параллелизм, скорректируйте doris_max_remote_scanner_thread_pool_thread_num |
| Потоки веб-сервера исчерпаны, Stream Load работает медленно | Параллелизм на одном BE превышает 128 | Поддерживайте параллелизм ниже 128 или скорректируйте webserver_num_workers |
| Низкий параллелизм Broker Load | Отдельный сжатый файл / файл Parquet / ORC слишком велик и не разбит на части | Перед загрузкой разбейте большой файл на несколько файлов меньшего размера |
| Высокие затраты на повторную попытку при сбое одной загрузки Broker Load | Слишком большой размер пакета | Поддерживайте размер каждого пакета ниже 100 GB и отправляйте данные пакетами |