Как реализовать поток активности в социальной сети

Я разрабатываю собственную социальную сеть, и я не нашел в сети примеров реализации потока действий пользователей... Например, как отфильтровать действия для каждого пользователя? Как хранить события акции? Какую модель данных и объектную модель я могу использовать для потока действий и для самих действий?

7 ответов

Решение

Резюме: для примерно 1 миллиона активных пользователей и 150 миллионов хранимых действий я упрощаю:

  • Используйте реляционную базу данных для хранения уникальных действий (1 запись на действие / "вещь, которая произошла"). Сделайте записи максимально компактными. Структура, позволяющая быстро получить пакет действий по идентификатору активности или с помощью набора идентификаторов друзей с временными ограничениями.
  • Публикуйте идентификаторы активности в Redis при каждом создании записи активности, добавляя идентификатор в список "потока активности" для каждого пользователя, который является другом / подписчиком, который должен видеть действие.

Запросите Redis, чтобы получить поток активности для любого пользователя, а затем, при необходимости, получите связанные данные из БД. Вернитесь к запросам по БД по времени, если пользователю нужно просматривать далеко назад во времени (если вы даже предлагаете это)


Я использую простую старую таблицу MySQL для работы примерно с 15 миллионами операций.

Это выглядит примерно так:

id             
user_id       (int)
activity_type (tinyint)
source_id     (int)  
parent_id     (int)
parent_type   (tinyint)
time          (datetime but a smaller type like int would be better) 

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 в миксе, это может работать так:

  • Создайте свою запись активности MySQL
  • Для каждого друга пользователя, создавшего действие, вставьте идентификатор в свой список действий в Redis.
  • Обрезать каждый список до последних X элементов

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

Для более подробного объяснения того, о чем я говорю, см. Пример Redis в Twitter: http://redis.io/topics/twitter-clone

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

Обновление июль 2014 г. Ежемесячно мы получаем около 700 000 активных пользователей. Последние пару лет я использую Redis (как описано в маркированном списке) для хранения последних 1000 идентификаторов активности для каждого пользователя. Обычно в системе около 100 миллионов записей активности, и они все еще хранятся в MySQL и имеют ту же структуру. Эти записи позволяют нам с меньшим количеством памяти Redis, они служат в качестве записи данных деятельности, и мы используем их, если пользователям нужно искать страницы назад во времени, чтобы что-то найти.

Это не было умным или особенно интересным решением, но оно послужило мне хорошо.

Это моя реализация потока активности, использующая mysql. Существует три класса: Activity, ActivityFeed, Подписчик.

Activity представляет собой запись активности, и ее таблица выглядит следующим образом:

id
subject_id
object_id
type
verb
data
time

Subject_id идентификатор объекта, выполняющего действие, object_id идентификатор объекта, который получает действие. type а также verb описывает само действие (например, если пользователь добавляет комментарий к статье, он будет "комментировать" и "создан" соответственно), данные содержат дополнительные данные во избежание объединений (например, они могут содержать имя субъекта и фамилия, название статьи и URL, тело комментария и т. д.).

Каждое действие принадлежит одному или нескольким ActivityFeeds, и они связаны таблицей, которая выглядит следующим образом:

feed_name
activity_id

В моем приложении у меня есть один фид для каждого пользователя и один фид для каждого элемента (обычно это статьи блога), но они могут быть любыми.

Подписчик обычно является пользователем вашего сайта, но это также может быть любой объект в вашей объектной модели (например, статья может быть подписана на feed_action его создателя).

Каждый подписчик принадлежит одному или нескольким ActivityFeeds, и, как и выше, они связаны таблицей ссылок такого типа:

feed_name
subscriber_id
reason

reason поле здесь объясняет, почему подписчик подписался на канал. Например, если пользователь делает закладку на запись в блоге, причина - "закладка". Это поможет мне позже в фильтрации действий для уведомлений для пользователей.

Чтобы получить действие для подписчика, я делаю простое объединение трех таблиц. Соединение происходит быстро, потому что я выбираю несколько видов деятельности благодаря WHERE состояние, которое выглядит сейчас - time > some hours, Я избегаю других объединений благодаря полю данных в таблице Activity.

Дальнейшее объяснение reason поле. Если, например, я хочу отфильтровать действия для уведомлений по электронной почте для пользователя, и пользователь добавил в закладки запись в блоге (и поэтому он подписывается на ленту сообщений с причиной "закладки"), я не хочу, чтобы пользователь получал уведомления по электронной почте о действиях над этим элементом, в то время как если он комментирует сообщение (и поэтому оно подписывается на ленту сообщений с причиной "комментарий"), я хочу, чтобы он был уведомлен, когда другие пользователи добавляют комментарии к тому же сообщению. Поле причины помогает мне в этом различении (я реализовал это через класс ActivityFilter) вместе с настройками уведомлений пользователя.

Существует текущий формат потока активности, который разрабатывается группой известных людей.

http://activitystrea.ms/.

По сути, каждое действие имеет субъекта (который выполняет действие), глагол (действие действия), объект (над которым действует субъект) и цель.

Например: Макс опубликовал ссылку на стену Адама.

На момент написания этой статьи их спецификация JSON достигла версии 1.0, в которой показан шаблон действия, которое вы можете применить.

Их формат уже принят BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID и многими другими.

Я думаю, что объяснение того, как система уведомлений работает на больших сайтах, можно найти в вопросе переполнения стека, как сайты социальных сетей вычисляют обновления друзей? в ответ Jeremy Wall. Он предлагает использовать Message Qeue и указывает на две программы с открытым исходным кодом, которые его реализуют:

  1. RabbitMQ
  2. Apache QPid

Смотрите также вопрос Каков наилучший способ реализации потока социальной активности?

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

В любом случае, мой друг, это действительно сложная задача, если вам нужна высокопроизводительная и масштабируемая система. Но, конечно, некоторые щедрые инженеры поделились своим опытом по этому вопросу. В последнее время LinkedIn сделала свою систему сообщений Kafka с открытым исходным кодом. До этого Facebook уже предоставил Scribe сообществу открытого кода. Kafka написан на Scala, и сначала для его запуска требуется некоторое время, но я протестировал пару виртуальных серверов. Это действительно быстро.

http://blog.linkedin.com/2011/01/11/open-source-linkedin-kafka/

http://incubator.apache.org/kafka/index.html

Хорошей практикой для Платформы социальных сетей Dearlink является включение визуального элемента в каждое сообщение. Даже если ваш пост является текстовым, добавьте графику или фотографию, чтобы повысить вовлеченность. Видео также являются хорошим дополнением. Вы также можете повысить вовлеченность, завершив сообщение восклицательным знаком. Позитивные настроения хороши для постов Dearlink. Точно так же задайте своей аудитории вопрос, чтобы привлечь больше внимания читателей, например комментарии. Хэштеги Использование хэштегов на Платформе социальных сетей Dearlink — это хороший способ связать ваш пост с более широкой дискуссией. Это также может привлечь больше внимания, если вы будете выбирать хэштеги с умом. Тем не менее, хэштеги на Dearlink не очень популярны, поэтому ограничьтесь одним или двумя. Вы можете создавать свои собственные хэштеги, связанные с брендом, и использовать их. Например, маркетинговая кампания с собственным хэштегом отлично подходит для привлечения внимания.https://www.dearlink.livehttps://m.dearlink.live

Вместо того, чтобы использовать свой собственный, вы можете обратиться к стороннему сервису, используемому через API. Я запустил один под названием Collabinate ( http://www.collabinate.com/), который имеет серверную базу данных графа и несколько довольно сложных алгоритмов для обработки больших объемов данных с высокой степенью параллелизма и высокой производительности. Хотя он не обладает широким набором функциональных возможностей, как, например, Facebook или Twitter, этого более чем достаточно для большинства случаев использования, когда вам необходимо встроить потоки действий, социальные каналы или функции микроблогов в приложение.

Другие вопросы по тегам