소셜 네트워크에서 활동 스트림을 구현하는 방법


140

저는 자체 소셜 네트워크를 개발하고 있으며 웹 구현 예제에서 사용자의 작업 스트림을 찾지 못했습니다 ... 예를 들어 각 사용자의 작업을 필터링하는 방법은 무엇입니까? 액션 이벤트를 저장하는 방법? 작업 스트림과 작업 자체에 사용할 수있는 데이터 모델 및 개체 모델은 무엇입니까?


9
행운을 빕니다, 이것은 우리 모두가 알고 싶어하는 끝없는 질문입니다. 페이스 북이 그것을 어떻게 뽑아 내고, 대답은 매우 복잡하며 우리는 그것을하는 가장 효율적인 방법을 결코 모를 수 있습니다. 당신이 좋은 방법을 찾을 경우, BTW이 그래서 그냥 검색 SO에 많은 많은 시간을 논의하고있다보기에 다른 사람을 위해 여기에 게시 당신은 몇 가지 팁을 발견 할 것이다하시기 바랍니다
JasonDavis

1
Stream Framework는 가장 널리 사용되는 솔루션입니다. github.com/tschellenbach/Stream-Framework 이 패키지 목록도 참조하십시오 : djangopackages.com/grids/g/activities
Thierry

1
개인화와 관련하여 분석 및 기계 학습을 기반으로합니다. 또한 getstream.io/personalization
Thierry

답변:


241

요약 : 약 1 백만 명의 활성 사용자와 1 억 5 천만 개의 저장된 활동에 대해 간단하게 유지합니다.

  • 고유 한 활동을 저장하기 위해 관계형 데이터베이스를 사용하십시오 (활동 당 1 개의 레코드 / "발생한 것") 레코드를 가능한 한 컴팩트하게 만드십시오. 활동 ID 또는 시간 제한이있는 친구 ID 세트를 사용하여 일련의 활동을 신속하게 파악할 수있는 구조입니다.
  • 활동 레코드가 작성 될 때마다 활동 ID를 Redis에 공개하고 활동을보아야하는 친구 / 구독자 인 모든 사용자의 "활동 스트림"목록에 ID를 추가하십시오.

Redis에 쿼리하여 모든 사용자의 활동 스트림을 가져온 다음 필요에 따라 db에서 관련 데이터를 가져옵니다. 사용자가 시간을 거슬러 탐색해야하는 경우 시간별 DB 조회로 돌아갑니다 (제공하는 경우).


약 1,500 만 건의 활동을 처리하기 위해 평범한 오래된 MySQL 테이블을 사용합니다.

다음과 같이 보입니다 :

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내 응용 프로그램에 유용합니다 - 그들은 활동이 관련되어 무엇을 말해. 책이 마음에 들었다면 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는 빠르며 한 연결에서 명령을 파이프 라인하는 방법을 제공하므로 활동을 1000 명의 친구에게 알리려면 밀리 초가 걸립니다.

내가 말하는 것에 대한 자세한 설명은 Redis의 Twitter 예제를 참조하십시오 : http://redis.io/topics/twitter-clone

2011 년 2 월 업데이트 현재 5 천만 건의 활동이 진행 중이며 아무런 변화가 없습니다. 이와 비슷한 일을 할 때 좋은 점은 작고 작은 행을 사용한다는 것입니다. 더 많은 활동과 그 활동에 대한 더 많은 쿼리를 포함하도록 몇 가지 변경을 계획하고 있으며 Redis를 사용하여 신속하게 작업을 수행 할 것입니다. 다른 지역에서 Redis를 사용하고 있으며 특정 종류의 문제에 실제로 효과적입니다.

2014 년 7 월 업데이트 최대 약 7 만 명의 월간 활성 사용자입니다. 지난 몇 년 동안 저는 각 사용자의 마지막 1000 활동 ID를 저장하기 위해 Redis (글 머리 기호 목록에 설명 된대로)를 사용했습니다. 일반적으로 시스템에는 약 1 억 개의 활동 레코드가 있으며 여전히 MySQL에 저장되며 여전히 동일한 레이아웃입니다. 이러한 레코드를 통해 적은 Redis 메모리로 벗어날 수 있고 활동 데이터 레코드로 사용되며 사용자가 무언가를 찾기 위해 시간을 더 넘겨야하는 경우이를 사용합니다.

이것은 영리하거나 특히 흥미로운 해결책은 아니지만 나에게 도움이되었습니다.


2
Redis의 경우 +1 그것이 가능해야하므로 v2를 레디 스에 전적으로 의존하는 가상 메모리를 사용
stagas

16
여러 활동 소스 (추가, 주석 등)가있는 경우이 테이블을 실제 활동과 어떻게 결합합니까? 여러 개의 왼쪽 조인을 사용합니까 (각 활동 테이블마다)?
알리 Shakiba

1
@ casey Echoing @JohnS의 질문- JOIN다양한 activity_type테이블에서 어떻게 수행 합니까? 그것들은 성능 측면에서 비싸지 않습니까?
Rob Sobers

1
누군가 "JOIN"에 대한 JohnS 질문에 대한 답변을 받았습니다. 누구나 설명 할 수있는 링크를 게시 할 수 있습니까? 나는 비슷한 일을해야하며 그것은 매우 도움이 될 것입니다.
Waseem

3
조인이 없습니다. 고유 한 쿼리 하나만 activity_type으로 필요한 다른 데이터를 얻을 수 있습니다.
폭로

21

이것은 mysql을 사용하여 액티비티 스트림을 구현 한 것입니다. Activity, ActivityFeed, Subscriber의 세 가지 클래스가 있습니다.

활동은 활동 항목을 나타내며 해당 테이블은 다음과 같습니다.

id
subject_id
object_id
type
verb
data
time

Subject_id액션을 수행하는 객체 object_id의 id, 액션을받는 객체의 id typeverb(사용자가 문서에 주석을 추가 할 경우, 예를 들어, 그들은 각각 "창조", "코멘트"와 것) 작업 자체를 설명, 데이터 (예를 들어, 피사체의 이름을 포함 할 수 있습니다 조인 방지하기 위해 추가 데이터를 포함 성, 기사 제목 및 URL, 의견 본문 등).

각 활동은 하나 이상의 ActivityFeeds에 속하며 다음과 같은 테이블과 관련됩니다.

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는 Adam의 벽에 대한 링크를 게시했습니다.

JSON 사양은 작성 당시 버전 1.0에 도달했으며 적용 할 수있는 활동의 패턴을 보여줍니다.

BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID 및 기타 여러 형식에서 이미 해당 형식을 채택했습니다.


안녕하세요 @ sntran이 게시물이 몇 년 전인 것을 알고 있지만 활동 스트림에 대한 질문이 더 있습니다. 도울 수있는 방법이 있습니까?
hiswendy

확실한. 귀하의 질문은 무엇인가?
Sơn Trần-Nguyễn

내 질문은 실제로 여기에 게시됩니다! 링크 . 액티비티 스트림에 대한 기본 지식이 있다고 생각하지만 실제로 구현 방법을 잘 모르겠습니다 (즉, angular 또는 node.js를 사용해야합니까?) 들어오는 API JSON? 이것들은 기본적인 질문이지만 온라인에서 답변을 찾을 수 없습니다. 도움이 될 수 있다면 진심으로 감사하겠습니다. 감사합니다!
hiswendy

13

대형 웹 사이트에서 알림 시스템이 작동하는 방식에 대한 설명은 소셜 네트워킹 웹 사이트에서 친구 업데이트를 어떻게 계산합니까? , Jeremy Wall 의 답변에서. 그는 Message Qeue 의 사용을 제안하고 이를 구현하는 두 가지 오픈 소스 소프트웨어를 나타냅니다.

  1. RabbitMQ
  2. 아파치 QPid

또한 질문을 참조하십시오 사회 활동 스트림을 구현하는 가장 좋은 방법은 무엇입니까?


1

성능 및 분산 메시지 큐가 절대적으로 필요합니다. 그러나 끝이 아닙니다. 영구 데이터로 저장할 항목과 일시적인 항목 등을 결정해야합니다.

어쨌든, 고성능의 확장 가능한 시스템을 사용하고 있다면 내 친구는 정말 어려운 작업입니다. 그러나 물론 일부 관대 한 엔지니어들은 이에 대한 경험을 공유했습니다. LinkedIn은 최근 메시지 큐 시스템 Kafka를 오픈 소스로 만들었습니다. 그 전에 Facebook은 이미 Scribe를 오픈 소스 커뮤니티에 제공했습니다. Kafka는 스칼라로 작성되었으며 처음에는 실행하는 데 시간이 걸리지 만 몇 개의 가상 서버로 테스트했습니다. 정말 빠릅니다.

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와 같은 다양한 기능이 없지만 활동 스트림, 소셜 피드 또는 마이크로 블로깅 기능을 애플리케이션에 빌드해야하는 대부분의 유스 케이스에 충분합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.