Автор оригинала: Shawn Chiao.
Вступление
Dynamodb , относительно новое прибытие в Партию NoSQL, отметила свой трехлетний юбилей в начале этого года. Теперь мы видели его развернутыми в зрелых продуктах, таких как портфель онлайн-игр в Tinyco и наше собственное решение оптимизации магазина приложений в Gummicube Отказ Это Pay-As-You-Go и чрезвычайно масштабируемо, причем в основном нулевое введение накладной. Тем не менее, у него есть необычные ограничения в дизайне схемы.
Я закончил серию миграции с MongoDB в DishanoDB в начале года и столкнулся с обоими блокирующих блоков и успехов. Вот постммерм о том, что упал, и надеюсь, вы найдете эту запись полезной.
Фон: зачем мигрировать?
Наше веб-приложение написано в Meteor.js , который использует MongoDB по умолчанию, и мы храним все наши данные приложения таким образом с 1 дня. Однако, как выросли наш сервис, и больше собраны данные, стало очевидно, что у нас действительно есть два типа данных.
С одной стороны, у нас есть вид данных, которые напрямую используются для питания нашего веб-приложения — такие вещи, как пользователи, а содержимое, которое они создают в системе. Но у нас также есть огромная коллекция поисковых данных, которые имеют миллиарды записей. Два типа данных доступны по-разному, и имеет больше смысла перемещать массивные результаты поиска в другую базу данных, которая легко масштабируется и может быть оптимизирована отдельно от остальных данных.
Успех: сокращенное администрирование системы
Dynamodb — это полностью управляемая база данных, и нам больше не нужно иметь дело с настройкой инструмента мониторинга, обработки масштабирования, посвященной системе и обновлениям безопасности … Список продолжается. Меньше времени Управляющий сервер означает больше времени написания кода и создания продукта.
Успех: Архивация старых данных
Мы знаем, что более поздние результаты доступны чаще, чем старые результаты. В конце концов очень старые данные о том, что приложение больше не запрашивает (скажем, данные более 2 лет) могут быть сняты с DynamOdb и перемещаются в отдельное медленное хранение, такое как Amazon S3 или Ледник Отказ
Поэтому вместо одного гигантского стола мы сделали отдельный стол на каждый месяц. Например, у нас есть следующие имена таблиц:
Keyword_Search_Result_2014-12 Keyword_Search_Result_2015-01 Keyword_Search_Result_2015-02 ...
Затем мы добавляем логику на уровне приложений, чтобы запросить правильную таблицу. Уважаемый, это могло быть сделано в Mongodb также, отделяя результаты поиска в разные коллекции, основанные на которых они записаны. Но установка в Dynamodb имеет несколько преимуществ, как мы увидим.
Как только таблицы настроены, мы можем установить прочитанную пропускную способность на таблицах в соответствии с тем, как часто они доступны. Вы можете использовать Потребляемая емкость чтения и Пишите емкость От веб-консоли AWS, чтобы помочь вам определить необходимую пропускную способность для вещей плавно работать.
Используйте пропускную способность
Согласно документации Dynamodb, «DynamoDB в настоящее время резервирует 5 минут (300 секунд) неиспользуемого прочитанного и записи». Это позволяет нам превратить исторический месяц на действительно низкий объем, поскольку шаблон доступа на эти исторические данные имеет тенденцию приходить в очень редко.
Официальная документация советует против «проектирования вашего приложения, чтобы это зависит от доступов в разрывной способности». Однако для нас это использование случая, когда случайное замедление для доступа к историческим данным является приемлемым для нашего опыта конечного пользователя, поэтому мы смогли воспользоваться здесь из пропускной способности.
Динамодб Автоматическое масштабирование
Также есть несколько проектов с открытым исходным кодом, которые направлены на создание раствора автоматического масштабирования для Dynamodb. Например, мы можем снизить емкость по вечерам, поскольку находятся меньшее количество клиентов; Затем возьмите его обратно в течение дня. Вы можете проверить Динамический динамодб На официальном блоге AWS более подробно.
Но имейте в виду — вы не можете уменьшить емкость на столе более 4 раз в данный календарный день.
Проблема: Обращение с несколькими ключевыми запросами
Одно из первых ограничений на Dynamodb вы увидите, является индекс. Вы можете иметь один ключ HASH, либо комбинацию клавиш HASH KEY + RANGE. Короче говоря, нет поддержки для нескольких ключевых индекса.
Наши миллиарды записей результатов поиска в нашей системе выглядят что-то подобное:
{ keyword : "codementor", platform : "iPhone", country : "US", results : "...", created_on : 2015-01-01T10:00:00Z }
И наш самый распространенный запрос на эти данные в матчах MongoDB против Ключевое слово, платформа, страна и создание_on Отказ Например: дайте мне результат поиска для ключевого слова «Compentor» на iPhone в США, 1 января 2015 года. Как чертовски мы моделируем это в Dynamodb?
Решение: Комбинированные поля, разделенные таблицы
Хотя нам нужно запросить использование всех четырех полей, эти четыре поля не создаются равными. Страна и платформа В основном есть enum, где у нас есть небольшой ограниченный набор поддерживаемых значений, таких как «iPhone», «iPad» и «US», «CA» и т. Д.
Мы решили объединить страну и ключевое слово вместе в одно поле, поскольку приложение никогда не выполняет запрос на результат поиска с простой страной, но никаких ключевых слов, ни справедливых ключевых слов и без страны. Затем мы разделим платформу на уровне стола, поскольку там не очень много платформ (извините, BlackBerry). Имея большую таблицу также помогает нам получить больше контроля над планированием мощности для разных данных, как я упоминал ранее.
В конце концов, мы закончили именами таблиц как:
Keyword_Search_Result_iPhone_2015_01 Keyword_Search_Result_iPad_2015_02 ...
И каждый из результатов поиска выглядит что-то подобное:
{ keyword : "codementor__US", platform : "iPhone", results : "...", created_on : 2015-01-01T10:00:00Z } ... { keyword : "codementor__CA", platform : "iPad", results : "...", created_on : 2015-01-02T10:00:00Z }
Примечание : Я все еще в конечном итоге покинул поле платформы в данных, даже если платформа может быть выведена на таблице, от. Помните, База данных де-нормализации может быть вашим другом в NoSQL Отказ
«Распаковка» кода страны и выбор таблицы затем решаются на нашем слое доступа к данным кодовой базы. К тому времени, когда он доходит до остальной части кода, мы имели дело с тем же объектом JSON, так как мы вернулись с MongoDB.
Слово осторожно : Это конкретное решение работало для нас, потому что он соответствовал нашему примещению и нашему продукту. Это не предназначено для того, чтобы быть руководством, но, в качестве примера, как вам может потребоваться подумать за пределами коробки, чтобы «Динамодб» надо работать так, как вам нужно.
Выпуск: нет родной доступ
Еще одна явная проблема — это тот факт, что dynamodb не поддерживает родную дату или объект dateTime. Общая практика состоит в том, чтобы преобразовать его в метку в Linux и хранить номер вместо этого:
{ keyword : "codementor__US", platform : "iPhone", results : "...", created_on : 1437764250 }
И мы просто всегда будем преобразовывать дату временным меткам на уровне приложений перед запросом DynamOdb. В моем конкретном случае я даже могу сделать Create_on Ключ диапазона, поэтому я могу даже получить сортировку и что нет. Проблема решена верно?
Попался: Запрос даты
Оказывается — не совсем. Наше применение обычно запрашивает результаты в определенный день, и это означает, что мне действительно нужно сделать Запрос вместо GetITem команда. Для этого монгодб Найти утверждение:
.find({ "keyword" : "codementor__US", "created_date" : new Date(2015, 0, 1) });
Мне нужно сделать это Запрос Команда на dynamodb:
"keyword" : { "AttributeValueList" : [ { "S" : "codementor__US" } ], "ComparisonOperator" : "EQ" }, "created_date" : { "AttributeValueList" : [ { "N" : 1420070400 }, { "N" : 1420156799 } ], "ComparisonOperator" : "BETWEEN" }
где 1420070400 и 1420156800 и 1420156800 2015-01-01T00: 00: 00 и 2015-01-01T23: 59: 59 в Linux Timestamp, соответственно.
Да, это может быть запрошено, но есть две проблемы.
Во-первых, Запрос Команды намного медленнее, чем прямой Розыгрыш Команда, где вам дают как точная клавиша HASH и клавиша диапазона, чтобы соответствовать.
Во-вторых, Dynamodb предлагает Batchgetitem , что полезно для получения результатов поиска для нескольких ключевых слов, которые часто происходят в нашей системе. Накладные расходы в каждом из запросов API To Dynamodb могут действительно добавить при работе с количеством ключевых слов, которые запрашиваются наши приложения. Нам нужно было другое решение.
Решение: Дата хранения в виде строки
После подтверждения с использованием случаев нам нужно только хранить один результат поиска в день, мы решили хранить только отформатированную дату в качестве строки:
{ keyword : "codementor", platform : "iPhone", country : "US", results : "...", created_on : "2015-01-01" }
Теперь мы можем получить наши данные быстрее с помощью GetITem вызов:
"keyword" : { "S" : "codementor__US", }, "created_date" : { "S" : "2015-01-01"), }
… что позволяет нам получать результаты пакетными материалами. Сейчас все бегут в головокружительно быстро. Также есть дополнительный бонус — теперь данные являются читаемыми человеком при использовании веб-консоли dynamodb, которая также экономит разработчик некоторое время
Я не знаю, если сберегайте строку используют еще несколько байтов, чем сохранение чисел, но если это сделало, он не сделал много заметной разницы даже для наших миллиардов записей.
Резюме
Dynamodb очень похоже на многие другие решения NoSQL, но существуют некоторые значительные ограничения дизайна в обмен на его нулевое обслуживание и легкое масштабирование.
Возможно, вам придется креативен в разработке ваших таблиц и вырваться из старых парадигм, чтобы выполнить работу. Но теперь, когда это сделано, я должен признать, что мне нравится проводить меньше времени поддержания и настройки нашего кластера MongoDB, потому что это освобождает мое время, чтобы сосредоточиться на фактическом строге нашего продукта!
Оригинал: «https://www.codementor.io/@mantle0/handling-date-and-datetime-in-dynamodb-du107mpin»