2014-06-26 6 views
8

Предположим, у нас есть приложение для социальной сети (с использованием NodeJS, Express) и MongoDB в качестве основного механизма базы данных.MongoDB и Redis как архитектура уровня кэша

В большинстве вызовов API от клиентов (мобильное приложение, веб-приложение и т. Д.) Я не хочу делать сложный запрос для каждого запроса. На эти запросы можно ответить с уровня кэша, например Redis.

Но мой вопрос в том, как/когда я должен обновлять уровень кэша, поскольку все операции записи выполняются в базе данных MongoDB, а не в уровне кэша (Redis). Каков правильный подход/архитектура для решения этой проблемы?

ответ

15

Это действительно зависит от ваших потребностей, но вот довольно часто один:

on_get_request 
    if data_in_redis 
    serve_data_from _redis 
    else 
    get_data_from_mongo 
    set_data_in_redis 
    set_expire_in_redis 
    serve_data_from_memory 

Данные будут немного несвежий время от времени, но это нормально для большинства случаев использования. Он хорошо работает в сочетании с некоторыми кэш недействительности, когда важные данные записываются:

on_important_data 
    delete_invalid_redis_keys 

Но это все предполагает низкую запись, высокое чтение и стабильный набор запросов.

Как выглядит ваш случай с высокой нагрузкой?

+0

Как насчет работы cron для заполнения кешей? –

+0

Может вступить в игру, если: a) приемлемое время простоя и b) время чтения велико. Что не редкость, хорошим случаем будет сокращение карты монго, где результаты, которые составляют десять минут, достаточно хороши, cron карта монго уменьшает каждые десять минут обновление redis. – generalhenry

5

Идельный подход - это путь кэш-памяти. Сначала вы можете написать mongodb, а затем написать redis. Это самый распространенный способ.

Другой вариант, Вы можете написать REDIS первый и отправить асинхронной сообщение с помощью Redis (например, Q) Некоторые нити могут потребить сообщение и прочитать его, записать его в MongoDB.

Первый вариант легче реализовать. Второй вариант может поддерживать огромное количество транзакций записи. Как я знаю, проблема блокировки mongodb еще не решена (она исправлена ​​из глобальной блокировки в блокировку уровня db) Второй вариант может быть значительным, чтобы уменьшить такой конфликт блокировки.

+0

фактическое тестирование показывает, что замок не является проблема с вставкой содержимого, так как обычно диск IO в конечном итоге будет максимальным. Пока схема и индексирование выполняются оптимально, латентность каждой вставки может оставаться постоянной по мере увеличения размера DB/индексов. –

0

Это потребует серьезной перекачки данных, чтобы сделать Redis жизнеспособной опцией для уровня кеша над MongoDB, учитывая, что у MongoDB есть рабочий набор, который хранится в ОЗУ; так как оба они могут действительно служить из памяти, если вы знаете, что делаете, и правильно планируете свою схему.

Обычно обращается к Redis для кэширования цели массивных объектов, таких как Craigslist (http://www.slideshare.net/jzawodn/living-with-sql-and-nosql-at-craigslist-a-pragmatic-approach), который, как вы можете видеть на слайде 7 этой презентации использовать его для:

  • счетчиков
  • сгустков
  • очереди

и больше, но вы можете легко увидеть, как их Memcached установки также могут быть объединены с ним, чтобы включить некоторые проводки, а если MongoDB были их основным хранилищем вместо MySQL.

Так что презентация сама по себе дает вам представление о том, как другие используют Redis с MongoDB.

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

Вот некоторые сведения, которые я буду использовать, чтобы немного поднять мой ответ: What is Redis and what do I use it for?. Я настоятельно рекомендую вам прочитать этот вопрос, поскольку это даст вам больше смысла в том, какой именно вариант использования Redis и что он может сделать.

+0

не забывайте, что MongoDB одновременно реплицирует данные и сбрасывает их на диск в виде журнала и в виде файлов данных, что замедлит его по сравнению с чистым решением в памяти. MongoDB * может быть сконфигурирован только в памяти - см. Мой ответ о том, как это сделал проект «Социологический». –

0

Вам нужны транзакции и записи в режиме реального времени? Когда кто-то пишет обновление о монго, абсолютно необходимо, чтобы клиенты немедленно уведомлялись об изменении (1 секунда/минута/день)?

Действительно ли ваши данные важны, чтобы любая запись не терялась? Если да, вы не можете писать redis сначала, за исключением AOF (который не является режимом по умолчанию при повторном использовании и намного медленнее). Сделки между mongo и redis не будут такими легко реализуемыми, например.

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

Другой способ, вы можете определить опрос с вашим приемлемым интервалом для реального времени между redis и mongo, чтобы обновить кеш с изменениями от mongo до redis (развязка), не записывая напрямую, чтобы перерисовать из вашего кода. Вы можете использовать прослушиватели («триггеры» в монго) для этого или использовать грязную проверку.

Наконец-то некоторые из них мигрировали из монго + redis в couchbase, например, viber, может быть, вам стоит рассмотреть его вариант? http://www.couchbase.com/viber

+0

Я только прочитал пару строк, но у MongoDB нет триггеров – Sammaye

5

Это уже реализовано в справочной архитектуре для MongoDB open source project called "Socialite", хотя оно находится на Java, а не node.js, поэтому мои ответы основаны на моем опыте и нагрузочном тестировании этого кода.

Как вы можете видеть из его реализации фида состояния, the feed has option fanoutOnWrite cache, который будет create a cache (limited size document) для активных пользователей, ограничивая количество последних записей в документе кеша (этот номер настраивается).

Ключевыми принципами этой реализации являются то, что требования к содержанию на самом деле отличаются от требований к кеш-керам, и сначала записывается база данных для записи в контент, так как это система записи для всего содержимого, а затем вы обновляете кеш (если это существует). Эта часть can be done asynchronously, при желании. В обновлении используются «ограниченные массивы» aka update $slice functionality, чтобы атомизировать новое значение/содержимое в массив и одновременно измельчать самую старую из них.

Не создавайте кеш для пользователя, если он еще не существует (если они никогда не вошли в систему, тогда вы тратите усилия). При желании вы можете использовать кеши на основе некоторого параметра TTL.

Когда вы читаете кэш для пользователя, когда он входит в систему, а его нет, затем возвращайтесь к «fanoutOnRead» (который запрашивает все содержимое пользователей, за которыми они следуют), а затем строит их кеш из этого результата ,

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

+0

Ницца получил мой голос – Sammaye

1

Поскольку ваш вопрос касается архитектуры и начинается с «Предположим ..."

Любая причина для выбора MongoDB?

С Postgres я получить более высокую производительность, чем MongoDB и лучшие из реляционных и schemaless документов с Postgres JSon/jsonb поддержки, которая на самом деле быстрее, чем MongoDB. С Postgres вы получите НАДЁЖНЫМ боевая закалка база данных, которая имеет отличную производительность, масштабируемость и, самое главное позволяет спать в ночное время и наслаждаться отпуском.

вы также можете использовать Postgres СЛУШАЙ/NOTIFY для событий в реальное время, так что вы можете выполнить REDIS кэша перебора.

Вот пример o е с использованием Postgres LISTEN/NOTIFY в nodejs: http://gonzalo123.com/2011/05/23/real-time-notifications-part-ii-now-with-node-js-and-socket-io/

Вот некоторые комплексные тесты производительности для Postgres 9.4 в качестве schemaless/NoSQL документа магазина против MongoDB:

http://thebuild.com/presentations/pg-as-nosql-pgday-fosdem-2013.pdf

+0

Вы обратили внимание на «позволяет вам спать по ночам и наслаждаться отдыхом» :-). Спасибо за ссылки тоже. –

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