소셜 네트워크에서 활동 스트림을 구현하는 방법
저는 자체 소셜 네트워크를 개발하고 있으며 웹 구현 예제에서 사용자의 작업 스트림을 찾지 못했습니다 ... 예를 들어 각 사용자의 작업을 필터링하는 방법은 무엇입니까? 액션 이벤트를 저장하는 방법? 작업 스트림과 작업 자체에 사용할 수있는 데이터 모델과 개체 모델은 무엇입니까?
요약 : 약 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 활동 레코드 작성
- 활동을 만든 사용자의 각 친구에 대해 Redis의 활동 목록으로 ID를 푸시하십시오.
- 각 목록을 마지막 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 메모리를 확보 할 수 있고 활동 데이터 레코드로 사용되며 사용자가 무언가를 찾기 위해 시간을 더 넘겨야하는 경우이 레코드를 사용합니다.
이것은 영리하거나 특히 흥미로운 해결책은 아니지만 나에게 도움이되었습니다.
이것은 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
내 응용 프로그램에는 각 사용자에 대해 하나의 피드와 각 항목에 대해 하나의 피드 (일반적으로 블로그 기사)가 있지만 원하는대로 할 수 있습니다.
A Subscriber is usually an user of your site, but it can also be any object in your object model (for example an article could be subscribed to the feed_action of his creator).
Every Subscriber belongs to one or more ActivityFeeds, and, like above, they are related by a link table of this kind:
feed_name
subscriber_id
reason
The reason
field here explains why the subscriber has subscribed the feed. For example, if a user bookmark a blog post, the reason is 'bookmark'. This helps me later in filtering actions for notifications to the users.
To retrieve the activity for a subscriber, I do a simple join of the three tables. The join is fast because I select few activities thanks to a WHERE
condition that looks like now - time > some hours
. I avoid other joins thanks to data field in Activity table.
Further explanation on reason
field. If, for example, I want to filter actions for email notifications to the user, and the user bookmarked a blog post (and so he subscribes to the post feed with the reason 'bookmark'), I don't want that the user receives email notifications about actions on that item, while if he comments the post (and so it subscribes to the post feed with reason 'comment') I want he is notified when other users add comments to the same post. The reason field helps me in this discrimination (I implemented it through an ActivityFilter class), together with the notifications preferences of the user.
There is a current format for activity stream that is being developed by a bunch of well-know people.
Basically, every activity has an actor (who performs the activity), a verb (the action of the activity), an object (on which the actor performs on), and a target.
For example: Max has posted a link to Adam's wall.
Their JSON's Spec has reached version 1.0 at the time of writing, which shows the pattern for the activity that you can apply.
Their format has already been adopted by BBC, Gnip, Google Buzz Gowalla, IBM, MySpace, Opera, Socialcast, Superfeedr, TypePad, Windows Live, YIID, and many others.
I think that an explanation on how notifications system works on large websites can be found in the stack overflow question how does social networking websites compute friends updates?, in the Jeremy Wall's answer. He suggests the use of Message Qeue and he indicates two open source softwares that implement it:
See also the question What’s the best manner of implementing a social activity stream?
You absolutely need a performant & distributed message queue. But it does not end there, you'll have to make decisions on what to store as persistent data and what as transient and etc.
Anyway, it is really a difficult task my friend if you are after a high performance and scalable system. But, of course some generous engineers have shared their experience on this. LinkedIn lately made its message queue system Kafka open source. Before that, Facebook had already provided Scribe to the open source community. Kafka is written in Scala and at first it takes some time to make it run but i tested with a couple of virtual servers. It is really fast.
http://blog.linkedin.com/2011/01/11/open-source-linkedin-kafka/
http://incubator.apache.org/kafka/index.html
Instead of rolling your own, you could look to a third party service used via an API. I started one called Collabinate (http://www.collabinate.com) that has a graph database backend and some fairly sophisticated algorithms for handling large amounts of data in a highly concurrent, high performance manner. While it does not have the breadth of functionality that say Facebook or Twitter do, it more than suffices for most use cases where you need to build activity streams, social feeds, or microblogging functionality into an application.
참고URL : https://stackoverflow.com/questions/1443960/how-to-implement-the-activity-stream-in-a-social-network
'Programming' 카테고리의 다른 글
클래스 상수에 액세스 (0) | 2020.06.29 |
---|---|
숫자 (0-9) 만 허용하고 문자는 허용하지 않는 정규식 (0) | 2020.06.29 |
Java 클래스가 비슷한 것을 구현해야하는 이유는 무엇입니까? (0) | 2020.06.28 |
Python 프로그램을 C / C ++ 코드로 변환 하시겠습니까? (0) | 2020.06.28 |
Hamcrest에서 무언가가 null인지 어떻게 주장합니까? (0) | 2020.06.28 |