Jak wdrożyć Strumień aktywności w sieci społecznościowej

Rozwijam własną sieć społecznościową i nie znalazłem w sieci przykładów implementacji strumienia działań użytkowników... Na przykład, jak filtrować akcje dla każdego użytkownika? Jak przechowywać zdarzenia akcji? Jakiego modelu danych i modelu obiektowego mogę użyć dla strumienia akcji i dla samych akcji?

Author: dreftymac, 2009-09-18

6 answers

Podsumowanie: dla około 1 miliona aktywnych użytkowników i 150 milionów przechowywanych aktywności, trzymam to prosto:

  • użyj relacyjnej bazy danych do przechowywania unikalnych działań (1 rekord na działanie / "rzecz, która się wydarzyła") spraw, aby rekordy były tak kompaktowe, jak to tylko możliwe. Struktura, dzięki której można szybko pobrać partię działań według identyfikatora aktywności lub za pomocą zestawu identyfikatorów znajomych z ograniczeniami czasowymi.
  • publikowanie identyfikatorów aktywności do Redis za każdym razem, gdy tworzony jest rekord aktywności, dodanie identyfikatora do listy "Strumień aktywności" dla każdego użytkownika, który jest przyjacielem / subskrybentem, który powinien zobaczyć aktywność.

Zapytanie Redis, aby uzyskać Strumień aktywności dla dowolnego użytkownika, a następnie pobrać powiązane dane z db w razie potrzeby. Jeśli użytkownik chce przeglądać bazę danych w czasie, może cofnąć się w czasie (jeśli w ogóle to oferuje)


Używam zwykłej tabeli MySQL do obsługi około 15 milionów działań.

Wygląda jak to:

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 mówi mi rodzaj aktywności, source_id mówi mi zapis, z którym aktywność jest związana. Jeśli więc typ aktywności oznacza "dodane ulubione", to Wiem, że source_id odnosi się do ID ulubionego rekordu.

The parent_id/parent_type są przydatne dla mojej aplikacji-mówią mi, z czym jest związana aktywność. Jeśli książka była faworyzowana,to parent_id / parent_type powiedziałby mi, że aktywność odnosi się do książki (typu) z podanym kluczem głównym (id)

I indeks na (user_id, time) i zapytanie o czynności, które są user_id IN (...friends...) AND time > some-cutoff-point. Porzucenie id i wybór innego indeksu klastrowego może być dobrym pomysłem - nie eksperymentowałem z tym.

Dość podstawowe rzeczy, ale to działa, to proste, i to jest łatwe do pracy, jak zmieniają się Twoje potrzeby. Ponadto, jeśli nie używasz MySQL może być w stanie zrobić lepiej indeks-wise.


Aby uzyskać szybszy dostęp do najnowszych aktywności, eksperymentowałem z Redis}. Redis przechowuje wszystkie swoje dane w pamięci, więc nie możesz umieścić tam wszystkich swoich działań, ale możesz przechowywać wystarczająco dużo dla większości ekranów, które często trafiają na Twoją witrynę. Ostatnie 100 dla każdego użytkownika lub coś w tym stylu. Z Redis w miksie może działać tak:

  • Utwórz rekord aktywności MySQL
  • dla każdego znajomego użytkownika, który utworzył aktywność, wprowadź identyfikator na listę aktywności w Redis.
  • przycinanie każdej listy do ostatnich x pozycji
Redis jest szybki i umożliwia przesyłanie poleceń potokowych w obrębie jednego połączenia , więc wysyłanie aktywności do 1000 znajomych zajmuje milisekundy.

Aby uzyskać bardziej szczegółowe wyjaśnienie tego, o czym mówię, zobacz przykład Redis na Twitterze: http://redis.io/topics/twitter-clone

Aktualizacja luty 2011 mam 50 milionów aktywnych działań w tej chwili i nic nie zmieniłem. Jedną z miłych rzeczy w robieniu czegoś podobnego jest to, że używa kompaktowych, małych rzędów. Jestem planując wprowadzenie pewnych zmian, które obejmowałyby o wiele więcej działań i więcej zapytań tych działań, a ja na pewno będę używał Redis, aby utrzymać szybkość. Używam Redis w innych obszarach i naprawdę działa dobrze w przypadku niektórych problemów.

Aktualizacja lipiec 2014 jesteśmy do około 700K miesięcznie aktywnych użytkowników. Przez ostatnie kilka lat używałem Redis (zgodnie z opisem na liście punktowanej) do przechowywania ostatnich 1000 identyfikatorów aktywności dla każdego użytkownika. Zwykle są około 100 milionów rekordów aktywności w systemie i są one nadal przechowywane w MySQL i są nadal ten sam układ. Te rekordy pozwalają nam uciec z mniejszą ilością pamięci Redis, służą jako zapis danych o aktywności i używamy ich, jeśli użytkownicy muszą cofnąć się w czasie, aby coś znaleźć.

[7]}to nie było sprytne lub szczególnie interesujące rozwiązanie, ale dobrze mi służyło.
 219
Author: casey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-10 18:36:01

To jest moja implementacja strumienia aktywności, przy użyciu mysql. Istnieją trzy klasy: Activity, ActivityFeed, Subscriber.

Aktywność reprezentuje wpis aktywności, a jego tabela wygląda następująco:

id
subject_id
object_id
type
verb
data
time

Subject_id id obiektu wykonującego akcję, object_id id obiektu, który otrzymuje akcję. type i verb opisuje samą akcję (na przykład, jeśli użytkownik doda komentarz do artykułu, będzie to odpowiednio "komentarz" i "utworzony"), dane zawiera dodatkowe dane w celu uniknięcia dołączania (na przykład może zawierać imię i nazwisko tematu, tytuł artykułu i adres url, Treść komentarza itp.).

Każda aktywność należy do jednej lub więcej aktywności, a są one powiązane tabelą, która wygląda tak:

feed_name
activity_id

W mojej aplikacji mam jeden kanał dla każdego użytkownika i jeden kanał dla każdego elementu (zwykle artykuły blogowe), ale mogą być, co chcesz.

Subskrybent jest zwykle użytkownikiem Twojej witryny, ale to może być również dowolnym obiektem w modelu obiektowym (na przykład artykuł może być subskrybowany do feed_action jego twórcy).

Każdy abonent należy do jednej lub kilku aktywności i, jak wyżej, są one powiązane tabelą linków tego typu:

feed_name
subscriber_id
reason

Pole reason wyjaśnia, dlaczego subskrybent subskrybował kanał. Na przykład, jeśli użytkownik tworzy zakładkę do posta na blogu, powodem jest "zakładka". Pomaga mi to później w filtrowaniu akcji powiadomień do użytkowników.

Aby odzyskać aktywność dla abonenta, wykonuję proste połączenie trzech tabel. Połączenie jest szybkie, ponieważ wybieram kilka aktywności dzięki warunkowi WHERE, który wygląda jak teraz - time > some hours. Unikam innych złączeń dzięki polu danych w tabeli aktywności.

Dalsze wyjaśnienie w polu reason. Jeśli, na przykład, chcę filtrować działania dla powiadomień e-mail do użytkownika, a użytkownik dodał zakładkę do posta na blogu (i tak subskrybuje kanał postu z powodu "zakładka"), nie chcę, aby użytkownik otrzymywał powiadomienia e-mail o działaniach na tym elemencie, a jeśli komentuje post (a więc subskrybuje kanał postu z powodu "komentarz") chcę, aby był powiadamiany, gdy inni użytkownicy dodają komentarze do tego samego postu. Pole reason pomaga mi w tej dyskryminacji (zaimplementowałem je za pomocą klasy ActivityFilter), wraz z preferencjami powiadomień użytkownika.

 21
Author: Nicolò Martini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-22 22:28:19

Istnieje aktualny format strumienia aktywności, który jest rozwijany przez grupę dobrze znanych osób.

Http://activitystrea.ms/.

Zasadniczo, każda czynność ma aktora (który wykonuje czynność), czasownik (działanie czynności), przedmiot (na którym aktor wykonuje) i cel.

Na przykład: Max opublikował link do ściany Adama.

Ich Specyfikacja JSON osiągnęła wersję 1.0 w momencie pisania, co pokazuje wzór dla aktywność, którą możesz zastosować.

Ich format został już przyjęty przez BBC, Gnip, Google Buzz Gowalla, IBM, Myspace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID i wiele innych.

 13
Author: sntran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-14 14:48:46

Myślę, że wyjaśnienie, jak działa system powiadomień na dużych stronach można znaleźć w pytaniu przepełnienie stosu Jak portale społecznościowe obliczają aktualizacje znajomych?, w odpowiedzi Jeremy Wall . Sugeruje użycie Message Qeue i wskazuje dwa programy open source, które go implementują:

  1. RabbitMQ
  2. Apache QPid

Zobacz także pytanie jaki jest najlepszy sposób realizowanie strumienia aktywności społecznej?

 11
Author: Nicolò Martini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:24

Absolutnie potrzebujesz performant & distributed Message queue. Ale to nie koniec, będziesz musiał podjąć decyzję o tym, co przechowywać jako dane trwałe, a co jako przejściowe itp.

W każdym razie, to naprawdę trudne zadanie mój przyjacielu, jeśli szukasz wysokiej wydajności i skalowalnego systemu. Ale oczywiście niektórzy wspaniałomyślni inżynierowie podzielili się swoimi doświadczeniami w tej sprawie. LinkedIn udostępnił ostatnio swój system kolejki komunikatów Kafka open source. Wcześniej Facebook już udostępnił Skryba do społeczności open source. Kafka jest napisana w Scali i na początku zajmuje trochę czasu, aby go uruchomić, ale testowałem z kilkoma serwerami wirtualnymi. Jest naprawdę szybki.

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

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

 1
Author: Cagatay Kalan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-05 00:47:22

Zamiast tworzyć własne, możesz skorzystać z usługi innej firmy używanej przez API. Zacząłem jeden o nazwie Collabinate ( http://www.collabinate.com ), który ma zaplecze bazy danych wykresów i dość wyrafinowane algorytmy do obsługi dużych ilości danych w wysoce równoczesny, wysokiej wydajności sposób. Chociaż nie ma tak szerokiej funkcjonalności, jak Facebook lub Twitter, to więcej niż wystarcza w większości przypadków użycia, w których musisz budować strumienie aktywności, social feeds, czyli funkcjonalność mikroblogowania w aplikacji.

 0
Author: Mafuba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-19 02:47:46