WiredTiger и обновления на месте

У меня есть коллекция пользователей. У каждого пользователя есть поле геопозиции, которое довольно часто обновляется (каждый раз, когда пользователь значительно перемещается). Поскольку мне нужен параллелизм на уровне документа, а не на уровне коллекции при обновлении, я использую механизм хранения WiredTiger.

Я узнал, что с WiredTiger каждое обновление в документе приводит к созданию нового документа:

http://learnmongodbthehardway.com/schema/wiredtiger/

WiredTiger не поддерживает обновления на месте

Однако в этой статье также говорится, что хотя [WiredTiger] не поддерживает обновления на месте, для многих рабочих нагрузок он все же может работать лучше, чем MMAP. Что это значит? Каковы точные последствия, о которых я должен знать, когда использую WiredTiger? Например, без обновлений на месте будет ли быстро расти размер базы данных? Есть ли другие вещи, о которых нужно знать?

Я также узнал, что WiredTiger в MongoDB 3.6 добавил возможность хранить дельты, а не переписывать весь документ (https://jira.mongodb.org/browse/DOCS-11416). Что это значит?

ПРИМЕЧАНИЕ: Также я не понимаю, что в настоящее время большинство (если не все) жестких дисков имеют размер сектора 4096 байт, поэтому вы не можете записать на жесткий диск только 4 байта (например) но вместо этого должен записать полный блок из 4096 байт (поэтому сначала прочитайте его, обновите в нем 4 байта, а затем запишите его). Поскольку большинство документов часто имеют размер ‹ 4096 байт, это означает, что переписывание всего документа необходимо в любом случае (даже с MMAP). Что я пропустил?


person zeus    schedule 01.04.2018    source источник
comment
Вы читали предложение сразу после этого? Там сказано, что все документы будут переписаны. Это означает, что, скажем, $set WT прочитает документ, применит исправление и перезапишет документ, тогда как mmapv1 просто перезапишет поле. Думаю, это как-то связано с компрессией.   -  person Sergio Tulentsev    schedule 01.04.2018
comment
будет ли размер базы данных расти очень быстро - хороший вопрос, но легко проверяемый. Создайте тестовую базу данных и выполните для нее несколько сотен миллионов обновлений на месте. Проверьте размер БД до и после.   -  person Sergio Tulentsev    schedule 01.04.2018
comment
@SergioTulentsev: да, но я хочу подтвердить, потому что я не понимаю разницы, так как в настоящее время большинство (если не все) жестких дисков имеют размер сектора 4096 байт, вы не можете записать на жесткий диск только 4 байта (например) но вы должны записать полный блок из 4096 байт (поэтому сначала прочитайте его, обновите в нем 4 байта, а затем запишите его). Поскольку большинство документов часто имеют размер ‹ 4096 байт, это означает, что это похоже на то же поведение, что и в MMAP ... что я пропустил?   -  person zeus    schedule 01.04.2018
comment
Вы думаете о неправильной абстракции. перезапись этого 10-байтового поля выполняется отдельно от фиксации этой грязной отображаемой страницы на диск. Последнее выполняется ОС и имеет мало общего с первым, то есть фактическим обновлением на месте.   -  person Sergio Tulentsev    schedule 01.04.2018
comment
@SergioTulentsev: выполняется ОС или приложением, в конце все то же самое, 4096 байтов должны быть прочитаны и записаны на диск только для изменения 4 байтов. так что это точно так же, как изменить 4 или 4096 байт   -  person zeus    schedule 01.04.2018
comment
Опять неправильная абстракция. Он может вести себя так же в конце, но мы не говорим о конце. WT разработан по-другому, и, что касается движка db, он не может перезаписать ни одно поле (в то время как mmapv1 может).   -  person Sergio Tulentsev    schedule 01.04.2018
comment
К вашему сведению, я ответил на связанный (но несколько другой) вопрос, который появился на боковой панели: Выполняет ли частичное обновление документа MongoDB в WiredTiger дают какое-либо преимущество перед полным обновлением документа?.   -  person Stennie    schedule 03.04.2018
comment
спасибо @Stennie, это очень полезно!   -  person zeus    schedule 03.04.2018


Ответы (1)


В механизме хранения MMAPv1 обновления на месте часто выделяются как стратегия оптимизации, поскольку индексы для документа указывают непосредственно на расположение файлов и смещения. Перемещение документа в новое место хранения (особенно при наличии большого количества элементов индекса для обновления) требует больше затрат для MMAPv1, чем обновление на месте, при котором обновляются только измененные поля. См.: Характеристики хранилища записи в MMAPv1.

WiredTiger не поддерживает обновления на месте, так как внутри он использует MVCC (управление параллельным выполнением нескольких версий), т.е. обычно используется системами управления базами данных. Это значительное техническое улучшение по сравнению с упрощенным представлением в MMAP, которое позволяет создавать более сложные функции, такие как уровни изоляции и транзакции. Индексы WiredTiger имеют уровень косвенности (ссылка на внутренний RecordID вместо местоположения и смещения файла), поэтому перемещение документов на уровне хранилища не является серьезной проблемой.

Однако в этой статье также говорится, что «несмотря на то, что [WiredTiger] не допускает обновления на месте, он все же может работать лучше, чем MMAP, для многих рабочих нагрузок».

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

Тем не менее, общий выбор MMAPv1 против WiredTiger является спорным, если вы хотите планировать будущее: WiredTiger был механизмом хранения по умолчанию, начиная с MongoDB 3.2, и некоторые новые функции продукта не поддерживаются MMAPv1. Например, MMAPv1 не поддерживает Большинство прочитанных сведений, что в поворот означает, что его нельзя использовать для реплики Установите серверы конфигурации (требуется для сегментирования в MongoDB 3.4+) или Change Streams (MongoDB 3.6+). MMAPv1 будет объявлен устаревшим в следующем основном выпуске MongoDB (4.0), и в настоящее время планируется быть удалены в MongoDB 4.2.

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

Результаты хранения зависят от нескольких факторов, включая дизайн схемы, рабочую нагрузку, конфигурацию и версию сервера MongoDB. MMAPv1 и WiredTiger используют разные стратегии выделения записей, но обе будут пытаться использовать предварительно выделенное пространство, помеченное как свободное/повторно используемое. В целом WiredTiger более эффективно использует пространство для хранения, а также имеет преимущество сжатия данных и индексов. MMAPv1 выделяет дополнительное пространство для хранения, чтобы попытаться оптимизировать размещайте обновления и избегайте перемещения документов, хотя вы можете выбрать стратегию «без заполнения» для коллекций, когда рабочая нагрузка не изменяет размер документа с течением времени.

Были вложены значительные средства в улучшение и настройку WiredTiger для различных рабочих нагрузок с тех пор, как он был впервые представлен в MongoDB 3.0, поэтому я настоятельно рекомендую провести тестирование с последними сериями производственных выпусков для достижения наилучшего результата. Если у вас есть конкретный вопрос о дизайне схемы и расширении хранилища, я предлагаю опубликовать подробности на DBA StackExchange для обсуждения.

Я также узнал, что WiredTiger в MongoDB 3.6 добавил возможность хранить дельты, а не переписывать весь документ (https://jira.mongodb.org/browse/DOCS-11416). Что это значит?

Это деталь реализации, которая улучшает внутренние структуры данных WiredTiger для некоторых вариантов использования. В частности, WiredTiger в MongoDB 3.6+ может быть более эффективным при работе с небольшими изменениями в больших документах (по сравнению с предыдущими выпусками). Кэш WiredTiger должен иметь возможность возвращать несколько версий документов, пока они используются открытыми внутренними сеансами (MVCC, как упоминалось ранее), поэтому для больших документов с небольшими обновлениями более эффективно хранить список дельт. Однако, если накапливается слишком много дельт (или дельты изменяют большинство полей в документе), этот подход может быть менее эффективным, чем сохранение нескольких копий полного документа.

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

Также я не понимаю, что в настоящее время большинство (если не все) жестких дисков имеют размер сектора 4096 байт, поэтому вы не можете записать на жесткий диск только 4 байта (например), а вместо этого должны записать полный блок 4096 байт (поэтому сначала прочитайте его, обновите в нем 4 байта, а затем запишите его). Поскольку большинство документов часто имеют размер ‹ 4096 байт, это означает, что переписывание всего документа необходимо в любом случае (даже с MMAP). Что я пропустил?

Не вдаваясь слишком далеко в детали реализации и не пытаясь объяснить все движущиеся части, рассмотрим, как различные подходы применяются к рабочим нагрузкам, когда обновляется множество документов (а не на уровне одного документа), а также влияние на использование памяти (до документы записываются на диск). В зависимости от таких факторов, как размер документа и сжатие, один блок ввода-вывода может представлять от части документа (максимальный размер 16 МБ) до нескольких документов.

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

person Stennie    schedule 03.04.2018