Як реалізувати потік активності в соціальній мережі


140

Я розвиваю власну соціальну мережу, і в Інтернеті не знайшов прикладів реалізації потоку дій користувачів ... Наприклад, як фільтрувати дії для кожного користувача? Як зберігати події дії? Яку модель даних та об'єктну модель можна використовувати для потоку дій та для самих дій?


9
удачі, це нескінченне запитання, про яке ми всі хочемо знати, як фейсбук його відтягує, відповідь дуже складна, і ми ніколи не можемо знати найефективніший спосіб зробити це. Якщо ви знайдете ДОБРИЙ підхід, будь ласка, опублікуйте його тут, щоб інші його переглянули, BTW про це багато разів обговорювалося в ТАК, тому просто шукайте, і ви знайдете поради
JasonDavis,

1
Stream Framework - це найпоширеніше рішення: github.com/tschellenbach/Stream-Framework Також дивіться цей перелік пакунків: djangopackages.com/grids/g/activities
Thierry

1
Що стосується персоналізації, то вона заснована на аналітиці та машинному навчанні. Також дивіться getstream.io/personalization
Thierry

Відповіді:


241

Короткий зміст : Для близько 1 мільйона активних користувачів та 150 мільйонів збережених дій я просто кажу:

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

Запросіть Redis, щоб отримати потік активності для будь-якого користувача, а потім захопити відповідні дані з db за потреби. Повертайтеся до запиту на db час, якщо користувачеві потрібно переглядати далеко назад у часі (якщо ви навіть пропонуєте це)


Я використовую звичайну стару таблицю 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 тис. Активних користувачів щомісяця. Останні кілька років я використовував Redis (як описано в маркованому списку) для зберігання останніх 1000 ідентифікаторів активності для кожного користувача. Зазвичай у системі є близько 100 мільйонів записів про діяльність, і вони все ще зберігаються в MySQL і все ще мають однаковий макет. Ці записи дозволяють нам позбутися меншої кількості пам'яті Redis, вони служать записом даних про діяльність, і ми використовуємо їх, якщо користувачам потрібно переглядати сторінку ще в часі, щоб щось знайти.

Це не було розумним чи особливо цікавим рішенням, але воно мені добре послужило.


2
+1 для Redis. v2 використовує віртуальну пам’ять, тому слід повністю покладатися на Redis
стага

16
Якщо існує декілька джерел активності (додавання, коментування, подобається тощо), як ви з'єднаєте цю таблицю з фактичною діяльністю? Чи використовуєте ви кілька лівих приєднань (кожен для таблиці активності)?
Алі Шакіба

1
Питання @casey Echoing @JohnS - як ви виконуєте JOINрізні activity_typeтаблиці? Це приєднуються до дорогих виступів?
Роб Соберс

1
Хто-небудь отримав відповідь на питання Джонса про "ПРИЄДНАЙТЕСЬ". Чи може хтось розмістити посилання, де це може бути пояснено? Я маю зробити подібну річ, і мені це було б дуже корисно.
Waseem

3
Ніяких приєднань. Один запит на унікальний, activity_typeщоб отримати інші потрібні вам дані.
обігнав

21

Це моя реалізація потоку активності, використовуючи mysql. Є три класи: Діяльність, Активність, Підписка.

Діяльність являє собою запис про діяльність, і його таблиця виглядає приблизно так:

id
subject_id
object_id
type
verb
data
time

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

Кожна діяльність належить до одного або декількох каналів діяльності, і вони пов'язані таблицею, яка виглядає приблизно так:

feed_name
activity_id

У своїй програмі я маю один канал для кожного Користувача та один канал для кожного пункту (зазвичай статті блогу), але вони можуть бути будь-якими, що ви хочете.

Абонент, як правило, є користувачем вашого веб-сайту, але це також може бути будь-який об’єкт у вашій об’єктній моделі (наприклад, стаття може бути підписана на канал завантаження його творця).

Кожен абонент належить до одного або декількох каналів діяльності, і, як і вище, вони пов'язані таблицею посилань такого роду:

feed_name
subscriber_id
reason

reasonПоле тут пояснює , чому абонент підписався на канал. Наприклад, якщо користувач додає закладки до блогу, причиною є "закладка". Це допомагає мені згодом у фільтрації дій для сповіщень перед користувачами.

Щоб отримати активність для абонента, я виконую просте з'єднання трьох таблиць. Об’єднання швидко, тому що я вибираю декілька видів діяльності завдяки WHEREумові, який виглядає зараз - time > some hours. Я уникаю інших приєднань завдяки полі даних у таблиці "Діяльність".

Подальше пояснення на reasonмісцях. Наприклад, якщо я хочу відфільтрувати дії для сповіщень електронною поштою користувачеві, і користувач зробив закладки в блозі (і таким чином він підписався на канал публікації з причиною "закладки"), я не хочу, щоб користувач отримував сповіщення електронною поштою про дії з цим елементом, тоді як якщо він коментує публікацію (і тому він підписується на канал публікації з поясненням "коментар"), я хочу, щоб його отримували повідомлення, коли інші користувачі додають коментарі до тієї ж публікації. Поле причини допомагає мені в цій дискримінації (я реалізував її через клас ActivityFilter) разом з уподобаннями користувача сповіщень.


Ніколо Мартіні, я хотів додати коментар відповіді щодо діяльності та показати це під ним, як це можливо зі своєю структурою? я повинен додати ще одну таблицю або просто використовувати ту саму, якщо таку ж, то які ваші пропозиції?
Базит

Яке виконання цієї реалізації? Будь-які тести на великих столах?
Джошуа Ф. Рінтрі

16

Існує поточний формат потоку активності, який розробляє купа відомих людей.

http://activitystrea.ms/ .

В основному, в кожній діяльності є актор (який виконує діяльність), дієслово (дія діяльності), предмет (над яким виступає актор) і ціль.

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

На момент написання їх Spec JSON досягла версії 1.0, яка показує схему діяльності, яку ви можете застосувати.

Їх формат уже прийняли BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID та багато інших.


привіт @sntran Я знаю, що це повідомлення було років тому, але у мене є питання більше про потік діяльності. Чи можна допомогти?
hiswendy

Звичайно. Яке Ваше запитання?
Sơn Trần-Nguyễn

Моє запитання насправді розміщено тут! посилання . Я думаю, що я розумію потік активності, але я не дуже впевнений, як його реалізувати (тобто я повинен використовувати angular або node.js?) І звідти, як мені насправді СТВОРИТИ потік активності за допомогою API, що надходить, JSON? Це такі основні питання, але в Інтернеті я не знайшов жодної відповіді. Якщо ви можете допомогти, я б дуже по достоїнству оцінив це. Дякую!
hiswendy

13

Я думаю, що пояснення про те, як працює система сповіщень на великих веб-сайтах, можна знайти в питанні про переповнення стека, як веб-сайти соціальних мереж обчислюють друзів? , у відповіді Джеремі Стіни . Він пропонує використовувати чергу повідомлень, і він вказує два програмні програми з відкритим кодом, які її реалізують:

  1. КроликMQ
  2. Apache QPid

Дивіться також питання Який найкращий спосіб здійснення потоку соціальної активності?


1

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

У будь-якому випадку, мій друг, це справді важке завдання, якщо ти маєш високу продуктивність та масштабовану систему. Але, звичайно, деякі щедрі інженери поділилися своїм досвідом щодо цього. Нещодавно LinkedIn зробив свою систему черги повідомлень Kafka з відкритим кодом. До цього Facebook вже надав Scribe спільноті з відкритим кодом. Kafka написана у Scala, і спочатку потрібно деякий час, щоб запустити її, але я перевірив пару віртуальних серверів. Це дійсно швидко.

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

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


0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.