Etkinlik akışını bir sosyal ağda uygulama


140

Kendi sosyal ağımı geliştiriyorum ve web uygulamalarında kullanıcı eylemlerinin akışını bulamadım ... Örneğin, her kullanıcı için eylemleri nasıl filtreleyebilirim? Aksiyon olayları nasıl saklanır? İşlem akışı ve eylemler için hangi veri modelini ve nesne modelini kullanabilirim?


9
iyi şanslar, bu hepimizin bilmek istediği hiç bitmeyen bir soru, facebook bunu nasıl çekiyor, cevap çok karmaşık ve bunu yapmanın en etkili yolunu asla bilemeyebiliriz. İYİ bir yaklaşım bulursanız, lütfen başkalarının görmesi için buraya gönderin, BTW bu SO üzerinde birçok kez tartışıldı, bu yüzden sadece arama yapın ve bazı ipuçları bulacaksınız
JasonDavis

1
Stream Framework en yaygın kullanılan çözümdür: github.com/tschellenbach/Stream-Framework Ayrıca bu paket listesine de bakın: djangopackages.com/grids/g/activities
Thierry

1
Kişiselleştirme açısından analitik ve makine öğrenimine dayanmaktadır, ayrıca bkz. Getstream.io/personalization
Thierry

Yanıtlar:


241

Özet : Yaklaşık 1 milyon aktif kullanıcı ve 150 milyon depolanmış etkinlik için bunu basit tutuyorum:

  • Benzersiz etkinliklerin depolanması için ilişkisel bir veritabanı kullanın (etkinlik başına 1 kayıt / "olan") Kayıtları olabildiğince kompakt hale getirin. Etkinlik kimliğini veya zaman kısıtlamaları olan bir dizi arkadaş kimliğini kullanarak bir dizi etkinliği hızlı bir şekilde alabileceğiniz yapı.
  • Her etkinlik kaydı oluşturulduğunda etkinlik kimliklerini Redis'te yayınlayın, kimliği etkinliği görmesi gereken bir arkadaş / abone olan her kullanıcı için bir "etkinlik akışı" listesine ekleyin.

Sorgu Redis herhangi bir kullanıcı için etkinlik akışı almak ve daha sonra gerektiği gibi db ilgili verileri almak için. Kullanıcının zamanda geriye doğru göz atması gerekiyorsa db'yi sorgulamaya geri dönün (bunu bile teklif ederseniz)


Yaklaşık 15 milyon faaliyetle uğraşmak için eski bir MySQL tablosu kullanıyorum.

Şuna benziyor:

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_typebana etkinlik türünü source_idsöyler, etkinlikle ilgili kaydı söyler. Etkinlik türü "eklenen favori" anlamına gelirse, o zaman source_id bir favori kaydın kimliğini ifade biliyorum.

parent_id/ parent_typeUygulamam için yararlıdır - onlar aktivite ile ilgilidir söyle. Bir kitap favorilere eklendiyse parent_id / parent_type, etkinliğin belirli bir birincil anahtarla (id) bir kitap (tür) ile ilgili olduğunu söylerdi

Ben endeks (user_id, time)ve olan faaliyetler için sorgu user_id IN (...friends...) AND time > some-cutoff-point. Kimliği atmak ve farklı bir kümelenmiş dizin seçmek iyi bir fikir olabilir - bunu denemedim.

Oldukça basit şeyler, ama işe yarıyor, basit ve ihtiyaçlarınız değiştikçe çalışmak kolaydır. Ayrıca, MySQL kullanmıyorsanız, daha iyi dizin bazında yapabilirsiniz.


En son etkinliklere daha hızlı erişim için Redis ile denemeler yapıyorum . Redis, tüm verilerini bellekte saklar, böylece tüm etkinliklerinizi oraya koyamazsınız, ancak sitenizdeki yaygın olarak kullanılan ekranların çoğu için yeterince depolayabilirsiniz. Her kullanıcı için en yeni 100 veya bunun gibi bir şey. Karışımdaki Redis ile şu şekilde çalışabilir:

  • MySQL etkinlik kaydınızı oluşturun
  • Etkinliği oluşturan kullanıcının her arkadaşı için, kimliği Redis'teki etkinlik listesine itin.
  • Her listeyi son X öğeye kırp

Redis hızlıdır ve komutları tek bir bağlantıda boru hattı oluşturmak için bir yol sunar - bu nedenle bir etkinliği 1000 arkadaşa göndermek milisaniye sürer.

Neden bahsettiğimin daha ayrıntılı bir açıklaması için Redis'in Twitter örneğine bakın: http://redis.io/topics/twitter-clone

Şubat 2011 Güncellemesi Şu anda 50 milyon aktif etkinliğim var ve hiçbir şey değiştirmedim. Buna benzer bir şey yapmakla ilgili güzel bir şey, kompakt, küçük sıralar kullanmasıdır. Daha fazla etkinlik ve bu etkinliklerin daha fazla sorgusunu içerecek bazı değişiklikler yapmayı planlıyorum ve Redis'i işleri hızlı tutmak için kesinlikle kullanacağım. Redis'i diğer alanlarda kullanıyorum ve bazı problemler için gerçekten iyi çalışıyor.

Temmuz 2014 Güncellemesi Aylık yaklaşık 700 bin aktif kullanıcıya sahibiz. Son birkaç yıldır, her kullanıcı için son 1000 etkinlik kimliğini saklamak için Redis'i (madde işaretli listede açıklandığı gibi) kullanıyorum. Sistemde genellikle yaklaşık 100 milyon aktivite kaydı vardır ve bunlar hala MySQL'de saklanır ve hala aynı düzendedir. Bu kayıtlar, daha az Redis belleği ile kaçmamıza izin veriyor, etkinlik verilerinin kaydı olarak hizmet veriyor ve kullanıcıların bir şeyler bulmak için zamanda daha fazla sayfa geriye gitmeleri gerekiyorsa bunları kullanıyoruz.

Bu akıllıca veya özellikle ilginç bir çözüm değildi ama bana iyi hizmet etti.


2
Redis için +1. v2 sanal belleği kullanıyor, bu yüzden tamamen
Redis'e

16
Birden fazla etkinlik kaynağı (ekleme, yorum yapma, beğenme vb.) Varsa, bu tabloya gerçek etkinliklerle nasıl katılırsınız? Birden fazla sol birleştirme kullanıyor musunuz (her biri bir etkinlik tablosu için)?
Ali Shakiba

1
@casey Echoing @JohnS'in sorusu - JOINçeşitli activity_typetablolarda nasıl performans sergiliyorsunuz ? Bu katılımlar performans açısından pahalı mı?
Rob Sobers

1
Herkes "JOIN" hakkında JohnS sorusuna cevap var mı. Herkes açıklanabileceği bir bağlantı gönderebilir mi? Benzer bir şey yapmak zorundayım ve bu bana çok yardımcı olacak.
Waseem

3
Katılma yok. activity_typeİhtiyacınız olan diğer verileri almak için benzersiz başına bir sorgu .
2015'te

21

Bu benim mysql kullanarak bir aktivite akışı benim uygulamasıdır. Üç sınıf vardır: Etkinlik, Etkinlik Beslemesi, Abone.

Etkinlik bir etkinlik girişini temsil eder ve tablosu şöyle görünür:

id
subject_id
object_id
type
verb
data
time

Subject_ideylemi gerçekleştiren nesnenin kimliği, eylemi object_idalan nesnenin kimliği. typeve verbeylemin kendisini açıklar (örneğin, bir kullanıcı bir makaleye sırasıyla "yorum" ve "oluşturulmuş" olur yorum eklerse) veriler, birleştirmelerden kaçınmak için ek veriler içerir (örneğin, konu adını içerebilir) ve soyadı, makale başlığı ve url, yorum gövdesi vb.).

Her Etkinlik bir veya daha fazla ActivityFeed'e aittir ve bunlar şuna benzer bir tabloyla ilişkilidir:

feed_name
activity_id

Uygulamamda her Kullanıcı için bir yayın ve her bir Öğe için bir yayın var (genellikle blog makaleleri), ancak istediğiniz her şey olabilirler.

Bir Abone genellikle sitenizin bir kullanıcısıdır, ancak nesne modelinizdeki herhangi bir nesne de olabilir (örneğin, bir makale oluşturucusunun feed_action'ına abone olabilir).

Her Abone bir veya daha fazla ActivityFeed'e aittir ve yukarıdaki gibi bu tür bir bağlantı tablosu ile ilişkilidir:

feed_name
subscriber_id
reason

Bu reasonalan, abonenin neden feed'e abone olduğunu açıklıyor. Örneğin, bir kullanıcı bir blog yayınına yer işareti koyarsa, bunun nedeni 'yer işareti'dir. Bu, daha sonra kullanıcılara bildirimler için eylemleri filtrelemede bana yardımcı olur.

Bir abonenin etkinliğini almak için üç tablodan basit bir birleşim yapıyorum. Üyelik hızlı çünkü WHEREşu anki gibi görünen bir durum sayesinde birkaç etkinlik seçiyorum - time > some hours. Etkinlik tablosundaki veri alanı sayesinde diğer birleştirmelerden kaçınırım.

reasonAlanla ilgili daha fazla açıklama . Örneğin, kullanıcıya e-posta bildirimleri için eylemleri filtrelemek istiyor ve kullanıcı bir blog yayınına yer işareti koyuyorsa (ve böylece 'yer işareti' nedeni ile yayın beslemesine abone olursa), kullanıcının almasını istemiyorum Bu öğedeki eylemlerle ilgili e-posta bildirimleri gönderirken, gönderiyi yorumlarsa (ve böylece 'feed' gerekçesiyle gönderi beslemesine abone olursa) Diğer kullanıcılar aynı gönderiye yorum eklediğinde kendisine bildirilmesini istiyorum. Neden alanı, kullanıcının bildirim tercihleri ​​ile birlikte bu ayrımcılık (bir ActivityFilter sınıfı aracılığıyla uyguladım) bana yardımcı olur.


Nicolo martini, aktiviteye cevap yorumu eklemek ve altında göstermek istedim, yapınızla nasıl mümkün olabilir? başka bir tablo eklemeli miyim yoksa sadece aynısını kullanmalı mıyım, o zaman önerileriniz nelerdir?
Basit

Bu uygulamanın performansı nasıldır? Büyük masalarda test var mı?
Joshua F. Rountree

16

Etkinlik akışı için iyi bilinen bir grup insan tarafından geliştirilen güncel bir format vardır.

http://activitystrea.ms/ .

Temel olarak, her etkinliğin bir aktör (etkinliği gerçekleştiren), bir fiil (etkinliğin eylemi), bir nesnenin (aktörün üzerinde çalıştığı) ve bir hedefi vardır.

Örneğin: Max, Adem'in duvarına bir bağlantı gönderdi.

Onların JSON's Spec yazma sırasında 1.0 sürümü ulaştı, hangi uygulayabilirsiniz etkinlik için kalıp gösterir.

Biçimleri BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID ve diğerleri tarafından zaten benimsenmiştir.


hi @sntran Bu yazının yıllar önce olduğunu biliyorum, ancak etkinlik akışı hakkında daha fazla sorum var. Yardım etmenin bir yolu var mı?
hiswendy

Elbette. Sorun nedir?
Sơn Trần-Nguyễn

Sorum aslında buraya gönderildi! bağlantısını tıklayın . Aktivite akışı hakkında temel bir anlayışa sahip olduğumu düşünüyorum, ancak nasıl uygulanacağından gerçekten emin değilim (yani açısal veya node.js kullanmam gerekiyor mu?) Ve oradan, aslında nasıl bir aktivite akışı oluşturabilirim gelen API JSON? Bunlar böyle temel sorular, ama çevrimiçi cevap bulamadım. Eğer yardım edebilirsen, gerçekten takdir ediyorum. Teşekkür ederim!
hiswendy


1

Kesinlikle bir performans ve dağıtılmış mesaj kuyruğuna ihtiyacınız vardır. Ancak burada bitmiyor, kalıcı veri olarak neyin depolanacağı ve nelerin geçici ve benzeri olarak karar vermesi gerekecek.

Her neyse, yüksek performanslı ve ölçeklenebilir bir sistemin peşindeyseniz arkadaşım gerçekten zor bir iş. Ancak, elbette bazı cömert mühendisler bu konudaki deneyimlerini paylaştılar. LinkedIn son zamanlarda mesaj kuyruğu sistemi Kafka'yı açık kaynak yaptı. Bundan önce, Facebook zaten açık kaynak topluluğuna Scribe sağlamıştı. Kafka Scala'da yazılmıştır ve ilk başta çalıştırılması biraz zaman alır, ancak birkaç sanal sunucuyla test ettim. Gerçekten hızlı.

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

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


0

Kendinizinkini değiştirmek yerine, API aracılığıyla kullanılan bir üçüncü taraf hizmetine bakabilirsiniz. Bir grafik veritabanı arka ucuna ve büyük miktarda veriyi son derece eşzamanlı, yüksek performanslı bir şekilde işlemek için oldukça karmaşık algoritmalara sahip Collabinate ( http://www.collabinate.com ) adlı bir tane başlattım . Facebook veya Twitter'ın söylediği işlevsellik genişliğine sahip olmasa da, bir uygulamada etkinlik akışları, sosyal beslemeler veya mikroblog işlevselliği oluşturmanız gereken çoğu kullanım durumu için yeterli değildir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.