2016-01-22 2 views
0

Я столкнулся с интересной дилеммой, пытаясь решить проблему масштаба.NewsFeed с Redis at Scale Stratagy

В настоящее время у нас есть социальная платформа, которая имеет довольно типичный канал. Мы используем базу данных графа, и каждый раз, когда запрос запрашивается пользователем, мы попадаем в БД. Хотя сейчас все в порядке, он будет останавливаться, когда мы вырастием нашу базу пользователей. Введите Redis.

В настоящее время мы храним такие вещи, как комментарии, симпатии и т. Д. В отдельных ключах Redis в закодированных по JSON строках по идентификатору сообщения и обновляем их, когда есть обновления, добавления или удаления. Затем в коде мы просматриваем результаты DB-сообщений и извлекаем данные из магазина Redis. Это вызывает множественные вызовы Redis для создания каждого сообщения, что намного лучше, чем касаться DB каждый раз. Задача состоит в том, чтобы следить за изменением данных, таких как аватары комментатора/liker, имена экранов, закрытые учетные записи, новые понравившиеся, новые комментарии и т. Д., Связанные с каждым отдельным сообщением.

Я пытаюсь решить стратегию, чтобы справиться с этим самым эффективным способом. Redis будет забирать нас до сих пор, так как мы выберем около 12 гигабайт оперативной памяти на машину.

Одна из концепций в обсуждении - использовать маяк для каждого пользователя, который сохраняет новый идентификатор сообщения. Поэтому, когда пользователь делится чем-то новым, все маяки их подключенных друзей получают идентификатор сообщения, поэтому, когда пользователь регистрируется в своем канале, он рассматривается как «Грязный», требующий обновления, а затем сохраняет фид по идентификатору в наборе Redis Set, отсортированном по метке времени. Чтобы получить данные фида, мы можем сделать один запрос по идентификаторам, а не полный обход, который в сотни раз быстрее. Это все еще не решает информацию об учетной записи взаимодействующего пользователя, их проблемах и проблемах с комментариями, которые когда-либо меняются, но решает частично проблему с подачей.

Другая идея состоит в том, чтобы хранить весь канал пользователя (закодированный JSON) в записи MYSQL и обновлять его на лету, когда пользователь запрашивает его, а маяк показывает грязный фид. В противном случае для создания фида можно использовать только один select и json decode. Опять же, динамические компоненты - это huddle.

Кто-нибудь успешно справился с этим заданием или имел практические знания о стратегии решения этой проблемы.

+0

У вас нет полного ответа на вашу проблему, но если вы уже работаете с данными JSON, просмотрели ли вы [MongoDB] (https://www.mongodb.org)? Я использую его в течение многих лет, и он невероятно хорошо масштабируется с наборами реплик и окантовкой. Redis все еще будет более быстрым однократным временем поиска, но mongo обеспечивает гибкость для хранения всего набора данных JSON - кажется лучшим решением, чем хранение данных JSON в записи MySQL :) – solocommand

+0

Мне также нравится идея использования MongoDB, как описано выше, если вам нужно дальнейшее расширение, Riak также может быть другим вариантом для использования, поскольку он имеет исходящие ссылки perty с хорошей обработкой. – Daniel

ответ

1

Возможно, вы захотите использовать mongodb, как описано в @solocommand, но вы можете остановить ожидание того, что вы «обновляете» данные по запросу. Вместо этого вставьте свои пользователи в очередь «write», которая затем обновит базу данных по мере необходимости. Затем вы можете загрузить из базы данных (mongodb) и работать с ней по мере необходимости или обновить другие записи redis.

Переход на систему обмена сообщениями Amazon SQS, IronMQ или RabbitMQ может помочь вам улучшить масштаб. Вы также можете использовать очереди redis в качестве базовой шины сообщений.

1

В настоящее время мы храним вещи, как комментарии, любит и такие в отдельных ключах Redis в JSON закодированных строк по почте ID

Используйте более эффективный сериалайзер, как igbinary или msgpack. Я предлагаю igbinary (проверить http://kiss-web.blogspot.com/)

Тогда в коде цикла по результатам БД сообщений и тянуть в данных из хранилища Redis.

Обязательно используйте конвейер для максимальной производительности.

Это вызывает несколько обращений к Redis для создания каждого сообщения, что намного лучше, чем касаться DB каждый раз.

Не следует недооценивать мощность первичных ключей БД. Попробуйте сделать то же самое (не присоединиться, но выбрать с помощью клавиш) с БД:

SELECT * FROM comments WHERE id IN (1,2,3,4,5,6): 

Single Redis вызов работает быстрее, чем один вызов DB, ​​но делать много REDIS звонков (даже конвейерный) по сравнению с одним SQL запросом на первичных ключах - не так много. Особенно, когда вы даете вашей БД достаточно памяти для буферов.

Вы можете использовать DB и Redis путем «кэширования» данных DB в redis. Вы делаете что-то вроде этого:

  1. Каждый раз, когда вы обновляете данные, вы обновляете их в БД и удаляете из Redis.
  2. При извлечении данных вы сначала пытаетесь получить их от Redis. Если данные не найдены в Redis, вы выполняете поиск их id DB и вставляете в Redis для будущего использования с некоторым временем истечения срока действия.

Таким образом, вы храните в redis только полезные данные. Неиспользуемые (старые) данные останутся только в БД.

+0

Спасибо за советы. Мы перешли к очень похожему подходу с помощью конвейерных и mget-вызовов, чтобы лучше справляться с природой более динамичной информации. – SeaFuzz

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