Разрабатываю собственную социальную сеть, и я не нашел в сети примеров реализации потока действий пользователей ... Например, как отфильтровать действия для каждого пользователя? Как сохранить события действия? Какую модель данных и объектную модель я могу использовать для потока действий и для самих действий?
design-patterns
architecture
stream
social-networking
Николо Мартини
источник
источник
Ответы:
Резюме : для примерно 1 миллиона активных пользователей и 150 миллионов сохраненных действий я делаю это простым:
Запросите Redis, чтобы получить поток активности для любого пользователя, а затем при необходимости получить связанные данные из базы данных. Вернитесь к запросу базы данных по времени, если пользователю нужно просмотреть далеко назад во времени (если вы даже предлагаете это)
Я использую простую старую таблицу MySQL для обработки около 15 миллионов операций.
Это выглядит примерно так:
activity_type
сообщает мне тип действия,source_id
сообщает мне запись, к которой относится действие. Итак, если тип действия означает «добавленный в избранное», то я знаю, что source_id относится к идентификатору избранной записи.parent_id
/parent_type
Полезны для моего приложения - они говорят мне , что деятельность связана с. Если книга была добавлена в избранное, то parent_id / parent_type сообщит мне, что действие относится к книге (типу) с заданным первичным ключом (id).Я индексирую
(user_id, time)
и запрашиваю действия, которые естьuser_id IN (...friends...) AND time > some-cutoff-point
. Отказ от идентификатора и выбор другого кластерного индекса может быть хорошей идеей - я не экспериментировал с этим.Довольно простые вещи, но они работают, они просты, и с ними легко работать, когда ваши потребности меняются. Кроме того, если вы не используете MySQL, вы можете лучше работать с индексами.
Для более быстрого доступа к последним действиям я экспериментировал с Redis . Redis хранит все свои данные в памяти, поэтому вы не можете поместить туда все свои действия, но вы можете сохранить достаточно для большинства часто посещаемых экранов на вашем сайте. Последние 100 для каждого пользователя или что-то в этом роде. С Redis в миксе это может работать так:
Redis работает быстро и предлагает способ конвейерной передачи команд через одно соединение, поэтому передача активности 1000 друзьям занимает миллисекунды.
Для более подробного объяснения того, о чем я говорю, см. Пример Twitter Redis: http://redis.io/topics/twitter-clone
Обновление от февраля 2011 г. У меня 50 миллионов активных действий, и я ничего не изменил. В том, чтобы делать что-то подобное, хорошо то, что они используют компактные, маленькие строки. Я планирую внести некоторые изменения, которые повлекут за собой гораздо больше действий и больше запросов об этих действиях, и я обязательно буду использовать Redis для ускорения работы. Я использую Redis в других областях, и он действительно хорошо работает для определенных типов проблем.
Обновление июль 2014 г. У нас около 700 тыс. Активных пользователей в месяц. Последние пару лет я использую Redis (как описано в маркированном списке) для хранения последних 1000 идентификаторов действий для каждого пользователя. Обычно в системе около 100 миллионов записей активности, они по-прежнему хранятся в MySQL и имеют тот же формат. Эти записи позволяют нам обойтись меньшим объемом памяти Redis, они служат для записи данных об активности, и мы используем их, если пользователям нужно перейти на более раннюю страницу во времени, чтобы что-то найти.
Это не было умным или особенно интересным решением, но оно сослужило мне хорошую службу.
источник
JOIN
на разныхactivity_type
столах? Эти соединения дороги с точки зрения производительности?activity_type
чтобы получить другие данные, которые вам нужны.Это моя реализация потока активности с использованием mysql. Существует три класса: Activity, ActivityFeed, Subscriber.
Действие представляет собой запись действия, и его таблица выглядит следующим образом:
Subject_id
это идентификатор объекта, выполняющего действие,object_id
идентификатор объекта, который получает действие.type
иverb
описывает само действие (например, если пользователь добавляет комментарий к статье, они будут «комментировать» и «созданы» соответственно), данные содержат дополнительные данные, чтобы избежать объединений (например, они могут содержать имя темы и фамилия, заголовок и URL статьи, текст комментария и т. д.).Каждое Activity принадлежит одному или нескольким ActivityFeed, и они связаны таблицей, которая выглядит следующим образом:
В моем приложении у меня есть один канал для каждого пользователя и один канал для каждого элемента (обычно статьи в блогах), но они могут быть какими угодно.
Подписчик обычно является пользователем вашего сайта, но он также может быть любым объектом в вашей объектной модели (например, статья может быть подписана на feed_action его создателя).
Каждый подписчик принадлежит одному или нескольким ActivityFeed, и, как и выше, они связаны таблицей ссылок такого типа:
В этом
reason
поле объясняется, почему подписчик подписался на ленту. Например, если пользователь добавляет в закладки сообщение в блоге, причина в «закладке». Это помогает мне в дальнейшем фильтровать действия для уведомлений пользователей.Чтобы получить активность для подписчика, я просто объединяю три таблицы. Присоединение происходит быстро, потому что я выбираю несколько действий благодаря
WHERE
условию, которое сейчас выглядит как -time > some hours
. Я избегаю других объединений благодаря полю данных в таблице действий.Дальнейшие пояснения по
reason
полю. Если, например, я хочу отфильтровать действия для уведомлений по электронной почте для пользователя, и пользователь добавил в закладки сообщение в блоге (и поэтому он подписывается на канал сообщений с указанием причины «закладка»), я не хочу, чтобы пользователь получал уведомления по электронной почте о действиях над этим элементом, а если он комментирует сообщение (и поэтому он подписывается на ленту сообщений с причиной «комментарий»), я хочу, чтобы он получал уведомление, когда другие пользователи добавляют комментарии к тому же сообщению. Поле причины помогает мне в этом различении (я реализовал его через класс ActivityFilter) вместе с настройками уведомлений пользователя.источник
Существует текущий формат потока активности, который разрабатывается группой хорошо известных людей.
http://activitystrea.ms/ .
По сути, у каждого действия есть субъект (который выполняет действие), глагол (действие действия), объект (на котором действует субъект) и цель.
Например: Макс разместил ссылку на стену Адама.
На момент написания их спецификация JSON достигла версии 1.0, которая показывает шаблон действия, которое вы можете применить.
Их формат уже принят BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID и многими другими.
источник
Я думаю, что объяснение того, как работает система уведомлений на крупных веб-сайтах, можно найти в вопросе о переполнении стека, как веб-сайты социальных сетей вычисляют обновления друзей? в ответе Джереми Уолла . Он предлагает использовать Message Qeue и указывает два программного обеспечения с открытым исходным кодом, которые его реализуют:
См. Также вопрос Как лучше всего реализовать поток социальной активности?
источник
Вам абсолютно необходима эффективная и распределенная очередь сообщений. Но на этом все не заканчивается, вам придется принимать решения о том, что хранить как постоянные данные, а что как временные и т. Д.
В любом случае, мой друг, это действительно сложная задача, если вам нужна высокопроизводительная и масштабируемая система. Но, конечно, некоторые щедрые инженеры поделились своим опытом по этому поводу. LinkedIn недавно сделал свою систему очередей сообщений Kafka с открытым исходным кодом. До этого Facebook уже предоставил Scribe сообществу с открытым исходным кодом. Kafka написан на Scala, и сначала требуется некоторое время, чтобы запустить его, но я тестировал его на нескольких виртуальных серверах. Это действительно быстро.
http://blog.linkedin.com/2011/01/11/open-source-linkedin-kafka/
http://incubator.apache.org/kafka/index.html
источник
Вместо того, чтобы использовать свой собственный, вы можете обратиться к стороннему сервису, используемому через API. Я начал один под названием Collabinate ( http://www.collabinate.com ), который имеет серверную часть графической базы данных и несколько довольно сложных алгоритмов для одновременной высокопроизводительной обработки больших объемов данных. Хотя у него нет такой широты функциональности, как у Facebook или Twitter, этого более чем достаточно для большинства случаев использования, когда вам нужно встроить в приложение потоки активности, социальные каналы или функции микроблогов.
источник