Стратегии быстрого поиска миллиардов небольших документов в MongoDB - программирование
Подтвердить что ты не робот

Стратегии быстрого поиска миллиардов небольших документов в MongoDB

Мне нужно хранить несколько миллиардов небольших структур данных (около 200 байт каждый). До сих пор хранение каждого элемента в виде отдельного документа хорошо работает, а Mongo обеспечивает около 10 000 результатов в секунду. Я использую 20-байтовый хэш как _id для каждого документа и один индекс в поле _id. При тестировании это работает для наборов данных с 5 000 000 документов.

В процессе работы мы будем составлять около 10 000 запросов в секунду, обновляя существующие документы около 1000 раз в секунду и вставляя новые документы, возможно, 100 раз в секунду или меньше.

Как мы можем управлять большими наборами данных, когда мы не можем хранить весь индекс в ОЗУ? Будет ли MongoDB работать лучше, если мы объединим несколько элементов в каждый документ - для более быстрого поиска по индексу, но больше данных, возвращаемых в каждом запросе?

В отличие от других вопросов о SO, я не только интересуюсь, сколько данных мы можем нанести на Mongo. Он может четко управлять объемом данных, на которые мы смотрим. Моя забота заключается в том, как мы можем максимизировать скорость операций find в огромных коллекциях, учитывая ограниченную ОЗУ.

Наши поиски будут сгруппированы; около 50 000 элементов будут удовлетворять около 50% запросов, но оставшиеся 50% будут случайным образом распределены по всем данным. Можно ли ожидать увеличения производительности, переместив эти 50% в свою собственную коллекцию, чтобы сохранить меньший индекс самых используемых данных всегда в ram?

Уменьшает ли размер поля _id от 20-байтовых до 8-байтов оказывает значительное влияние на скорость индексирования MnogoDB?

4b9b3361

Ответ 1

Приходят в голову несколько стратегий:

1) Используйте различные коллекции/базу данных для "горячих" документов.

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

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

2) Сократите индексированные значения.

Чем меньше значение индекса, тем больше значений, которые вписываются в один блок B-Tree. (Примечание. Ключи не включены в индекс.) Чем больше записей в одном ведре, тем меньше количество ведер и меньше полной памяти, необходимой для индекса. Это приводит к более высокой вероятности/длительности жизни, когда блоки будут оставаться в памяти. В вашем примере сокращение на 20- > 8 символов составляет более 50% экономии. Если вы можете конвертировать эти 8 байтов в длину, есть немного больше сбережений, поскольку longs не имеют префикса длины (4 байта) и конечного нуля (всего 5 байтов).

3) Сократите имена клавиш.

Чем короче поле, тем меньше места занимает каждый документ. Это приводит к неудачному побочному эффекту снижения удобочитаемости.

4) Осколок

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

5) Отрегулируйте скорость чтения на диске до небольшого значения.

Так как "не горячие" чтения загружают случайный документ с диска, мы действительно хотим только прочитать/исправить в памяти этот документ и как можно меньше документов вокруг него. Большинство систем будут пытаться и читать вперед большой блок данных, как только пользователь будет читать часть файла. Это точно противоположно тому, что мы хотим.

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

6) Старайтесь использовать монотонно возрастающие значения для ключей.

Это вызовет оптимизацию (для индексов на основе ObjectId), что при расщеплении блока индекса он будет делать это при 90/10 вместо 50/50. В результате большинство блоков в вашем индексе будут близки к емкости, и вам будет нужно меньше их.

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

Rob.