วิธีการนำกระแสกิจกรรมไปใช้ในเครือข่ายโซเชียล


140

ฉันกำลังพัฒนาเครือข่ายโซเชียลของฉันเองและฉันไม่พบตัวอย่างของการใช้งานเว็บสตรีมของการกระทำของผู้ใช้ ... ตัวอย่างเช่นวิธีการกรองการกระทำสำหรับผู้ใช้แต่ละคน? วิธีการจัดเก็บกิจกรรมการกระทำ? โมเดลข้อมูลและโมเดลวัตถุใดที่ฉันสามารถใช้สำหรับสตรีมการดำเนินการและสำหรับแอคชั่นที่ใช้ได้


9
โชคดีนี่เป็นคำถามที่ไม่สิ้นสุดที่เราทุกคนต้องการทราบวิธีดึง Facebook ออกคำตอบนั้นซับซ้อนมากและเราอาจไม่เคยรู้วิธีที่มีประสิทธิภาพที่สุดในการทำเช่นนั้น หากคุณพบว่าวิธีการที่ดีกรุณาโพสต์ไว้ที่นี่สำหรับคนอื่น ๆ ไปยังมุมมอง, 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 บันทึกต่อกิจกรรม / "สิ่งที่เกิดขึ้น") สร้างระเบียนให้มีขนาดกะทัดรัดที่สุดเท่าที่จะทำได้ โครงสร้างเพื่อให้คุณสามารถคว้าชุดกิจกรรมได้อย่างรวดเร็วโดยใช้รหัสกิจกรรมหรือโดยใช้ชุดรหัสเพื่อนที่มีข้อ จำกัด ด้านเวลา
  • เผยแพร่ ID กิจกรรมไปยัง Redis เมื่อใดก็ตามที่มีการสร้างบันทึกกิจกรรมเพิ่ม ID ลงในรายการ "สตรีมกิจกรรม" สำหรับผู้ใช้ทุกคนที่เป็นเพื่อน / สมาชิกที่ควรเห็นกิจกรรม

Query 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 อ้างถึง ID ของบันทึกรายการโปรด

parent_id/ parent_typeมีประโยชน์สำหรับ app ของฉัน - พวกเขาบอกฉันว่ากิจกรรมที่เกี่ยวข้องกับ หากหนังสือเล่มนี้เป็นที่ชื่นชอบแล้ว parent_id / parent_type จะบอกฉันว่ากิจกรรมเกี่ยวข้องกับหนังสือ (ประเภท) ด้วยคีย์หลักที่กำหนด (id)

ดัชนีฉันบนและแบบสอบถามสำหรับกิจกรรมที่เป็น(user_id, time) user_id IN (...friends...) AND time > some-cutoff-pointการใช้ ID และการเลือกดัชนีกลุ่มอื่นอาจเป็นความคิดที่ดี - ฉันไม่ได้ทดลองสิ่งนั้น

แต่มันใช้งานได้ง่ายและใช้งานง่ายเมื่อความต้องการของคุณเปลี่ยนไป นอกจากนี้หากคุณไม่ได้ใช้ MySQL คุณอาจทำดัชนีได้ดีกว่า


สำหรับการเข้าถึงได้เร็วขึ้นเพื่อกิจกรรมล่าสุดที่ฉันได้รับการทดสอบด้วยRedis Redis เก็บข้อมูลทั้งหมดไว้ในหน่วยความจำดังนั้นคุณจึงไม่สามารถใส่กิจกรรมทั้งหมดไว้ในนั้นได้ แต่คุณสามารถจัดเก็บได้เพียงพอสำหรับหน้าจอที่ใช้กันทั่วไปส่วนใหญ่บนไซต์ของคุณ 100 รายการล่าสุดสำหรับผู้ใช้แต่ละรายหรือบางอย่างเช่นนั้น ด้วย Redis ในการผสมมันอาจทำงานเช่นนี้:

  • สร้างกิจกรรม MySQL ของคุณ
  • สำหรับเพื่อนแต่ละคนของผู้ใช้ที่สร้างกิจกรรมให้กด ID ลงในรายการกิจกรรมของพวกเขาใน Redis
  • ตัดแต่ละรายการเป็นรายการ X สุดท้าย

Redis นั้นเร็วและเสนอวิธีในการส่งคำสั่งไปยังการเชื่อมต่อเดียวดังนั้นการผลักกิจกรรมออกไปให้เพื่อน 1,000 คนใช้เวลามิลลิวินาที

สำหรับคำอธิบายโดยละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่ฉันกำลังพูดถึงดูตัวอย่าง Twitter ของ Redis: http://redis.io/topics/twitter-clone

อัปเดตกุมภาพันธ์ 2554ฉันมีกิจกรรมที่ใช้งานอยู่ 50 ล้านรายการในขณะนี้และฉันไม่ได้เปลี่ยนแปลงอะไรเลย สิ่งหนึ่งที่ดีเกี่ยวกับการทำสิ่งที่คล้ายกันคือมันใช้แถวกะทัดรัดและเล็ก ฉันกำลังวางแผนที่จะทำการเปลี่ยนแปลงบางอย่างที่จะเกี่ยวข้องกับกิจกรรมอื่น ๆ อีกมากมายและสอบถามเพิ่มเติมเกี่ยวกับกิจกรรมเหล่านั้นและฉันจะใช้ Redis เพื่อให้สิ่งต่าง ๆ รวดเร็ว ฉันใช้ Redis ในด้านอื่น ๆ และมันใช้ได้ดีกับปัญหาบางประเภท

อัปเดตกรกฎาคม 2014เรามีผู้ใช้งานรายเดือนประมาณ 700,000 ราย ในช่วงสองสามปีที่ผ่านมาฉันใช้ Redis (ดังอธิบายไว้ในรายการหัวข้อย่อย) สำหรับการจัดเก็บ 1,000 ID กิจกรรมล่าสุดสำหรับผู้ใช้แต่ละคน โดยปกติจะมีบันทึกกิจกรรมประมาณ 100 ล้านรายการในระบบและยังคงเก็บไว้ใน MySQL และยังคงเป็นเค้าโครงเดียวกัน บันทึกเหล่านี้ช่วยให้เราได้รับหน่วยความจำ Redis น้อยลงซึ่งทำหน้าที่เป็นบันทึกข้อมูลกิจกรรมและเราใช้ข้อมูลเหล่านั้นหากผู้ใช้ต้องการย้อนเวลากลับไปเพื่อค้นหาบางสิ่งเพิ่มเติม

นี่ไม่ใช่ทางออกที่ฉลาดหรือน่าสนใจโดยเฉพาะ แต่มันให้บริการฉันดี


2
+1 สำหรับ Redis v2 ใช้หน่วยความจำเสมือนดังนั้นจึงเป็นไปได้ที่จะพึ่งพา Redis ทั้งหมด
stagas

16
หากมีแหล่งกิจกรรมหลายแหล่ง (เพิ่มแสดงความคิดเห็นชอบ ฯลฯ ) คุณจะเข้าร่วมตารางนี้กับกิจกรรมจริงได้อย่างไร คุณใช้หลายซ้ายเข้าร่วม (แต่ละคนสำหรับตารางกิจกรรม)?
Ali Shakiba

1
@casey Echoing @JohnS 'คำถาม - คุณจะแสดงJOINบนactivity_typeตารางต่าง ๆ ได้อย่างไร? สิ่งเหล่านี้มาพร้อมกับประสิทธิภาพที่ชาญฉลาดหรือไม่
Rob Sobers

1
มีใครได้รับคำตอบคำถาม JohnS เกี่ยวกับ "เข้าร่วม" ทุกคนสามารถโพสต์ลิงก์ที่อาจอธิบายได้หรือไม่ ฉันต้องทำสิ่งที่คล้ายกันและมันจะเป็นประโยชน์กับฉันมาก
Waseem

3
ไม่มีการเข้าร่วม หนึ่งแบบสอบถามต่อหนึ่งที่ไม่ซ้ำกัน activity_typeเพื่อรับข้อมูลอื่น ๆ ที่คุณต้องการ
outcassed

21

นี่คือการใช้งานสตรีมกิจกรรมโดยใช้ mysql มีสามคลาส: กิจกรรม, ActivityFeed, สมาชิก

กิจกรรมแสดงถึงรายการกิจกรรมและตารางมีลักษณะดังนี้:

id
subject_id
object_id
type
verb
data
time

Subject_idคือ id ของวัตถุที่ดำเนินการแอ็คชันobject_idid ของวัตถุที่ได้รับการดำเนินการ typeและverbอธิบายการกระทำของตัวเอง (ตัวอย่างเช่นหากผู้ใช้เพิ่มความคิดเห็นในบทความพวกเขาจะเป็น "ความคิดเห็น" และ "สร้าง" ตามลำดับ) ข้อมูลมีข้อมูลเพิ่มเติมเพื่อหลีกเลี่ยงการเข้าร่วม (ตัวอย่างเช่นมันสามารถมีชื่อหัวเรื่อง และนามสกุลชื่อบทความและ URL เนื้อหาของความคิดเห็นเป็นต้น)

แต่ละกิจกรรมเป็นของฟีดกิจกรรมหนึ่งรายการขึ้นไปและเกี่ยวข้องกับตารางที่มีลักษณะดังนี้:

feed_name
activity_id

ในแอปพลิเคชันของฉันฉันมีฟีดหนึ่งรายการสำหรับผู้ใช้แต่ละรายและฟีดหนึ่งรายการสำหรับแต่ละรายการ (โดยปกติบทความในบล็อก) แต่พวกเขาสามารถเป็นอะไรก็ได้ที่คุณต้องการ

ผู้สมัครสมาชิกมักจะเป็นผู้ใช้เว็บไซต์ของคุณ แต่ก็สามารถเป็นวัตถุใด ๆ ในรูปแบบวัตถุของคุณ (ตัวอย่างเช่นบทความสามารถสมัครรับข้อมูล feed_action ของผู้สร้างของเขา)

สมาชิกทุกคนเป็นสมาชิกหนึ่งของ ActivityFeeds หนึ่งรายการขึ้นไปและเช่นเดียวกับด้านบนจะมีการเชื่อมโยงกับตารางลิงก์ประเภทนี้:

feed_name
subscriber_id
reason

reasonฟิลด์ที่นี่อธิบายว่าทำไมสมาชิกที่ได้สมัครเป็นสมาชิกฟีด ตัวอย่างเช่นหากผู้ใช้บุ๊กมาร์กโพสต์บล็อกเหตุผลคือ 'คั่นหน้า' สิ่งนี้ช่วยฉันในภายหลังในการกรองการกระทำสำหรับการแจ้งเตือนไปยังผู้ใช้

เพื่อดึงกิจกรรมสำหรับผู้สมัครสมาชิกฉันเข้าร่วมสามตารางง่ายๆ เข้าร่วมเป็นไปอย่างรวดเร็วเพราะผมเลือกกิจกรรมไม่กี่ขอบคุณWHEREสภาพที่ดูเหมือนว่าตอนนี้ time > some hours- ฉันหลีกเลี่ยงการรวมอื่น ๆ ขอบคุณเขตข้อมูลในตารางกิจกรรม

คำอธิบายเพิ่มเติมเกี่ยวกับreasonสนาม ตัวอย่างเช่นหากฉันต้องการกรองการดำเนินการสำหรับการแจ้งเตือนทางอีเมลไปยังผู้ใช้และผู้ใช้ทำบุ๊คมาร์คโพสต์บล็อก (และเขาสมัครรับฟีดโพสต์ด้วยเหตุผล 'บุ๊คมาร์ค') ฉันไม่ต้องการให้ผู้ใช้รับ แจ้งเตือนทางอีเมลเกี่ยวกับการกระทำในรายการนั้นในขณะที่ถ้าเขาแสดงความคิดเห็นโพสต์ (และดังนั้นจึงสมัครรับฟีดโพสต์ด้วยเหตุผล 'ความคิดเห็น') ฉันต้องการเขาจะได้รับแจ้งเมื่อผู้ใช้รายอื่นเพิ่มความคิดเห็นในโพสต์เดียวกัน ฟิลด์เหตุผลช่วยฉันในการเลือกปฏิบัตินี้ (ฉันใช้มันผ่านคลาส ActivityFilter) พร้อมกับการตั้งค่าการแจ้งเตือนของผู้ใช้


Nicolo martini ฉันต้องการที่จะเพิ่มความคิดเห็นตอบกลับเกี่ยวกับกิจกรรมและแสดงไว้ภายใต้มันเป็นไปได้อย่างไรกับโครงสร้างของคุณ? ฉันควรเพิ่มตารางอื่นหรือเพียงใช้เหมือนกันถ้าเหมือนกันคำแนะนำของคุณคืออะไร
Basit

ประสิทธิภาพของการใช้งานนี้เป็นอย่างไร? การทดสอบใด ๆ บนโต๊ะขนาดใหญ่?
Joshua F. Rountree

16

มีรูปแบบปัจจุบันสำหรับการสตรีมกิจกรรมที่ได้รับการพัฒนาโดยกลุ่มคนที่มีชื่อเสียง

http://activitystrea.ms/

โดยพื้นฐานแล้วทุกกิจกรรมมีนักแสดง (ที่ทำกิจกรรม), กริยา (การกระทำของกิจกรรม), วัตถุ (ซึ่งนักแสดงดำเนินการ) และเป้าหมาย

ตัวอย่างเช่น: Max ได้โพสต์ลิงก์ไปที่กำแพงของอดัม

สเป็คของ JSON ของพวกเขามาถึงเวอร์ชัน 1.0 แล้วในขณะที่เขียนซึ่งแสดงรูปแบบสำหรับกิจกรรมที่คุณสามารถนำไปใช้ได้

รูปแบบของพวกเขาได้รับการรับรองจาก BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID และอื่น ๆ อีกมากมาย


สวัสดี @sntran ฉันรู้ว่าโพสต์นี้เมื่อหลายปีก่อน แต่ฉันมีคำถามเพิ่มเติมเกี่ยวกับสตรีมกิจกรรม มีวิธีที่คุณสามารถช่วยเหลือได้หรือไม่?
hiswendy

แน่ใจ คำถามของคุณคืออะไร?
SầnTrần-Nguyễn

คำถามของฉันโพสต์จริงที่นี่! ลิงค์ ฉันคิดว่าฉันมีความเข้าใจพื้นฐานเกี่ยวกับการสตรีมกิจกรรม แต่จริงๆแล้วฉันไม่แน่ใจว่าจะนำมันไปใช้ได้อย่างไร (เช่นฉันควรใช้ angular หรือ node.js) จากนั้นฉันจะสร้างสตรีมกิจกรรมได้อย่างไรด้วย API JSON ที่เข้ามา? นี่เป็นคำถามพื้นฐาน แต่ฉันไม่สามารถหาคำตอบออนไลน์ได้ หากคุณสามารถช่วยฉันขอขอบคุณมันอย่างแท้จริง ขอบคุณ!
hiswendy

13

ฉันคิดว่าคำอธิบายเกี่ยวกับวิธีการที่ระบบการแจ้งเตือนทำงานบนเว็บไซต์ขนาดใหญ่สามารถพบได้ในคำถามล้นสแต็คเว็บไซต์เครือข่ายสังคมคำนวณการอัปเดตของเพื่อนได้อย่างไร ในคำตอบของJeremy Wall เขาแนะนำให้ใช้Message Qeueและเขาระบุว่าซอฟต์แวร์โอเพนซอร์ซสองตัวที่ติดตั้งไว้:

  1. RabbitMQ
  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 ทำมากกว่าความพอเพียงสำหรับกรณีการใช้งานส่วนใหญ่ที่คุณต้องการสร้างกระแสกิจกรรมฟีดทางสังคมหรือฟังก์ชั่น microblogging ในแอปพลิเคชัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.