Bagaimana menerapkan aliran aktivitas di jejaring sosial


140

Saya sedang mengembangkan jaringan sosial saya sendiri, dan saya belum menemukan contoh web penerapan aliran tindakan pengguna ... Misalnya, bagaimana cara memfilter tindakan untuk setiap pengguna? Bagaimana cara menyimpan acara aksi? Model data dan model objek mana yang bisa saya gunakan untuk aliran tindakan dan untuk tindakan itu sendiri?


9
selamat mencoba, ini adalah pertanyaan yang tidak pernah berakhir yang kita semua ingin tahu, bagaimana facebook melakukannya, jawabannya sangat kompleks dan kita mungkin tidak pernah tahu cara paling efisien untuk melakukannya. Jika Anda menemukan pendekatan BAIK, silakan posting di sini untuk dilihat orang lain, BTW ini telah dibahas berkali-kali di SO jadi cari saja dan Anda akan menemukan beberapa tips
JasonDavis

1
Stream Framework adalah solusi yang paling banyak digunakan: github.com/tschellenbach/Stream-Framework Juga lihat daftar paket ini: djangopackages.com/grids/g/activities
Thierry

1
Dalam hal personalisasi, ini didasarkan pada analitik dan pembelajaran mesin, Juga lihat getstream.io/personalization
Thierry

Jawaban:


241

Ringkasan : Untuk sekitar 1 juta pengguna aktif dan 150 juta aktivitas tersimpan, saya tetap sederhana:

  • Gunakan basis data relasional untuk penyimpanan kegiatan unik (1 catatan per aktivitas / "hal yang terjadi") Buat catatan sekompleks yang Anda bisa. Struktur sehingga Anda dapat dengan cepat mengambil kumpulan kegiatan berdasarkan ID aktivitas atau dengan menggunakan satu set ID teman dengan batasan waktu.
  • Publikasikan ID aktivitas ke Redis setiap kali catatan aktivitas dibuat, tambahkan ID ke daftar "aliran aktivitas" untuk setiap pengguna yang merupakan teman / pelanggan yang harus melihat aktivitas.

Query Redis untuk mendapatkan aliran aktivitas untuk setiap pengguna dan kemudian mengambil data terkait dari db sesuai kebutuhan. Kembali ke menanyakan db berdasarkan waktu jika pengguna perlu menelusuri jauh ke belakang (jika Anda bahkan menawarkan ini)


Saya menggunakan tabel MySQL lama yang biasa untuk menangani sekitar 15 juta kegiatan.

Itu terlihat seperti ini:

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_typememberi tahu saya jenis kegiatan, source_idmemberi tahu saya catatan yang terkait dengan kegiatan tersebut. Jadi jika jenis aktivitas berarti "tambah favorit" maka saya tahu bahwa source_id merujuk ke ID dari catatan favorit.

The parent_id/ parent_typeberguna untuk aplikasi saya - mereka memberitahu saya apa aktivitas tersebut terkait dengan. Jika sebuah buku difavoritkan, maka parent_id / parent_type akan memberi tahu saya bahwa aktivitas tersebut berkaitan dengan buku (jenis) dengan kunci primer yang diberikan (id)

Saya mengindeks (user_id, time)dan menanyakan aktivitas yang ada user_id IN (...friends...) AND time > some-cutoff-point. Mengesampingkan id dan memilih indeks berkerumun yang berbeda mungkin merupakan ide yang baik - saya belum bereksperimen dengan itu.

Hal-hal yang cukup mendasar, tetapi bekerja, itu sederhana, dan mudah untuk bekerja seiring dengan perubahan kebutuhan Anda. Juga, jika Anda tidak menggunakan MySQL, Anda mungkin bisa melakukan lebih baik dalam hal indeks.


Untuk akses yang lebih cepat ke aktivitas terbaru, saya telah bereksperimen dengan Redis . Redis menyimpan semua data di dalam memori, sehingga Anda tidak dapat memasukkan semua aktivitas Anda di sana, tetapi Anda dapat menyimpan cukup banyak untuk sebagian besar layar yang paling populer di situs Anda. 100 terbaru untuk setiap pengguna atau sesuatu seperti itu. Dengan Redis dalam campuran, ini mungkin bekerja seperti ini:

  • Buat catatan aktivitas MySQL Anda
  • Untuk setiap teman pengguna yang membuat aktivitas, dorong ID ke daftar aktivitas mereka di Redis.
  • Pangkas setiap daftar ke item X terakhir

Redis cepat dan menawarkan cara untuk menyalurkan perintah di satu koneksi - jadi mendorong aktivitas ke 1000 teman membutuhkan milidetik.

Untuk penjelasan lebih rinci tentang apa yang saya bicarakan, lihat contoh Twitter Redis: http://redis.io/topics/twitter-clone

Perbarui Februari 2011 Saya punya 50 juta aktivitas aktif saat ini dan saya belum mengubah apa pun. Satu hal yang menyenangkan tentang melakukan sesuatu yang mirip dengan ini adalah menggunakan baris kecil yang ringkas. Saya berencana membuat beberapa perubahan yang akan melibatkan lebih banyak aktivitas dan lebih banyak pertanyaan dari aktivitas itu dan saya pasti akan menggunakan Redis untuk menjaga hal-hal cepat. Saya menggunakan Redis di area lain dan itu benar-benar berfungsi dengan baik untuk beberapa jenis masalah.

Perbarui Juli 2014 Kami hingga sekitar 700 ribu pengguna aktif bulanan. Selama beberapa tahun terakhir, saya telah menggunakan Redis (seperti yang dijelaskan dalam daftar berpoin) untuk menyimpan 1000 ID aktivitas terakhir untuk setiap pengguna. Biasanya ada sekitar 100 juta catatan aktivitas dalam sistem dan mereka masih disimpan di MySQL dan tata letak masih sama. Catatan-catatan ini memungkinkan kami untuk pergi dengan memori Redis yang lebih sedikit, mereka berfungsi sebagai catatan data aktivitas, dan kami menggunakannya jika pengguna perlu halaman lebih jauh ke belakang pada waktunya untuk menemukan sesuatu.

Ini bukan solusi cerdas atau sangat menarik tetapi telah membantu saya dengan baik.


2
+1 untuk Redis. v2 menggunakan memori virtual sehingga dimungkinkan untuk sepenuhnya mengandalkan Redis
stagas

16
Jika ada beberapa sumber aktivitas (tambahkan, komentar, suka, dll.), Bagaimana Anda bergabung dengan tabel ini dengan aktivitas aktual? Apakah Anda menggunakan beberapa gabungan kiri (masing-masing untuk tabel aktivitas)?
Ali Shakiba

1
@casey Echoing @JohnS 'pertanyaan - bagaimana Anda melakukan JOINdi berbagai activity_typetabel? Apakah mereka bergabung dengan kinerja yang bijaksana?
Rob Sobers

1
Adakah yang mendapat jawaban atas pertanyaan JohnS tentang "GABUNG". Adakah yang bisa memposting tautan yang menjelaskannya? Saya harus melakukan hal serupa dan itu akan sangat membantu saya.
Waseem

3
Tidak ada yang bergabung. Satu permintaan per unik activity_typeuntuk mendapatkan data lain yang Anda butuhkan.
outcassed

21

Ini adalah implementasi saya dari aliran aktivitas, menggunakan mysql. Ada tiga kelas: Activity, ActivityFeed, Subscriber.

Aktivitas mewakili entri aktivitas, dan tabelnya terlihat seperti ini:

id
subject_id
object_id
type
verb
data
time

Subject_idadalah id dari objek yang melakukan aksi, object_idid dari objek yang menerima tindakan. typedan verbmenjelaskan tindakan itu sendiri (misalnya, jika pengguna menambahkan komentar ke artikel mereka akan "komentar" dan "dibuat" masing-masing), data berisi data tambahan untuk menghindari bergabung (misalnya, itu dapat berisi nama subjek dan nama keluarga, judul dan url artikel, badan komentar, dll.).

Setiap Kegiatan milik satu atau lebih ActivityFeeds, dan mereka terkait oleh tabel yang terlihat seperti ini:

feed_name
activity_id

Dalam aplikasi saya, saya punya satu umpan untuk setiap Pengguna dan satu umpan untuk setiap Item (biasanya artikel blog), tetapi mereka bisa apa saja yang Anda inginkan.

Pelanggan biasanya adalah pengguna situs Anda, tetapi ia juga bisa berupa objek apa pun dalam model objek Anda (misalnya artikel dapat berlangganan feed_action dari penciptanya).

Setiap Pelanggan milik satu atau lebih ActivityFeeds, dan, seperti di atas, mereka terkait dengan tabel tautan semacam ini:

feed_name
subscriber_id
reason

The reasonbidang sini menjelaskan mengapa pelanggan telah berlangganan feed. Misalnya, jika pengguna menandai posting blog, alasannya adalah 'bookmark'. Ini membantu saya nanti dalam memfilter tindakan untuk pemberitahuan kepada pengguna.

Untuk mengambil aktivitas untuk pelanggan, saya melakukan gabungan sederhana dari tiga tabel. Bergabung dengan cepat karena saya memilih beberapa kegiatan berkat WHEREkondisi yang tampak seperti sekarang - time > some hours. Saya menghindari gabungan lain berkat bidang data di tabel Aktivitas.

Penjelasan lebih lanjut di reasonlapangan. Jika, misalnya, saya ingin memfilter tindakan untuk pemberitahuan email kepada pengguna, dan pengguna membookmark posting blog (dan dia berlangganan feed postingan dengan alasan 'bookmark'), saya tidak ingin pengguna menerima email pemberitahuan tentang tindakan pada item itu, sementara jika dia berkomentar posting (dan jadi berlangganan feed posting dengan alasan 'komentar') Saya ingin dia diberitahu ketika pengguna lain menambahkan komentar ke posting yang sama. Bidang alasan membantu saya dalam diskriminasi ini (saya menerapkannya melalui kelas ActivityFilter), bersama dengan preferensi pemberitahuan pengguna.


Nicolo martini saya ingin menambahkan balasan komentar pada aktivitas dan menunjukkannya di bawahnya, bagaimana mungkin dengan struktur Anda? haruskah saya menambahkan tabel lain atau hanya menggunakan yang sama, jika sama, lalu apa saran Anda?
Basit

Bagaimana kinerja implementasi ini? Adakah tes di meja besar?
Joshua F. Rountree

16

Ada format saat ini untuk aliran aktivitas yang sedang dikembangkan oleh sekelompok orang yang terkenal.

http://activitystrea.ms/ .

Pada dasarnya, setiap aktivitas memiliki aktor (yang melakukan aktivitas), kata kerja (aksi aktivitas), objek (di mana aktor melakukan), dan target.

Sebagai contoh: Max telah memposting tautan ke dinding Adam.

Spec JSON mereka telah mencapai versi 1.0 pada saat penulisan, yang menunjukkan pola aktivitas yang dapat Anda terapkan.

Format mereka telah diadopsi oleh BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Siaran Sosial, Superfeedr, TypePad, Windows Live, YIID, dan banyak lainnya.


hi @sntran Saya tahu posting ini bertahun-tahun yang lalu, tapi saya punya pertanyaan lebih lanjut tentang aliran aktivitas. Apakah ada cara yang bisa Anda bantu?
hiswendy

Tentu. Apa pertanyaan Anda?
Sơn Trần-Nguyễn

Pertanyaan saya sebenarnya diposting di sini! tautan . Saya pikir saya memiliki pemahaman dasar tentang aliran aktivitas, tapi saya benar-benar tidak begitu yakin bagaimana cara mengimplementasikannya (yaitu apakah saya seharusnya menggunakan angular atau node.js?) Dan dari sana, bagaimana saya benar-benar MENCIPTAKAN aliran aktivitas dengan API JSON yang masuk? Ini adalah pertanyaan mendasar seperti itu, tetapi saya tidak dapat menemukan jawaban online. Jika Anda dapat membantu, saya akan sangat menghargainya. Terima kasih!
hiswendy


1

Anda benar-benar membutuhkan antrian performan & pesan yang didistribusikan. Tapi itu tidak berakhir di sana, Anda harus membuat keputusan tentang apa yang akan disimpan sebagai data yang persisten dan apa yang sementara dan sebagainya.

Bagaimanapun, itu benar-benar tugas yang sulit sobat jika Anda mengejar kinerja tinggi dan sistem yang dapat diskalakan. Tapi, tentu saja beberapa insinyur yang murah hati telah berbagi pengalaman mereka dalam hal ini. LinkedIn belakangan membuat sistem antrian pesannya Kafka open source. Sebelum itu, Facebook sudah menyediakan Scribe ke komunitas open source. Kafka ditulis dalam Scala dan pada awalnya butuh beberapa waktu untuk membuatnya berjalan tetapi saya diuji dengan beberapa server virtual. Ini sangat cepat.

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

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


0

Alih-alih menggulirkan milik Anda sendiri, Anda dapat melihat ke layanan pihak ketiga yang digunakan melalui API. Saya memulai satu yang disebut Collabinate ( http://www.collabinate.com ) yang memiliki backend basis data grafik dan beberapa algoritma yang cukup canggih untuk menangani sejumlah besar data dengan cara yang sangat bersamaan dan berkinerja tinggi. Meskipun tidak memiliki keluasan fungsionalitas yang dikatakan Facebook atau Twitter, itu lebih dari cukup untuk sebagian besar kasus penggunaan di mana Anda perlu membangun aliran aktivitas, umpan sosial, atau fungsionalitas microblogging ke dalam suatu aplikasi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.