문제

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

도움이 되었습니까?

해결책

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

  • 독특한 활동 (활동 당 1 개의 레코드 / "발생한 일")을 저장하기 위해 관계형 데이터베이스를 사용하여 최대한 레코드를 작곡하십시오. 활동 ID 또는 시간 제약이있는 친구 ID 세트를 사용하여 활동을 신속하게 잡을 수 있도록 구조.
  • 활동 레코드가 생성 될 때마다 활동 ID를 Redis에 게시하여 활동을 볼 수있는 친구/가입자 인 모든 사용자에 대한 ID를 "활동 스트림"목록에 추가하십시오.

Query 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는 모든 데이터를 메모리에 저장하므로 모든 활동을 거기에 넣을 수는 없지만 사이트에 일반적으로 적중 된 화면의 대부분을 충분히 저장할 수 있습니다. 각 사용자 또는 그와 비슷한 것에 대해 가장 최근의 100 개. Redis가 믹스에 있으면 다음과 같이 작동 할 수 있습니다.

  • MySQL 활동 레코드를 만듭니다
  • 활동을 만든 사용자의 각 친구에 대해 Redis의 활동 목록에 ID를 푸시하십시오.
  • 각 목록을 마지막 X 항목으로 자릅니다

Redis는 빠르며 하나의 연결에 걸쳐 파이프 라인 명령을 제공하는 방법을 제공하므로 1000 명의 친구에게 활동을 밀면 밀리 초가 걸립니다.

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

2011 년 2 월 업데이트 현재 5 천만 개의 활동적인 활동이 있었고 아무것도 바꾸지 않았습니다. 이것과 비슷한 일을하는 것에 대한 좋은 점은 작고 작은 줄을 사용한다는 것입니다. 나는 더 많은 활동과 그 활동에 대한 더 많은 쿼리를 포함하는 몇 가지 변경을 계획하고 있으며, Redis를 사용하여 물건을 빠르게 유지할 것입니다. 나는 다른 영역에서 Redis를 사용하고 있으며 특정 종류의 문제에 실제로 잘 작동합니다.

2014 년 7 월 업데이트 우리는 최대 약 700K 월간 활성 사용자입니다. 지난 몇 년 동안 각 사용자의 마지막 1000 활동 ID를 저장하기 위해 Redis (Bulleted List에 설명 된대로)를 사용해 왔습니다. 시스템에는 일반적으로 약 1 억 개의 활동 기록이 있으며 여전히 MySQL에 저장되어 있으며 여전히 동일한 레이아웃입니다. 이 레코드를 통해 우리는 덜 Redis 메모리로 도망 갈 수 있으며 활동 데이터의 레코드 역할을하며 사용자가 무언가를 찾기 위해 시간을 더 다시 방문 해야하는 경우 사용합니다.

이것은 영리하거나 특히 흥미로운 해결책이 아니었지만 저를 잘 제공했습니다.

다른 팁

이것은 MySQL을 사용하여 활동 스트림을 구현하는 것입니다. 활동, 활동 피드, 가입자의 세 가지 클래스가 있습니다.

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

id
subject_id
object_id
type
verb
data
time

Subject_id 객체의 ID가 동작을 수행하는 것입니다. object_id 동작을받는 객체의 ID. type 그리고 verb 조치 자체를 설명합니다 (예 : 사용자가 각각 "댓글"및 "작성된"기사에 주석을 추가하는 경우 각각 "주석"및 "생성 된"경우 데이터는 조인을 피하기 위해 추가 데이터가 포함되어 있습니다 (예 : 제목 이름과 포함 할 수 있습니다. 성, 기사 제목 및 URL, 주석 본문 등).

각 활동은 하나 이상의 활동 피드에 속하며 다음과 같은 것처럼 보이는 테이블과 관련이 있습니다.

feed_name
activity_id

내 응용 프로그램에는 각 사용자마다 하나의 피드와 각 항목에 대해 하나의 피드 (일반적으로 블로그 기사)가 있지만 원하는대로 할 수 있습니다.

가입자는 일반적으로 사이트의 사용자이지만 객체 모델의 모든 객체 일 수도 있습니다 (예 : 기사는 제작자의 Feed_action에 가입 할 수 있음).

모든 가입자는 하나 이상의 ActivityFeeds에 속하며 위와 마찬가지로 이러한 종류의 링크 테이블과 관련이 있습니다.

feed_name
subscriber_id
reason

그만큼 reason 여기에 필드는 가입자가 피드를 구독 한 이유를 설명합니다. 예를 들어, 사용자가 블로그 게시물을 북마크하는 경우 그 이유는 '북마크'입니다. 이것은 나중에 사용자에게 알림을 필터링하는 데 도움이됩니다.

가입자의 활동을 검색하기 위해 세 테이블에 간단한 조인을합니다. 덕분에 몇 가지 활동을 선택하기 때문에 조인이 빠릅니다. WHERE 지금처럼 보이는 상태 - time > some hours. 활동 테이블의 데이터 필드 덕분에 다른 조인을 피합니다.

추가 설명 reason 필드. 예를 들어, 사용자에게 이메일 알림을 필터링하려면 사용자가 블로그 게시물을 북마크 한 경우 (따라서 '북마크'이유가있는 게시물 피드에 구독 한 경우) 사용자가받는 것을 원하지 않습니다. 해당 항목에 대한 조치에 대한 이메일 알림, 게시물에 댓글을 달면 (따라서 '코멘트'가있는 게시물 피드에 가입하면 다른 사용자가 동일한 게시물에 주석을 추가 할 때 알림을 받기를 원합니다. 이유 필드는 사용자의 알림 환경 설정과 함께이 차별 (ActivityFilter 클래스를 통해 구현)에 도움이됩니다.

잘 알고있는 사람들이 개발하고있는 활동 스트림의 현재 형식이 있습니다.

http://activitystrea.ms/.

기본적으로 모든 활동에는 배우 (활동을 수행하는 사람), 동사 (활동의 동작), 대상 (배우가 수행하는) 및 대상이 있습니다.

예를 들어, Max는 Adam의 벽에 링크를 게시했습니다.

JSON의 사양은 글을 쓰는 시점에서 버전 1.0에 도달했으며, 이는 적용 할 수있는 활동의 패턴을 보여줍니다.

그들의 형식은 이미 BBC, GNIP, Google Buzz Gowalla, IBM, MySpace, Opera, Social, SuperFeedr, TypePad, Windows Live, Yiid 등에 의해 이미 채택되었습니다.

큰 웹 사이트에서 알림 시스템이 어떻게 작동하는지에 대한 설명은 스택 오버 플로우 질문에서 찾을 수 있다고 생각합니다. 소셜 네트워킹 웹 사이트는 친구 업데이트를 어떻게 계산합니까?,에서 제레미 월대답. 그는 사용을 제안합니다 메시지 Qeue 그리고 그는 그것을 구현하는 두 개의 오픈 소스 소프트웨어를 나타냅니다.

  1. Rabbitmq
  2. 아파치 QPID

질문도 참조하십시오 사회 활동 흐름을 구현하는 가장 좋은 방법은 무엇입니까?

당신은 절대적으로 성능 및 분산 메시지 대기열이 필요합니다. 그러나 그것은 끝나지 않습니다. 당신은 영구 데이터로 저장 해야하는 것에 대한 결정과 일시적인 등의 내용에 대한 결정을 내려야합니다.

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

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

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

직접 굴리는 대신 API를 통해 사용되는 제 3 자 서비스를 볼 수 있습니다. 나는 Collabinate라는 하나를 시작했습니다 (http://www.collabinate.com)에는 그래프 데이터베이스 백엔드와 많은 양의 데이터를 동시에 고성능으로 처리하기위한 상당히 정교한 알고리즘이 있습니다. Facebook이나 Twitter라고 말하는 기능의 폭 넓은 기능은 없지만 활동 스트림, 소셜 피드 또는 마이크로 블로그 기능을 애플리케이션으로 구축 해야하는 대부분의 사용 사례에 충분합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top