Как эффективно использовать более 10 компьютеров для импорта данных - PullRequest
9 голосов
/ 12 апреля 2011

У нас есть плоские файлы (CSV) с> 200 000 000 строк, которые мы импортируем в звездообразную схему с 23 таблицами измерений.Самая большая таблица измерений имеет 3 миллиона строк.На данный момент мы запускаем процесс импорта на одном компьютере, и это занимает около 15 часов.Поскольку это слишком долго, мы хотим использовать что-то вроде 40 компьютеров для импорта.

Мой вопрос

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

У кого-нибудь есть предложения?

РЕДАКТИРОВАТЬ:

Ниже приведено упрощение файлов CSV:

"avalue";"anothervalue"
"bvalue";"evenanothervalue"
"avalue";"evenanothervalue"
"avalue";"evenanothervalue" 
"bvalue";"evenanothervalue"
"avalue";"anothervalue"

После импорта таблицы выглядят следующим образом:

размерная таблица1

id  name
1   "avalue"
2   "bvalue"

размерная таблица2

id  name
1   "anothervalue"
2   "evenanothervalue"

таблица фактов

  dimension_table1_ID       dimension_table2_ID
    1                      1
    2                      2
    1                       2
    1                       2              
    2                       2
    1                       1

Ответы [ 8 ]

10 голосов
/ 27 апреля 2011

Можно использовать 64-битную хеш-функцию для получения bigint идентификатора для каждой строки вместо использования последовательных идентификаторов.

С помощью 64-битных хеш-кодов вы можете сохранить 2 ^ (32 - 7) или более 30 миллионов элементов в вашей хэш-таблице до того, как вероятность столкновения составит 0,0031%.

Это позволит вам иметь идентичные идентификаторы на всех узлах без какой-либо связи между серверами между фазами «отправки» и «слияния».

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

См:

http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash

http://code.google.com/p/smhasher/wiki/MurmurHash

http://www.partow.net/programming/hashfunctions/index.html

3 голосов
/ 12 апреля 2011

Загрузка данных CSV в базу данных происходит медленно, потому что для этого необходимо прочитать, разбить и проверить данные.

Итак, вам стоит попробовать следующее:

  1. Настройкалокальная база данных на каждом компьютере.Это избавит от задержки в сети.

  2. Загрузите различную часть данных на каждый компьютер.Попробуйте дать каждому компьютеру один и тот же кусок.Если по какой-то причине это непросто, дайте каждому компьютеру, скажем, 10 000 строк.Когда они будут готовы, дайте им следующий кусок.

  3. Сброс данных с помощью инструментов БД

  4. Загрузка всех дампов в одну БД

Убедитесь, что ваш загрузчик может импортировать данные в таблицу, которая уже содержит данные.Если вы не можете этого сделать, проверьте документацию вашей БД на наличие «удаленной таблицы».Многие базы данных позволяют сделать таблицу с другого сервера БД видимой локально.

Это позволяет вам запускать такие команды, как insert into TABLE (....) select .... from REMOTE_SERVER.TABLE

Если вам нужны первичные ключи (и вы должны), вытакже возникнет проблема с назначением ПК во время импорта в локальные БД.Я предлагаю добавить PK в файл CSV.

[EDIT] После проверки с вашими правками вот что вы должны попробовать:

  1. Напишите небольшую программу, которая извлекает уникальные значения в первом и втором столбце файла CSV.Это может быть простой скрипт, например:

     cut -d";" -f1 | sort -u | nawk ' { print FNR";"$0 }'
    

    Это довольно дешевый процесс (пару минут даже для больших файлов).Он дает вам файлы значений ID.

  2. Напишите программу, которая считывает новые файлы значений идентификаторов, кэширует их в памяти, а затем читает огромные файлы CSV и заменяет значения идентификаторами..

    Если файлы значений ID слишком велики, просто сделайте этот шаг для маленьких файлов и загрузите огромные файлы во все 40 БД на машину.

  3. Разделите огромный файл на 40 блоков и загрузите каждый из них на каждый компьютер.

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

  4. Используйте резервное копирование / восстановление или удаленные таблицы для объединения результатов.

    Или, что еще лучше, сохраните данные на 40 машинах и используйте алгоритмы параллельных вычислений для разделения работыи объединить результаты.Именно так Google может создавать результаты поиска из миллиардов веб-страниц за несколько миллисекунд.

См. здесь для ознакомления .

2 голосов
/ 21 апреля 2011

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

Какую базу данных вы планируете использовать с 23-мерной звездной схемой?Импорт может быть не единственным узким местом производительности.Возможно, вы захотите сделать это в распределенной системе основной памяти.Это позволяет избежать многих проблем, связанных с матерализацией.

Вам следует выяснить, существуют ли сильно коррелирующие измерения.

В целом, для 23-мерной звездообразной схемы с большими измерениями используется стандартная реляционная база данных (SQL Server, PostgreSQL, MySQL) очень плохо справится с вопросами хранилища данных.Чтобы избежать необходимости полного сканирования таблиц, реляционные базы данных используют материализованные представления.С 23 размерами вы не можете себе их позволить.Распределенная база данных основной памяти могла бы выполнять сканирование всей таблицы достаточно быстро (в 2004 году я сделал около 8 миллионов строк / сек / поток на Pentium 4 3 ГГц в Delphi).Vertica может быть другой вариант.

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

[править] Я рассмотрел ваши другие вопросы.Это не похоже на хорошее соответствие для PostgreSQL (или MySQL или SQL-сервера).Как долго вы готовы ждать результатов запроса?

2 голосов
/ 21 апреля 2011

Предполагая, что N компьютеров, X файлов по 50 ГБ каждый и цель состоит в том, чтобы в конце была одна база данных, содержащая все.

Вопрос: Теперь это занимает 15 часов.Вы знаете, какая часть процесса занимает больше всего времени?(Чтение данных, очистка данных, сохранение прочитанных данных в таблицах, индексирование ... вы вставляете данные в неиндексированные таблицы и выполняете индексирование после, верно?)

Чтобы разделить эту работу среди N компьютеров, я бы сделал кое-чтонапример (и это дизайн «за конвертом»):

  • Иметь «центральную» или основную базу данных.Используйте это для управления всем процессом и для хранения окончательного полного хранилища.
  • Содержит списки всех файлов X и всех N-1 (не считая себя) «рабочих» баз данных
  • КаждаяРабочая база данных каким-то образом связана с основной базой данных (насколько это зависит от СУБД, которую вы не указали)
  • При запуске и готовности «готовая» рабочая база данных опрашивает основную базу данных для обработки файла.Основная база данных копирует файлы в рабочие системы, гарантируя, что ни один файл не будет обработан более чем одним за один раз.(Необходимо отслеживать успех / неудачу при загрузке данного файла; следите за тайм-аутами (рабочий сбой), управляйте повторными попытками.)
  • Рабочая база данных имеет локальный экземпляр звездообразной схемы.При назначении файла он очищает схему и загружает данные из этого одного файла.(Для масштабируемости может стоить загружать несколько файлов одновременно?) Здесь выполняется очистка данных «первого этапа» для данных, содержащихся в этом файле (ах).
  • При загрузке основная база данных обновляется с «готовым изменением» для этого работника и переходит в режим ожидания.
  • Основная база данных имеет собственный список дел рабочих баз данных, которые имеютзакончил загрузку данных.Обрабатывает каждый ожидающий набор по очереди;после обработки рабочего набора рабочий возвращается в режим «проверка наличия другого файла для обработки».
  • В начале процесса схема «звезда» в базе данных master очищается.Первый загруженный набор, вероятно, может быть просто скопирован более дословно.
  • Для второго набора и более поздних необходимо прочитать и «объединить» данные - выбросить избыточные записи, объединить данные через согласованные измерения и т. Д. Применяемые бизнес-правиладля всех данных, а не только один набор за один раз, должно быть сделано и сейчас.Это будет очистка данных «второго этапа».
  • Еще раз повторите вышеуказанный шаг для каждой рабочей базы данных, пока все файлы не будут загружены.

Преимущества:

  • Чтение / преобразование данных из файлов в базы данных и очистка «первого этапа» масштабируется на компьютерах N.
  • В идеале, для мастера требуется небольшая работа («второй этап», объединение наборов данных).база данных

Ограничения:

  • Многие данные сначала считываются в рабочую базу данных, а затем снова считываются (хотя и в собственном формате СУБД) по сети
  • Основная база данных является возможной точкой притяжения.Здесь все должно пройти.

Ярлыки:

  • Кажется вероятным, что когда рабочая станция «проверяет» новый файл, она может обновить локальное хранилищеданные уже загружены в мастер и добавляют соображения по очистке данных, основанные на этом, к своей работе «первого этапа» (то есть он знает, что код 5484J уже загружен, поэтому он может отфильтровать его и не передавать обратно в базу данных мастера).
  • Секционирование таблиц SQL Server или аналогичные уловки физической реализации других СУБД, вероятно, могли бы быть использованы для хорошего эффекта.
  • Вероятны и другие ярлыки, но они полностью зависят от реализуемых бизнес-правил.

К сожалению, без дополнительной информации илиИз-за понимания системы и данных, нельзя сказать, будет ли этот процесс быстрее или медленнее, чем решение «сделай все в одном».В конце концов, это во многом зависит от ваших данных: они подчиняются методам «разделяй и властвуй» или все они должны проходить через один экземпляр обработки?

2 голосов
/ 12 апреля 2011

Это очень общий вопрос, который не учитывает бэкэнд базы данных.Запуск 40 или 1000 машин на базе данных, которая не справится с нагрузкой, ничего не даст.Такая проблема действительно широка, чтобы ответить на нее определенным образом. Сначала вы должны связаться с сотрудниками вашей организации, обладающими достаточными навыками на уровне БД, а затем вернуться с более конкретным вопросом.

1 голос
/ 27 апреля 2011

Рохит,

Я бы посоветовал вам исключить большую часть работы из нагрузки, сопоставляя данные ПЕРВЫМ, вне базы данных. Я работаю в среде Solaris Unix. Я склонялся бы к сценарию korn-shell, который cut разделяет файл на более управляемые куски, а затем распределяет эти куски одинаково на два моих ДРУГИХ сервера. Я бы обработал куски, используя скрипт nawk (nawk имеет эффективную хеш-таблицу, которую они называют «ассоциативными массивами») для вычисления различных значений (таблиц измерений) и таблицы фактов. Просто свяжите каждое новое увиденное имя с приращением для этого измерения, а затем напишите Факт.

Если вы делаете это по именованным каналам, вы можете передавать, обрабатывать удаленно и выполнять обратный возврат данных «на лету», пока «главный» компьютер сидит там и загружает их прямо в таблицы.

Помните, что бы вы ни делали с 200 000 000 строк данных (сколько это гигабайт?), Это займет некоторое время. Похоже, вы хотите повеселиться. Интересно прочитать, как другие люди предлагают решить эту проблему ... Старая поговорка "есть более чем один способ сделать это!" никогда не было так верно. Удачи!

Приветствия. Кит.

0 голосов
/ 21 июля 2011

Кажется, что ваша реализация очень неэффективна, поскольку она загружается со скоростью менее 1 МБ / с (50 ГБ / 15 часов).

Правильная реализация на современном одном сервере (2 процессора Xeon 5690 + ОЗУ, которых достаточно для ВСЕХ измерений, загруженных в хеш-таблицы + 8 ГБ), должна обеспечить как минимум в 10 раз большую скорость, т. Е. Не менее 10 МБ / с.

0 голосов
/ 26 апреля 2011

С другой стороны, вы можете использовать надстройку Windows Hyper-V Cloud Computing для Windows Server: http://www.microsoft.com/virtualization/en/us/private-cloud.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...