Подтвердить что ты не робот

Auto sharding postgresql?

У меня есть проблема, когда мне нужно очень быстро загрузить большое количество данных (5+ миллиардов строк) в базу данных (в идеале менее 30 минут, но быстрее), и мне недавно предложили заглянуть в postgresql (I не удалось с mysql и смотрел на hbase/cassandra). Моя настройка: у меня есть кластер (в настоящее время 8 серверов), который генерирует много данных, и я думал о запуске баз данных локально на каждом компьютере в кластере, который он пишет быстро локально, а затем в конце (или в процессе генерации данных) сливаются вместе. Данные не в каком-либо порядке, поэтому мне не важно, на каком конкретном сервере он включен (пока он в конечном итоге там).

Мои вопросы: есть ли хорошие учебные пособия или места, чтобы узнать о автоматическом очертании PostgreSQL (я нашел результаты таких фирм, как sykpe, делающие автоматическое очертание, но не учебники, я хочу играть с этим сам)? Это то, что я пытаюсь сделать возможным? Поскольку данные не в каком-либо порядке, я собирался использовать автоинкрементный идентификационный номер, это вызовет конфликт, если данные будут объединены (это уже не большая проблема)?

Обновление: идея Фрэнка ниже вида устранила проблему автоинкрементного конфликта, о которой я спрашивал. Вопрос в основном в настоящее время, как я могу узнать об автоматическом очертании и будет ли он поддерживать распределенные загрузки данных на несколько серверов?

4b9b3361

Ответ 1

Во-первых: вам действительно нужно вставить сгенерированные данные из вашего кластера прямо в реляционную базу данных? Вы не возражаете, чтобы слить его в конце так или иначе, так зачем вообще вставлять в базу данных? В вашей позиции я бы хотел, чтобы ваши узлы кластера записывали плоские файлы, возможно, gzip'd CSV-данные. Затем я импортировал и объединять эти данные с помощью инструмента, такого как pg_bulkload.

Если вам нужно вставить прямо в реляционную базу данных: Это (часть), что PgPool-II и (especeially) PgBouncer. Настройте PgBouncer на балансировку нагрузки на разных узлах, и вы должны быть в значительной степени отсортированы.

Обратите внимание, что PostgreSQL - это транзакционная база данных с надежными гарантиями долговечности. Это также означает, что если вы используете его упрощенным способом, выполнение большого количества мелких записей может быть медленным. Вы должны учитывать, какие компромиссы вы готовы сделать между долговечностью данных, скоростью и стоимостью аппаратного обеспечения.

С одной стороны, каждый INSERT может быть собственной транзакцией, которая синхронно передается на диск перед возвратом успеха. Это ограничивает количество транзакций в секунду на число fsync(), которое может выполнять ваша дисковая подсистема, которая часто бывает только в десятках или сотнях в секунду (без резервного контроллера RAID). Это значение по умолчанию, если вы ничего не делаете, и если вы не оберните INSERT в BEGIN и COMMIT.

С другой стороны, вы говорите: "Мне действительно все равно, если я потеряю все эти данные" и использую разблокированные таблицы для ваших вставок, Это в основном дает разрешению базы данных, чтобы отбросить ваши данные, если он не может гарантировать это в порядке - скажем, после сбоя ОС, сбоя базы данных, потери мощности и т.д.

Среднее место, где вы, вероятно, захотите. Это связано с некоторой комбинацией асинхронной фиксации, группа фиксирует (commit_delay и commit_siblings), пакетные вставки в группы, завернутые в явную BEGIN и END и т.д. Вместо дозирования INSERT вы могли бы выполнять COPY нагрузки нескольких тысяч записей за раз. Все эти вещи прослеживают долговечность данных от скорости.

Для быстрых объемных вставок вы также должны рассмотреть возможность вставки в таблицы без каких-либо индексов, кроме первичного ключа. Может быть, даже не это. Создайте индексы, как только ваши объемные вставки будут выполнены. Это будет намного быстрее.

Ответ 2

Вот несколько вещей, которые могут помочь:

  • БД на каждом сервере должна иметь небольшую таблицу метаданных с уникальными характеристиками этого сервера. Такой, какой он сервер; серверы могут быть пронумерованы последовательно. Помимо содержимого этой таблицы, вероятно, разумно попытаться сохранить схему на каждом сервере как можно более похоже.

  • С миллиардами строк вам понадобятся идентификаторы bigint (или UUID или тому подобное). С помощью bigints вы можете выделить большой диапазон для каждого сервера и настроить его последовательность, чтобы использовать его. Например. сервер 1 получает 1..1000000000000000, сервер 2 получает 1000000000000001 до 2000000000000000 и т.д.

  • Если данные являются простыми точками данных (например, с точностью до 10 приборов каждую секунду), вы можете получить выигрыш в эффективности, сохранив его в таблице со столбцами (time timestamp, values double precision[]), а не с более правильным (time timestamp, instrument_id int, value double precision). Это явная денормализация с точки зрения эффективности. (I в блоге о моем собственном опыте с этой схемой.)

Ответ 3

Извините, у меня нет учебника, но вот схема возможного решения:

  • Загрузите одну из восьми ваших данных в экземпляр PG на каждом из серверов.
  • Для оптимальной скорости загрузки не используйте вставки, но COPY
  • Когда данные загружаются, не объединяйте восемь баз данных в один. Вместо этого используйте plProxy, чтобы запустить один оператор для запроса сразу всех баз данных (или для правильного ответа на запрос).

Как уже отмечалось, ключи могут быть проблемой. Используйте неперекрывающиеся последовательности или uuids или порядковые номера с префиксом строки, не должны быть слишком трудными для решения.

Вы должны начать с теста COPY на одном из серверов и посмотреть, как близко к вашей 30-минутной цели, которую вы можете получить. Если ваши данные не важны, и у вас есть недавняя версия Postgresql, вы можете попробовать использовать нелегальные таблицы, которые должны быть намного быстрее (но не аварийно- безопасно). Похоже на забавный проект, удачи.

Ответ 4

Используйте citus для автоматического обхода PostgreSQL. Также полезно эта ссылка.

Ответ 5

Вы можете использовать mySQL, который поддерживает автоматическое очертание по кластеру.