Rozwijam własną sieć społecznościową i nie znalazłem w sieci przykładów realizacji strumienia działań użytkowników ... Na przykład, jak filtrować akcje dla każdego użytkownika? Jak przechowywać wydarzenia akcji? Którego modelu danych i modelu obiektowego mogę używać dla strumienia akcji i dla samych akcji?
design-patterns
architecture
stream
social-networking
Nicolò Martini
źródło
źródło
Odpowiedzi:
Podsumowanie : Dla około 1 miliona aktywnych użytkowników i 150 milionów zapisanych działań, utrzymuję to w prostocie:
Zapytaj Redis, aby uzyskać strumień aktywności dla dowolnego użytkownika, a następnie w razie potrzeby pobierz powiązane dane z bazy danych. Wróć do odpytywania bazy danych według czasu, jeśli użytkownik musi przeglądać daleko w czasie (jeśli w ogóle to oferujesz)
Używam zwykłej starej tabeli MySQL do obsługi około 15 milionów działań.
Wygląda mniej więcej tak:
activity_type
informuje mnie o rodzaju czynności,source_id
informuje o zapisie, z którym jest ona związana. Więc jeśli typ działania oznacza „dodane ulubione”, to wiem, że source_id odnosi się do identyfikatora ulubionego rekordu.parent_id
/parent_type
Są użyteczne dla mojej aplikacji - mówią mi, jaka działalność jest związana. Gdyby książka została dodana do ulubionych, wtedy parent_id / parent_type powiedziałby mi, że działanie dotyczy książki (typu) z podanym kluczem podstawowym (id)Indeksuję
(user_id, time)
i wyszukuję działania, które sąuser_id IN (...friends...) AND time > some-cutoff-point
. Porzucenie identyfikatora i wybranie innego indeksu klastrowego może być dobrym pomysłem - nie eksperymentowałem z tym.Całkiem podstawowe rzeczy, ale działają, są proste i łatwo się z nimi pracuje, gdy zmieniają się Twoje potrzeby. Ponadto, jeśli nie używasz MySQL, możesz być w stanie zrobić to lepiej pod względem indeksowania.
Aby uzyskać szybszy dostęp do najnowszych działań, 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ć ich wystarczająco dużo dla większości najczęściej odwiedzanych ekranów w Twojej witrynie. Najnowsze 100 dla każdego użytkownika lub coś w tym rodzaju. Z Redisem w miksie może to wyglądać tak:
Usługa Redis jest szybka i oferuje sposób przesyłania poleceń w ramach jednego połączenia - więc przekazanie aktywności 1000 znajomym zajmuje milisekundy.
Bardziej szczegółowe wyjaśnienie tego, o czym mówię, można znaleźć w przykładzie Redis na Twitterze: http://redis.io/topics/twitter-clone
Aktualizacja luty 2011 Mam w tej chwili 50 milionów aktywnych działań i niczego nie zmieniłem. Jedną fajną rzeczą w robieniu czegoś podobnego jest to, że używa kompaktowych, małych rzędów. Planuję wprowadzić pewne zmiany, które obejmowałyby znacznie więcej działań i więcej zapytań związanych z tymi działaniami, i na pewno będę używać Redis, aby przyspieszyć działanie. Używam Redis w innych obszarach i naprawdę dobrze działa w przypadku niektórych problemów.
Aktualizacja, lipiec 2014 r. Mamy około 700 tys. Aktywnych użytkowników miesięcznie. Od kilku lat używam Redis (zgodnie z opisem na liście punktowanej) do przechowywania ostatnich 1000 identyfikatorów aktywności dla każdego użytkownika. W systemie jest zwykle około 100 milionów rekordów aktywności i nadal są one przechowywane w MySQL i nadal mają 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źć.
Nie było to sprytne ani szczególnie interesujące rozwiązanie, ale dobrze mi służyło.
źródło
JOIN
na różnychactivity_type
stołach? Czy te połączenia są drogie pod względem wydajności?activity_type
aby uzyskać inne potrzebne dane.To jest moja implementacja strumienia aktywności przy użyciu mysql. Istnieją trzy klasy: Activity, ActivityFeed, Subscriber.
Aktywność reprezentuje wpis aktywności, a jej tabela wygląda następująco:
Subject_id
to identyfikator obiektu wykonującego akcję,object_id
identyfikator obiektu, który otrzymuje akcję.type
iverb
opisuje samą akcję (na przykład, jeśli użytkownik doda komentarz do artykułu, będzie to odpowiednio „komentarz” i „utworzony”), dane zawierają dodatkowe dane w celu uniknięcia łączenia (na przykład mogą zawierać nazwę tematu i nazwisko, tytuł i adres artykułu, treść komentarza itp.).Każde działanie należy do co najmniej jednego źródła działań i są one powiązane tabelą, która wygląda następująco:
W mojej aplikacji mam jeden kanał dla każdego użytkownika i jeden kanał dla każdego elementu (zwykle artykuły na blogu), ale mogą to być, co chcesz.
Subskrybent jest zwykle użytkownikiem Twojej witryny, ale może to być również dowolny obiekt w Twoim modelu obiektowym (na przykład artykuł może być zasubskrybowany w treści źródła treści jego twórcy).
Każdy subskrybent należy do co najmniej jednego źródła ActivityFeed i, podobnie jak powyżej, są one powiązane tabelą linków tego rodzaju:
reason
Pole tutaj wyjaśnia dlaczego abonent subskrypcji kanału. Na przykład, jeśli użytkownik doda zakładkę do posta na blogu, powodem jest „zakładka”. Pomaga mi to później w filtrowaniu działań pod kątem powiadomień dla użytkowników.Aby pobrać aktywność dla subskrybenta, wykonuję proste połączenie trzech tabel. Łączenie jest szybkie, ponieważ wybieram kilka działań dzięki
WHERE
warunkowi, który wygląda jak teraz -time > some hours
. Unikam innych łączeń dzięki polu danych w Tabeli aktywności.Dalsze wyjaśnienia w
reason
terenie. Jeśli na przykład chcę filtrować akcje dla powiadomień e-mail do użytkownika, a użytkownik dodał zakładkę do posta na blogu (i subskrybuje kanał postów z powodem `` zakładka ''), nie chcę, aby użytkownik otrzymał powiadomienia e-mail o działaniach dotyczących tego elementu, a jeśli komentuje post (a więc subskrybuje kanał wiadomości z uzasadnieniem „komentarz”), chcę, aby był powiadamiany, gdy inni użytkownicy dodają komentarze do tego samego postu. Pole powodu pomaga mi w tej dyskryminacji (zaimplementowałem to poprzez klasę ActivityFilter), wraz z preferencjami powiadomień użytkownika.źródło
Istnieje obecny format strumienia aktywności, który jest opracowywany przez grupę dobrze znanych osób.
http://activitystrea.ms/ .
Zasadniczo, każda czynność ma aktora (który wykonuje czynność), czasownik (czynność 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 tego tekstu, która pokazuje wzorzec aktywności, 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.
źródło
Myślę, że wyjaśnienie, jak działa system powiadomień na dużych stronach internetowych, można znaleźć w pytaniu o przepełnienie stosu, w jaki sposób serwisy społecznościowe obliczają aktualizacje znajomych? , w odpowiedzi Jeremy Wall . Sugeruje użycie Message Qeue i wskazuje dwa programy open source, które ją implementują:
Zobacz też pytanie Jaki jest najlepszy sposób realizacji strumienia aktywności społecznej?
źródło
Absolutnie potrzebujesz wydajnej i rozproszonej kolejki wiadomości. Ale to nie koniec, będziesz musiał podjąć decyzje, co przechowywać jako dane trwałe, a co przejściowe itp.
Zresztą to naprawdę trudne zadanie, przyjacielu, jeśli szukasz wydajnego i skalowalnego systemu. Ale oczywiście niektórzy hojni inżynierowie podzielili się swoimi doświadczeniami w tej sprawie. LinkedIn ostatnio udostępnił swój system kolejki wiadomości Kafka open source. Wcześniej Facebook udostępnił Scribe społeczności open source. Kafka jest napisana w Scali i na początku jej uruchomienie zajmuje trochę czasu, ale testowałem z kilkoma serwerami wirtualnymi. To jest naprawdę szybkie.
http://blog.linkedin.com/2011/01/11/open-source-linkedin-kafka/
http://incubator.apache.org/kafka/index.html
źródło
Zamiast tworzyć własną, możesz poszukać usługi strony trzeciej używanej za pośrednictwem interfejsu API. Założyłem jeden o nazwie Collabinate ( http://www.collabinate.com ), który ma zaplecze graficznej bazy danych i kilka dość wyrafinowanych algorytmów do obsługi dużych ilości danych w sposób bardzo współbieżny i wydajny. Chociaż nie ma tak szerokiego zakresu funkcji, jak Facebook lub Twitter, jest więcej niż wystarczający w większości przypadków użycia, w których musisz wbudować strumienie aktywności, kanały społecznościowe lub funkcję mikroblogowania w aplikacji.
źródło