Дизайн схемы MongoDB - чат в режиме реального времени

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

Модуль, которым я в настоящее время интересуюсь, относится к чату в режиме реального времени. Если я должен был сделать это в традиционном RDBMS, я разделил его на:

  • Канал (Канал имеет многих пользователей),
  • Пользователь (У пользователя есть один канал, но много сообщений),
  • Сообщение (Сообщение имеет пользователя),

Цель этого варианта использования, я хотел бы предположить, что обычно будет 5 каналов, активных когда-то, каждая обработка самое большее 5 сообщений в секунду.

Определенные запросы, которые должны быть быстрыми:

  • Выберите новые сообщения (на основе закладки, метка времени, возможно, или счетчик постепенного увеличения?)
  • Добавьте сообщение к каналу
  • Проверьте, что пользователь может отправить в канале

Мысль, что предел документа с MongoDB составляет 4 МБ, как Вы пошли бы о разработке схемы? Как что был бы Ваш взгляд? Есть ли какие-либо глюки, которые я должен не упустить?

14
задан Community 22 September 2017 в 18:01
поделиться

3 ответа

Я использовал Redis , NGINX и PHP-FPM для своего проекта чата. Не очень элегантно, но все же помогает. Пазл состоит из нескольких частей.

  1. Существует очень простой сценарий PHP, который принимает клиентские команды и помещает их в один большой СПИСОК. Он также проверяет все СПИСКИ комнат и частный СПИСОК пользователей, чтобы увидеть, есть ли сообщения, которые он должен доставить. Это опрашивается клиентом, написанным на jQuery, и это делается каждые несколько секунд.

  2. Существует сценарий PHP командной строки, который работает на стороне сервера в бесконечном цикле 20 раз в секунду, который проверяет этот список, а затем обрабатывает эти команды. Сценарий определяет, кто в какой комнате находится, и разрешения в памяти сценариев, эта информация не сохраняется в Redis.

  3. Redis имеет СПИСОК для каждой комнаты и СПИСОК для каждого пользователя, который работает как частная очередь. Он также имеет несколько счетчиков для каждой комнаты, в которой находится пользователь. Если счетчик пользователей меньше общего количества сообщений в комнате, то он получает разницу и отправляет ее пользователю.

Мне не удалось провести стресс-тестирование этого решения, но, по крайней мере, исходя из моего базового тестирования, оно, вероятно, могло обрабатывать многие тысячи сообщений в секунду. Также есть возможность перенести это на что-то вроде Node.js для повышения производительности. Redis также развивается и имеет некоторые интересные функции, такие как команды Pub / Subscribe, которые могут быть интересны, которые, возможно, могут удалить опрос на стороне сервера.

Я изучал решения на основе Comet, но многие из них были сложными, плохо документированными или требовали от меня изучения совершенно нового языка (например, Jetty-> Java, APE-> C) и т. Д.Также доставка и прохождение через прокси-серверы иногда могут быть проблемой для Comet. Вот почему я придерживаюсь опросов.

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

3
ответ дан 1 December 2019 в 16:24
поделиться

Зачем использовать mongo для системы обмена сообщениями? Независимо от того, насколько быстро статическое хранилище (а mongo очень быстрое), будь то mongo или db, для имитации очереди сообщений вам придется использовать какой-то опрос, который не очень масштабируем или эффективен. Конечно, вы не делаете ничего особенно интенсивного, но почему бы просто не использовать правильный инструмент для правильной работы? Используйте систему обмена сообщениями, например Rabbit или ActiveMQ .

Если вам необходимо использовать mongo (возможно, вы просто хотите поиграть с ним, и этот проект - хороший шанс для этого?), Я полагаю, у вас будет коллекция для пользователей (где каждый пользовательский объект имеет список очереди, которые слушает пользователь). Для сообщений у вас может быть коллекция для каждой очереди, но тогда вам придется опрашивать каждую очередь, которая вас интересует, на предмет сообщений. Лучше было бы иметь одну коллекцию в качестве очереди, поскольку в mongo легко выполнять запросы «in» к одной коллекции, поэтому было бы легко делать такие вещи, как «получить все сообщения новее X в любых очередях, где очередь .name в списке [a, b, c] ".

Вы также можете подумать о том, чтобы настроить свою коллекцию как коллекцию с ограничением монго, что просто означает, что вы указываете mongo при настройке коллекции, что ваша коллекция должна содержать только X байтов или X элементов. Добавление дополнительных элементов имеет поведение «первым пришел - первым обслужен», что в значительной степени идеально для очереди сообщений. Но опять же, это не совсем система обмена сообщениями.

3
ответ дан 1 December 2019 в 16:24
поделиться

1) ape-project.org

2) http://code.google.com/p/redis/

3) после того, как вы пройдете все это - вы можете вводить данные в mongodb для регистрации и сохранения согласованных данных (пользователей, каналов)

1
ответ дан 1 December 2019 в 16:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: