Рекомендации по загрузке данных и настройке производительности
Загрузка данных — одна из важнейших возможностей Apache Doris. Её эффективность напрямую определяет актуальность аналитики в реальном времени и стабильность системы. В этой статье на примере типичных бизнес-сценариев сначала приводятся рекомендации, которые можно сразу применить на практике, а затем рассматриваются внутренние механизмы загрузки и подход к настройке. Это поможет вам:
- Выбрать подходящий способ загрузки с учётом особенностей ваших задач
- Принимать обоснованные решения при проектировании таблиц, формировании пакетов, распределении по бакетам, настройке памяти и параллелизма
- Избежать распространённых проблем: частых загрузок небольших объёмов данных, усиления записи и нехватки памяти Memtable (OOM)
- Найти баланс между задержкой и пропускной способностью, соответствующий вашим требованиям
Быстрая навигация
| Задача | Рекомендация | Раздел |
|---|---|---|
| Выбор способа загрузки | Выбирайте с учётом источника данных и требований к работе в реальном времени | Выбор подходящего способа загрузки |
| Модель таблицы | Отдавайте предпочтение модели Duplicate Key | Модель таблицы и индексы |
| Партиционирование и распределение по бакетам | Поддерживайте размер отдельного Tablet в пределах от 1 до 10 ГБ | Настройка партиционирования и распределения по бакетам |
| Случайное распределение по бакетам | Включите load_to_single_tablet для повышения пропускной способности | Оптимизация загрузки при случайном распределении по бакетам |
| Частые загрузки небольших объёмов данных | Объединяйте данные в пакеты на стороне клиента и используйте Group Commit | Стратегия формирования пакетов |
| Количество партиций в одной загрузке | Ограничивайте его, чтобы избежать слишком большого количества Memtable | Загрузка партиций и контроль памяти |
| Загрузка большого объёма данных | Разбивайте данные на пакеты размером не более 100 ГБ каждый | Пакетная загрузка больших объёмов данных |
| Параллелизм 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 ГБ
Поддерживайте размер отдельного Tablet в диапазоне от 1 до 10 ГБ:
| Размер Tablet | Влияние |
|---|---|
| Слишком маленький | Слабый эффект агрегации, повышенная нагрузка на управление метаданными |
| Слишком большой | Затрудняет перенос и восстановление реплик |
| 1-10 ГБ (рекомендуется) | Обеспечивает баланс между загрузкой, запросами и управлением репликами |
Формула количества бакетов: 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). Частые загрузки небольших пакетов размером порядка КБ приводят к следующим последствиям:
- Частая запись в FE Edit Log увеличивает дисковый I/O на FE.
- Частые сбросы MemTable BE создают множество небольших файлов Segment.
- Частый Compaction приводит к сильному усилению записи.
Снизить эти издержки можно, сочетая формирование пакетов на стороне клиента и сервера:
| Способ формирования пакетов | Сценарии применения | Рекомендация |
|---|---|---|
| Формирование пакетов на стороне клиента | Пакетная запись, которой управляет клиент | Накапливайте на клиенте от сотен МБ до нескольких ГБ данных перед запуском загрузки. Замена множества небольших транзакций одной крупной снижает частоту записи в FE Edit Log и сбросов MemTable BE, предотвращая фрагментацию хранилища и расход ресурсов на последующий Compaction. |
| Формирование пакетов на стороне сервера (Group Commit) | Множество одновременных загрузок небольших объёмов данных | Включите Group Commit, чтобы сервер объединял несколько небольших пакетов за короткий промежуток времени в одну транзакцию. Полученная крупная транзакция создаёт более крупные файлы Segment и снижает нагрузку фонового Compaction. Этот подход особенно подходит для частых загрузок небольших пакетов, например журналов и данных IoT. |
Загрузка партиций и контроль памяти
Во время загрузки BE сначала записывает данные в MemTable в памяти (по умолчанию 200 МБ). При заполнении MemTable асинхронно сбрасывается на диск, формируя файлы Segment. У каждого Tablet в памяти находится одна активная MemTable, поэтому количество партиций, охватываемых одной загрузкой, напрямую влияет на потребление памяти:
- Слишком большое количество партиций приводит к большому количеству активных Tablet и, соответственно, активных MemTable, что увеличивает потребление памяти.
- При слишком высоком потреблении памяти запускается досрочный сброс, чтобы предотвратить OOM процесса.
- Досрочные сбросы создают множество небольших файлов, что дополнительно снижает производительность загрузки.
Для стабильной пропускной способности загрузки:
- Загружайте партиции последовательно: например, загружайте данные по дням, чтобы запись была сосредоточена в одной партиции. Это уменьшает рассредоточение MemTable и количество сбросов, снижает фрагментацию памяти и нагрузку на I/O.
- Строго ограничивайте количество партиций, охватываемых одной загрузкой, чтобы избежать досрочных сбросов из-за слишком большого количества MemTable.
Пакетная загрузка больших объёмов данных
Если файлов много и объём данных очень большой, загружайте данные пакетами, чтобы снизить затраты на повторные попытки и избежать резких нагрузок на память и диски BE:
| Источник данных | Рекомендуемый способ загрузки | Рекомендуемый размер пакета |
|---|---|---|
| Удалённые файлы, например в HDFS или объектном хранилище | Broker Load | Каждый пакет не более 100 ГБ |
| Большие локальные файлы | Инструмент 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, обеспечивая параллельную обработку для повышения эффективности.
-
Чтение и распределение данных
- BE в роли Coordinator читает данные из источника, например получает сообщения из Kafka, читает файлы из S3 или напрямую принимает поток данных по HTTP.
- Doris разбирает формат данных, например разделяет CSV или выполняет разбор JSON, и поддерживает заданные пользователем облегчённые операции ETL, включая:
- Предварительную фильтрацию: фильтрацию исходных данных для сокращения затрат на обработку.
- Сопоставление столбцов: настройку соответствия между исходными столбцами и столбцами целевой таблицы.
- Преобразование данных: обработку данных с помощью выражений.
- Последующую фильтрацию: фильтрацию преобразованных данных.
- После разбора BE в роли Coordinator распределяет данные между несколькими нижестоящими узлами BE в роли Executor в соответствии с правилами партиционирования и распределения по бакетам.
-
Запись данных
- Данные распределяются между несколькими узлами BE и записываются в таблицы в памяти (MemTable) с сортировкой по столбцам Key. Для моделей Aggregate и Unique Key Doris выполняет агрегацию или дедупликацию по Key с использованием SUM, REPLACE и других операций.
- При заполнении MemTable (по умолчанию 200 МБ) или завершении задачи данные асинхронно записываются на диск, образуя колоночные файлы 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 ГБ памяти
- 3 BE: CPU с 16 ядрами, 64 ГБ памяти
Набор данных:
- Данные 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, что приводит к сильному усилению записи. Накапливайте на клиенте от нескольких МБ до нескольких ГБ данных либо включите Group Commit для формирования пакетов на стороне сервера.
Вопрос 3: Что делать, если при загрузке создаётся много небольших файлов и нагрузка Compaction высока?
Включите Group Commit для объединения небольших транзакций либо накапливайте на клиенте от сотен МБ до нескольких ГБ данных перед загрузкой. Также проверьте схему партиционирования и распределения по бакетам, чтобы избежать слишком большого количества активных Tablet.
Вопрос 4: Почему одна загрузка не должна охватывать слишком много партиций?
Каждый Tablet содержит в памяти одну активную Memtable. Когда суммарный объём памяти, занятый активными Memtable, становится слишком большим, запускается досрочный сброс для предотвращения OOM. Это создаёт множество небольших файлов и снижает производительность загрузки. Ограничение количества партиций в одной загрузке смягчает эту проблему.
Вопрос 5: Всегда ли увеличение объёма данных в одной загрузке полезно?
Нет. Размер каждого пакета не должен превышать 100 ГБ. Слишком большой пакет увеличивает затраты на повторную попытку и нагрузку на память и диски BE. Для больших локальных файлов можно использовать инструмент streamloader, который автоматически формирует пакеты.
Вопрос 6: Почему рекомендуется размер Tablet в пределах 1-10 ГБ?
Слишком маленький Tablet ослабляет эффект агрегации и увеличивает нагрузку на управление метаданными; слишком большой Tablet требует больше ресурсов для переноса и восстановления реплик. Диапазон 1-10 ГБ подобран эмпирически и обеспечивает баланс между загрузкой, запросами и управлением репликами.
Вопрос 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 ГБ) и выберите подходящий ключ распределения по бакетам. При случайном распределении по бакетам можно включить load_to_single_tablet=true, чтобы снизить затраты на распределение.
Устранение неполадок
| Симптом | Возможная причина | Диагностика и решение |
|---|---|---|
| Низкая пропускная способность загрузки, частый Compaction | Частые загрузки небольших пакетов вызывают усиление записи | Формируйте пакеты на стороне клиента или включите Group Commit |
| Во время загрузки создаётся много небольших файлов | Одна загрузка охватывает слишком много партиций, вызывая досрочный сброс Memtable | Сократите количество партиций в одной загрузке; загружайте партиции последовательно |
| Большая задержка до появления загруженных данных в запросах | Запись не завершена на большинстве реплик, медленный Publish | Используйте SHOW LOAD для просмотра состояния задачи; проверьте состояние BE и при необходимости увеличьте тайм-аут публикации |
| OOM на BE или частый 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 ГБ и отправляйте данные пакетами |