2016-12-01 5 views
2

Я новичок в игре с mongodb. В связи с тем, что я должен хранить + -50 млн документов, мне пришлось создать MongoDB осколок кластер с двумя наборами репликmongodb sharding - куски не имеют одинакового размера

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

{ 
    "_id" : "predefined_unique_id", 
    "appNr" : "abcde", 
    "modifiedDate" : ISODate("2016-09-16T13:00:57.000Z"), 
    "size" : NumberLong(803), 
    "crc32" : NumberLong(538462645) 
} 

Ключ осколка is appNr (был выбран потому, что для удобства выполнения запроса все документы, имеющие одинаковые appNr, должны оставаться в пределах одного фрагмента). Обычно несколько документов имеют одинаковые appNr.

После загрузки, как два миллиона записей, я вижу ломти уравновешены, однако когда running db.my_collection.getShardDistribution(), я получаю:

Shard rs0 at rs0/... 
data : 733.97MiB docs : 5618348 chunks : 22 
estimated data per chunk : 33.36MiB 
estimated docs per chunk : 255379 

Shard rs1 at rs1/... 

data : 210.09MiB docs : 1734181 chunks : 19 
estimated data per chunk : 11.05MiB 
estimated docs per chunk : 91272 

Totals 
data : 944.07MiB docs : 7352529 chunks : 41 
Shard rs0 contains 77.74% data, 76.41% docs in cluster, avg obj size on shard : 136B 
Shard rs1 contains 22.25% data, 23.58% docs in cluster, avg obj size on shard : 127B 

Мой вопрос, какие настройки я должен сделать для того, чтобы получить данные в равной степени распределены между осколками ? Я хотел бы понять, как данные разбиваются на куски. Я определил ключ дальнего порядка и размер блока 264.

ответ

2

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

Диаграмма пространства значений ключа осколка, сегментированная на меньшие диапазоны или фрагменты. Маршруты mongos записываются в соответствующий фрагмент на основе значения ключа осколка. MongoDB разбивает куски, когда они растут за пределы настроенного размера блока. Обе вставки и обновления могут вызывать разделение кусков.

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

Размер куска будет иметь большое влияние на осколки.

Размер блока по умолчанию в MongoDB составляет 64 мегабайта. Мы можем увеличить или уменьшить размер куска. Но изменение размера куска должно производиться после рассмотрения нижеуказанных статей.

  1. Небольшие куски приводят к более равномерному распределению данных за счет более частых переходов. Это создает затраты на уровне маршрутизации запросов (mongos).
  2. Большие куски приводят к меньшему количеству перемещений. Это более эффективно как с точки зрения сети, так и с точки зрения внутренних накладных расходов на уровне маршрутизации запросов. Но эта эффективность достигается за счет потенциально неравномерного распределения данных.
  3. Размер фрагмента влияет на максимальное количество документов на фрагмент для миграции.
  4. Размер фрагмента влияет на максимальный размер коллекции при обходе существующей коллекции. Постобработка, размер куска не ограничивает размер коллекции.

Отсылая эти данные и ваш осколок «appNr», это произошло бы из-за размера куска.

Попробуйте изменить размер куска вместо 264 МБ (который у вас есть) до меньшего размера и посмотреть, есть ли изменение в распределении документов. Но это будет пробный и ошибочный подход, и потребуется немало времени и итераций.

Ссылка: https://docs.mongodb.com/v3.2/core/sharding-data-partitioning/

Надеется, что это помогает!

+0

Благодарим вас за ответ. Я уменьшил размер до 64, но это не помогло. Я решил проблему, воспользовавшись хэшированным ключом осколка и, подобно этому монго, позаботится о том, чтобы иметь более сбалансированные куски, которые заканчиваются более сбалансированным осколком. – DariusNica

+0

@DariusNica - Отлично, он решил вашу проблему, мы говорим спасибо в stackoverflow, принимая ответ или повышая ответ :-) –

1

Я опубликую свои выводы здесь, возможно, они будут иметь дальнейшее использование.

В документации по mongodb говорится, что «когда кусок растет выше определенного размера куска», он расщепляется. Я думаю, что документация не полностью точна или довольно неполна.

Когда mongo выполняет автоматическое разделение, команда splitVector будет запрашивать первичный осколок для разделения точек, а затем будет разделяться соответствующим образом. Это произойдет сначала, когда будет достигнуто 20% от указанного размера куска и - если не обнаружено точек расщепления - будет повторите попытку на 40%, 60% и так далее ... так что расщепление не должно ждать максимального размера. В моем случае, для первой половины осколков это произошло нормально, но затем во второй половине - раскол произошел только после того, как был превышен максимальный размер блока. Все еще нужно исследовать, почему раскол не произошел раньше, поскольку я не вижу причин для такого поведения.

После разделения в кусках начинается балансировка. Это будет разделять куски одинаково на черепах, не учитывая размер куска (кусок с 0 документами равен куску с 100 документами из этого). Куски будут перемещены в соответствии с порядком их создания.

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

гораздо лучше объяснение, которое я нашел here

Для того, чтобы исправить это, я изменил ключ шардинга к «Хешированному».

Смежные вопросы