저는 자체 소셜 네트워크를 개발하고 있으며 웹 구현 예제에서 사용자의 작업 스트림을 찾지 못했습니다 ... 예를 들어 각 사용자의 작업을 필터링하는 방법은 무엇입니까? 액션 이벤트를 저장하는 방법? 작업 스트림과 작업 자체에 사용할 수있는 데이터 모델 및 개체 모델은 무엇입니까?
저는 자체 소셜 네트워크를 개발하고 있으며 웹 구현 예제에서 사용자의 작업 스트림을 찾지 못했습니다 ... 예를 들어 각 사용자의 작업을 필터링하는 방법은 무엇입니까? 액션 이벤트를 저장하는 방법? 작업 스트림과 작업 자체에 사용할 수있는 데이터 모델 및 개체 모델은 무엇입니까?
답변:
요약 : 약 1 백만 명의 활성 사용자와 1 억 5 천만 개의 저장된 활동에 대해 간단하게 유지합니다.
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가 혼합되어 있으면 다음과 같이 작동 할 수 있습니다.
Redis는 빠르며 한 연결에서 명령을 파이프 라인하는 방법을 제공하므로 활동을 1000 명의 친구에게 알리려면 밀리 초가 걸립니다.
내가 말하는 것에 대한 자세한 설명은 Redis의 Twitter 예제를 참조하십시오 : http://redis.io/topics/twitter-clone
2011 년 2 월 업데이트 현재 5 천만 건의 활동이 진행 중이며 아무런 변화가 없습니다. 이와 비슷한 일을 할 때 좋은 점은 작고 작은 행을 사용한다는 것입니다. 더 많은 활동과 그 활동에 대한 더 많은 쿼리를 포함하도록 몇 가지 변경을 계획하고 있으며 Redis를 사용하여 신속하게 작업을 수행 할 것입니다. 다른 지역에서 Redis를 사용하고 있으며 특정 종류의 문제에 실제로 효과적입니다.
2014 년 7 월 업데이트 최대 약 7 만 명의 월간 활성 사용자입니다. 지난 몇 년 동안 저는 각 사용자의 마지막 1000 활동 ID를 저장하기 위해 Redis (글 머리 기호 목록에 설명 된대로)를 사용했습니다. 일반적으로 시스템에는 약 1 억 개의 활동 레코드가 있으며 여전히 MySQL에 저장되며 여전히 동일한 레이아웃입니다. 이러한 레코드를 통해 적은 Redis 메모리로 벗어날 수 있고 활동 데이터 레코드로 사용되며 사용자가 무언가를 찾기 위해 시간을 더 넘겨야하는 경우이를 사용합니다.
이것은 영리하거나 특히 흥미로운 해결책은 아니지만 나에게 도움이되었습니다.
JOIN
다양한 activity_type
테이블에서 어떻게 수행 합니까? 그것들은 성능 측면에서 비싸지 않습니까?
activity_type
으로 필요한 다른 데이터를 얻을 수 있습니다.
이것은 mysql을 사용하여 액티비티 스트림을 구현 한 것입니다. Activity, ActivityFeed, Subscriber의 세 가지 클래스가 있습니다.
활동은 활동 항목을 나타내며 해당 테이블은 다음과 같습니다.
id
subject_id
object_id
type
verb
data
time
Subject_id
액션을 수행하는 객체 object_id
의 id, 액션을받는 객체의 id type
및 verb
(사용자가 문서에 주석을 추가 할 경우, 예를 들어, 그들은 각각 "창조", "코멘트"와 것) 작업 자체를 설명, 데이터 (예를 들어, 피사체의 이름을 포함 할 수 있습니다 조인 방지하기 위해 추가 데이터를 포함 성, 기사 제목 및 URL, 의견 본문 등).
각 활동은 하나 이상의 ActivityFeeds에 속하며 다음과 같은 테이블과 관련됩니다.
feed_name
activity_id
내 응용 프로그램에는 각 사용자에 대해 하나의 피드와 각 항목에 대해 하나의 피드 (일반적으로 블로그 기사)가 있지만 원하는대로 할 수 있습니다.
가입자는 일반적으로 사이트의 사용자이지만 객체 모델의 모든 객체 일 수도 있습니다 (예 : 기사가 작성자의 feed_action에 가입 될 수 있음).
모든 가입자는 하나 이상의 ActivityFeeds에 속하며 위와 같이 이러한 종류의 링크 테이블과 관련됩니다.
feed_name
subscriber_id
reason
reason
여기 의 필드는 가입자가 피드를 구독 한 이유를 설명합니다. 예를 들어, 사용자가 블로그 게시물을 책갈피에 추가하면 그 이유는 '북마크'입니다. 이를 통해 나중에 사용자에게 알림을위한 작업을 필터링 할 수 있습니다.
구독자에 대한 활동을 검색하기 위해 세 테이블을 간단히 조인합니다. WHERE
지금처럼 보이는 조건으로 인해 몇 가지 활동을 선택하기 때문에 조인이 빠릅니다 time > some hours
. 활동 테이블의 데이터 필드 덕분에 다른 조인을 피할 수 있습니다.
reason
필드에 대한 추가 설명 . 예를 들어, 사용자에게 이메일 알림에 대한 조치를 필터링하고 사용자가 블로그 게시물을 책갈피에 추가하여 ( '책갈피'이유로 게시물 피드를 구독 한 경우) 사용자가받는 것을 원하지 않습니다. 해당 항목에 대한 작업에 대한 전자 메일 알림, 게시물에 댓글을 달고 이유가 '댓글'인 게시물 피드를 구독하는 경우 다른 사용자가 동일한 게시물에 댓글을 추가하면 알림을 받고 싶습니다. 이유 필드는 사용자의 알림 환경 설정과 함께이 구별 (ActivityFilter 클래스를 통해 구현)에 도움이됩니다.
잘 알려진 많은 사람들이 개발하고있는 활동 스트림의 현재 형식이 있습니다.
기본적으로 모든 활동에는 행위자 (활동을 수행하는 사람), 동사 (활동의 활동), 행위자 (행위자가 수행하는 대상) 및 대상이 있습니다.
예를 들어 : Max는 Adam의 벽에 대한 링크를 게시했습니다.
JSON 사양은 작성 당시 버전 1.0에 도달했으며 적용 할 수있는 활동의 패턴을 보여줍니다.
BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID 및 기타 여러 형식에서 이미 해당 형식을 채택했습니다.
대형 웹 사이트에서 알림 시스템이 작동하는 방식에 대한 설명은 소셜 네트워킹 웹 사이트에서 친구 업데이트를 어떻게 계산합니까? , Jeremy Wall 의 답변에서. 그는 Message Qeue 의 사용을 제안하고 이를 구현하는 두 가지 오픈 소스 소프트웨어를 나타냅니다.
또한 질문을 참조하십시오 사회 활동 스트림을 구현하는 가장 좋은 방법은 무엇입니까?
성능 및 분산 메시지 큐가 절대적으로 필요합니다. 그러나 끝이 아닙니다. 영구 데이터로 저장할 항목과 일시적인 항목 등을 결정해야합니다.
어쨌든, 고성능의 확장 가능한 시스템을 사용하고 있다면 내 친구는 정말 어려운 작업입니다. 그러나 물론 일부 관대 한 엔지니어들은 이에 대한 경험을 공유했습니다. LinkedIn은 최근 메시지 큐 시스템 Kafka를 오픈 소스로 만들었습니다. 그 전에 Facebook은 이미 Scribe를 오픈 소스 커뮤니티에 제공했습니다. Kafka는 스칼라로 작성되었으며 처음에는 실행하는 데 시간이 걸리지 만 몇 개의 가상 서버로 테스트했습니다. 정말 빠릅니다.
http://blog.linkedin.com/2011/01/11/open-source-linkedin-kafka/
직접 롤링하는 대신 API를 통해 사용되는 타사 서비스를 살펴볼 수 있습니다. Collabinate ( http://www.collabinate.com )라는 그래프 데이터베이스 백엔드와 많은 양의 데이터를 동시에 수행하는 고성능 알고리즘으로 처리하는 상당히 정교한 알고리즘을 가지고 있습니다. Facebook이나 Twitter와 같은 다양한 기능이 없지만 활동 스트림, 소셜 피드 또는 마이크로 블로깅 기능을 애플리케이션에 빌드해야하는 대부분의 유스 케이스에 충분합니다.