2014-02-06 2 views
8

Как реализовать динамическое обновление подсчета голосов, похожего на quora: - всякий раз, когда пользователь поднимает ответ, он автоматически отражается для каждого, кто просматривает эту страницу.Реализация динамического обновления upvote/downvote

Я ищу ответ, которые касаются следующим:

  • ли мы должны продолжать опрос для upvote подсчетов для каждого ответа, если да то, как управлять нагрузкой сервера, возникающей из-за многими пользователями
    опрос на upvotes.
  • Или использовать websockits/push-уведомления, насколько они масштабируемы?
  • Как сохранить счет upvote/downvote в базах данных/inmemory для поддержки этого. Как они контролируют количество операций чтения/записи. Бэкэнд-база данных - mysql

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

+0

Для опроса используйте длительный опрос, который по меньшей мере уменьшает количество просмотров на сервере. У вас есть петля с задержкой в ​​конце и выходите из цикла, когда вы находите что-то, чтобы отчитываться перед фронтом (или после фиксированного времени, чтобы остановить сиротские запросы, оставаясь слишком долго). Затем внешний интерфейс обрабатывает данные и отправляет следующий запрос. – Kickstart

+0

Вам нужно только обновить количество голосов или многое другое? Объем данных и то, как часто обновляются обновления/получение данных с сервера, определяет, какие технологии/методы использовать.
Если это только количество голосов, то используйте обычный AJAX-101, передайте серверу массив идентификаторов сообщений и верните объект JSON (несколько килобайт) нового счетчика голосов и с простым jquery обновите представление, запустите это каждые 2 секунды с помощью setInterval и очистите его самостоятельно, чтобы не было большого использования памяти. – MJoraid

+0

Этот процесс можно оптимизировать. Если вы хотите подключиться к серверу в режиме реального времени, просто немного обновите свои методы и используйте node.js. Если вы ожидаете, что объем данных должен быть обновлен, он будет увеличиваться, а затем использовать тот же техно, что и в системе чата facebook/gmail/yahoo «Протокол обмена сообщениями в реальном времени» => «- это протокол на основе TCP, который поддерживает постоянные подключения и позволяет плавно передавать потоки и передавать как можно больше информации, он разбивает потоки на фрагменты и их размер согласовывается динамически между клиентом/сервером « – MJoraid

ответ

4

Это не задние системные детали, о которых вам нужно беспокоиться, но передняя часть.Наличие открытого соединения все время непрактично в любом реальном масштабе. Вместо этого вы хотите обратное - чтобы можно было быстро и быстро подключать и подключаться к серверу.

Websockets - это сексуальная технология, но опять же, в реальном мире есть issues with proxies, если вы разрабатываете что-то, что должно работать на разных экранах (рабочий стол, планшет, мобильный), это может стать для вас проблемой. Даже добрые долгие опросы могут не работать через брандмауэры и прокси.

Вот хорошая новость: Я думаю, что

«держать опрос для upvote подсчетов для каждого ответа»

является вполне хорошим решением в этом случае. Рассмотрим следующий пример:

  • ваш вариант использования не требует каких-либо реальных обновления в режиме реального времени. Существует немного вреда, чтобы увидеть счетчик, обновленный немного позже.
  • для очень популярных тем, которые вы хотели бы раздавить несколько голосов/голосов в одном в любом случае
  • большинство тем не увидит ни одного голосования -отслеживать трафик вообще в течение нескольких дней/недель, поэтому держать соединение открытым, ожидая события, которое никогда не приходит, - это отходы
  • большинство пользователей никогда не будет голосовать за голос или проголосовать за то, что только что прочитало тему, так что ваш уровень чтения/записи по темам будет сильно искажен по отношению к чтению
  • Сетевые латентности сильно различаются по клиентам, вы увидите ужасные скорости передачи для ответов 100B http, в то время как этот вялый клиент извлекает свой ответ побайтно ваш драгоценный сервис эр связь и что более важно - нить на заднем сервере занят

Вот что я хотел бы начать с:

  • есть браузеры периодически опрашивать новую тему стата, после того, как основной страница загружается
  • держите свой MySQL, держите там счетчики. Каждый раз, когда появляется обновление вверх/вниз, DB
  • помещает Memcached перед БД в качестве кэш-памяти для записи, то есть каждый раз, когда есть кеш обновления обновления/уменьшения, затем обновляйте БД. Установите явное время истечения срока действия счетчика на 10-15 минут. Каждый раз, когда счетчик обновляется, срок действия продлевается автоматически.
  • дизайн этого избирательного HTTP требует, чтобы быть кэшируемыми по HTTP прокси, установите истекают и ТТЛ заголовки HTTP, чтобы быть 60 сек
  • поставить обратный прокси-сервер (Varnish, nginx) перед фронтальными серверами, имеет этот прокси сделать кэширование указанных вызовов. Они заботятся о кеше второго уровня и помогают быстрее освобождать серверные серверные потоки, см. Информацию о сетевых записях выше
  • настроить ваш обратный прокси-компонент для общения с серверами memcached напрямую без звонка на серверный сервер, да если вы можете сделать это как с лаком, так и с nginx.
  • нет никакой привлекательной схемы для хранения таких данных, это простая операция inc()/dec() в memcached, обратите внимание, что она безопасна с точки зрения состояния гонки.Это также безопасная атомная операция в MySQL UPDATE table SET field = field + 1 WHERE [...]

Агрессивное кэширование многоуровневый охватывает ваш read путь: в Memcached и во всех HTTP кэши по пути, обратите внимание, что эти запросы HTTP опрос будет кэшируются на edges, а также.

Чтобы позаботиться о длинном хвосте непопулярной темы - сделайте http ttl для таких ответов обратным пропорциональным популярности.

Запрос на чтение будет редко попадать на внешний сервер, когда кэш кэша истек, а memcached также не имеет его. Если это все еще проблема, добавьте memecached серверы и увеличьте время истечения срока действия в memcached по всей доске.

После того, как вы закончили с этим, у вас есть все reads. Единственная проблема, которую вы все еще можете иметь, в зависимости от масштаба, - это высокая скорость writes т. Е. Поток голосов вверх/вниз. Здесь ваш единственный экземпляр MySQL может начать показывать некоторые задержки. Не бойтесь - продолжайте по старой дорожке с чередованием ваших экземпляров или добавьте NoSQL-хранилище только для счетчиков.

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

2

звучит так, как будто вы можете использовать систему обмена сообщениями, такую ​​как Kafka, или RabbitMQ, или ActiveMQ. Ваш фронт-сервер отправил голоса на канал сообщений и получил их с прослушивателем, и вы могли бы иметь часть на стороне сервера, периодически сохраняя голоса в db.

Вы также можете выполнить свою задачу, опросив вашу базу данных, а также увеличив/уменьшив число, относящееся к сообщению, через хранимую процедуру ... здесь есть множество параметров, и это зависит от того, быть лицом к лицу.

+0

ли системы обмена сообщениями поддерживают активное соединение для обновления прослушивателей? В моем случае пользователи получат доступ через веб-браузер и предположим, что слишком много пользователей не будут слишком сильно нажимать на такие системы? мне придется увеличить размер кластера, чтобы справиться с этим? – akshay202

+0

Я не использовал Кафку, но кажется многообещающим. Существует api для опроса системы здесь https://cwiki.apache.org/confluence/display/KAFKA/Consumer+Group+Example Kafka масштабирует, добавляя узлы, и он может обрабатывать огромный объем. Некоторые довольно крупные компании используют его https://cwiki.apache.org/confluence/display/KAFKA/Powered+By – markg

5

Websockets, Server Sent Events (Я думаю, это то, что вы имели в виду под «push-уведомлениями»), и длинный опрос AJAX имеет тот же недостаток - они продолжают поддерживать открытое TCP-соединение в течение длительного времени.
Итак, вопрос в том, сколько открытых TCP-соединений может обрабатывать сервер. В основном это зависит от его ОС, количества дескрипторов файлов (параметр конфигурации) и доступной памяти (каждое открытое соединение резервирует буферы чтения/записи). Here's more on that.

раз мы протестировали возможность держать 1 миллион WebSocket открытых соединений на одном сервере (Windows 7 x64 с 16 Гб оперативной памяти, виртуальной машины Java 1.7 с 8Gb кучи, используя Undertow beta для обслуживания веб-запросов). Удивительно, что самой сложной задачей было создание нагрузки на сервер)
Удалось удерживать 1M. Но снова сервер не сделал ничего полезного, только что получил запросы, прошел обновление протокола и открыл эти подключения. По какой-то причине было также некоторое количество потерянных соединений. Мы не расследовали. Но в производстве вам также придется пинговать сервер и обрабатывать пересоединение.

Кроме того, Websockets кажутся излишними, SSE still aren't widely adopted. Так что я бы пошел с хорошим старым опросом AJAX, но оптимизировал его как можно больше.
Работает везде, просто реализуется и настраивается, не полагается на внешнюю систему (у меня был плохой опыт с этим несколько раз), возможности для оптимизации. Например, вы можете группировать обновления для всех открытых статей в одном браузере или настраивать интервал обновления в соответствии с тем, насколько популярна эта статья.
В конце концов, вам не нужны уведомления в режиме реального времени.

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