IT

소셜 활동 스트림을 구현하는 가장 좋은 방법은 무엇입니까?

lottoking 2020. 3. 29. 09:13
반응형

소셜 활동 스트림을 구현하는 가장 좋은 방법은 무엇입니까? [닫은]


소셜 활동 스트림을 구현하는 가장 좋은 방법 인 의견을 듣고 싶습니다 (Facebook이 가장 유명한 예입니다). 관련된 문제 / 도전은 다음과 같습니다.

  • 다양한 유형의 활동 (게시, 댓글 작성 ..)
  • 다양한 유형의 객체 (게시물, 댓글, 사진 ..)
  • 다른 역할에 관련된 1-n 명의 사용자 ( "사용자 x는 사용자의 Z 게시물에 대한 사용자 y의 의견에 답변했습니다")
  • 동일한 활동 항목의 다른보기 ( "댓글을 달았습니다 .."vs. "친구 x는 댓글을 달았습니다"vs. "사용자 x는 댓글을 달았습니다 .."=> "댓글"활동의 3 가지 표현)

예를 들어 Facebook이 여러 활동 항목을 하나로 결합하는 것처럼 (예 : "사용자 x, y 및 z는 해당 사진에 댓글을 달았습니다")

그러한 시스템, 데이터 모델 등을 구현하기위한 가장 유연하고 효율적이며 강력한 접근 방식에 대한 패턴, 논문 등에 대한 생각이나 포인터는 높이 평가 될 것입니다.

대부분의 문제는 플랫폼에 구애받지 않지만 Ruby on Rails에서 이러한 시스템을 구현할 가능성이 있습니다.


나는 그러한 시스템을 만들었고이 접근법을 취했습니다.

id, userId, type, data, time 열이있는 데이터베이스 테이블

  • userId 는 활동을 생성 한 사용자입니다.
  • type 은 활동의 유형입니다 (예 : 블로그 게시물 작성, 사진 추가, 사용자 사진에 댓글 추가)
  • data 는 원하는 것을 넣을 수있는 활동에 대한 메타 데이터 가있는 직렬화 된 객체입니다.

이렇게하면 피드, 사용자, 시간 및 활동 유형에 대한 검색 / 조회가 제한되지만 페이스 북 유형의 활동 피드에서는 이것이 제한적이지 않습니다. 그리고 테이블에 정확한 색인으로 조회가 빠릅니다 .

이 디자인을 사용하면 각 이벤트 유형에 필요한 메타 데이터를 결정해야합니다. 예를 들어 새 사진의 피드 활동은 다음과 같습니다.

{id:1, userId:1, type:PHOTO, time:2008-10-15 12:00:00, data:{photoId:2089, photoName:A trip to the beach}}

사진의 이름이 사진을 포함하는 다른 테이블에 저장되어 있지만 거기에서 이름을 검색 할 수는 있지만 메타 데이터 필드에 이름을 복제합니다. 속도를 원하는 경우 다른 데이터베이스 테이블의 조인 그리고 50 명의 다른 사용자로부터 200 개의 다른 이벤트를 표시하려면 속도가 필요합니다.

그런 다음 다양한 유형의 활동 항목을 렌더링하기 위해 기본 FeedActivity 클래스를 확장하는 클래스가 있습니다. 렌더링 코드에는 이벤트 그룹화도 내장되어 데이터베이스와의 복잡성을 방지합니다.


이것은 Etsy.com이 활동 흐름을 어떻게 설계했는지를 설명하는 매우 훌륭한 프레젠테이션입니다. 난간에 관한 것이 아니지만 주제에서 찾은 가장 좋은 예입니다.

http://www.slideshare.net/danmckinley/etsy-activity-feeds-architecture


우리는 열려있는 우리의 접근을 공급했습니다 https://github.com/tschellenbach/Stream-Framework 그것은 현재이 문제를 해결하기위한 가장 큰 오픈 소스 라이브러리입니다.

Stream Framework를 구축 한 팀도 복잡성을 처리하는 호스팅 된 API를 제공합니다. getstream.io를 살펴보십시오. Node, Python, Rails 및 PHP에 사용할 수있는 클라이언트가 있습니다.

또한이 확장 성 게시물을 살펴보면 관련된 디자인 결정에 대해 설명했습니다 .http : //highscalability.com/blog/2013/10/28/design-decisions-for-scaling-your-high-traffic- feeds.html

이 튜토리얼 은 Redis를 사용하여 Pinterest의 피드와 같은 시스템을 설정하는 데 도움이됩니다. 시작하기가 매우 쉽습니다.

피드 디자인에 대해 자세히 알아 보려면 Feedly를 기반으로하는 기사 중 일부를 읽는 것이 좋습니다.

Stream Framework는 Python 기반이지만 Ruby 앱에서는 사용하기가 어렵지 않습니다. 간단히 서비스로 실행하고 앞에 작은 http API를 붙일 수 있습니다. 다른 언어에서 Feedly에 액세스하기위한 API 추가를 고려하고 있습니다. 현재로서는 자신의 역할을 맡아야합니다.


이벤트 스트림의 가장 큰 문제는 가시성과 성능입니다. 표시되는 이벤트를 해당 특정 사용자에게 흥미로운 이벤트로 제한해야하며 해당 이벤트를 정렬하고 식별하는 데 걸리는 시간을 유지해야합니다. 나는 작은 소셜 네트워크를 구축했습니다. 소규모로, 데이터베이스에 "이벤트"테이블을 유지하면 작동하지만 적당한로드에서 성능 문제가된다는 것을 알았습니다.

더 많은 메시지 및 사용자 스트림을 사용하는 경우 이벤트가 개별 프로파일에 메시지로 전송되는 메시징 시스템을 사용하는 것이 가장 좋습니다. 즉, 사람들의 이벤트 스트림을 쉽게 구독 할 수없고 이전 이벤트를 매우 쉽게 볼 수 있지만 특정 사용자에 대한 스트림을 렌더링해야 할 때 작은 메시지 그룹을 렌더링하는 것입니다.

나는 이것이 트위터의 원래 디자인 결함이라고 생각한다. 나는 그들이 이벤트를 가져 와서 필터링하기 위해 데이터베이스를 쳤다는 것을 기억한다. 이것은 아키텍처와 관련이 있고 Rails와는 아무런 관련이 없었습니다. 불행히도 "루비는 확장 할 수 없습니다"밈을 낳았습니다. 필자는 최근 개발자가 Amazon의 Simple Queue Service 를 훨씬 높은 확장 기능을 가진 트위터와 같은 애플리케이션의 메시징 백엔드로 사용하는 프레젠테이션을 보았습니다. 부하가 충분히 높은 경우 시스템의 일부로 SQS를 살펴볼 가치가 있습니다. .


별도의 소프트웨어를 사용하려는 경우 활동 스트림 (neo4j 그래프 데이터베이스 위에 구축)의 문제를 정확하게 해결하는 Graphity 서버를 제안합니다.

이 알고리즘은 독립형 REST 서버로 구현되어 자체 스트림을 제공하기 위해 자체 서버를 호스팅 할 수 있습니다. http://www.rene-pickhardt.de/graphity-server-for-social-activity-streams-released-gplv3 /

논문과 벤치 마크에서 뉴스 스트림 검색은 데이터의 비정규 화로 인한 중복없이 검색하려는 항목 수에 따라 선형으로 만 달라집니다.

http://www.rene-pickhardt.de/graphity-an-efficient-graph-model-for-retrieving-the-top-k-news-feeds-for-users-in-social-networks/

위의 링크에서 스크린 캐스트와이 접근법의 벤치 마크를 볼 수 있습니다 (그래프 티가 초당 10k 개 이상의 스트림을 검색 할 수 있음을 보여줍니다).


어제 이와 같은 시스템을 구현하기 시작했습니다.

Id , ActorId , TypeId , Date , ObjectId 속성 과 추가 Details 키 / 값 쌍 의 해시 테이블을 사용 하여 StreamEvent 클래스를 만들었습니다 . 데이터베이스에서 StreamEvent 테이블 ( Id , ActorId , TypeId , Date , ObjectId ) 및 StreamEventDetails 테이블 ( StreamEventId , DetailKey , DetailValue )로 표시됩니다.

ActorId , 유형 IDObjectId가이 주체 - 동사 - 개체 이벤트가 캡처 (나중에 쿼리) 할 수 있도록. 각 작업으로 인해 여러 개의 StreamEvent 인스턴스가 생성 될 수 있습니다.

그런 다음 각 유형의 이벤트 (예 : LoginEvent , PictureCommentEvent)에 대한 StreamEvent의 하위 클래스를 작성했습니다 . 이러한 각 서브 클래스에는 실제로 해시 테이블 / StreamEventDetail 테이블에 키 / 값 쌍으로 저장되는 PictureId , ThumbNail , CommenText 등과 같은 컨텍스트 별 특성 (이벤트에 필요한 것)이 있습니다.

데이터베이스에서 이러한 이벤트를 다시 가져올 때 팩토리 메소드 ( TypeId 기반 )를 사용하여 올바른 StreamEvent 클래스를 작성하십시오.

StreamEvent의 각 하위 클래스 에는 전달 된 StreamContext 클래스를 기반으로 이벤트를 화면에 출력 하는 Render ( context As StreamContext ) 메서드가 있습니다. StreamContext 클래스를 사용하면 뷰의 컨텍스트에 따라 옵션을 설정할 수 있습니다. 예를 들어 Facebook을 보면 홈페이지의 뉴스 피드에 각 작업에 관련된 모든 사람의 이름과 프로필 링크가 나열되어 있지만 친구의 피드를 보면 이름 만 볼 수 있지만 다른 배우의 이름 만 볼 수 있습니다. .

아직 집계 피드 (Facebook 홈)를 구현하지는 않았지만 UserId , StreamEventId 필드가있는 일종의 'Hmmm, 당신은이 흥미로운 것을 찾을 수 있습니다'알고리즘을 가진 AggregateFeed 테이블을 만들 것이라고 상상 합니다.

모든 의견은 대단히 감사하겠습니다.


// 실제 이벤트 당 하나의 항목
이벤트 {
  ID, 타임 스탬프, 유형, 데이터
}

// 이벤트 당 하나의 항목, 해당 이벤트를 포함하는 피드 당
events_feeds {
  event_id, feed_id
}

이벤트가 작성되면 표시되는 피드를 결정하고 events_feeds에 추가하십시오. 피드를 받으려면 events_feeds에서 선택하고 이벤트에 참여하며 타임 스탬프별로 정렬하십시오. 그런 다음 해당 쿼리 결과에서 필터링 및 집계를 수행 할 수 있습니다. 이 모델을 사용하면 추가 작업없이 작성 후 이벤트 특성을 변경할 수 있습니다.


Rails에서 구현하기로 결정했다면 다음 플러그인이 유용 할 것입니다.

ActivityStreams : http://github.com/face/activity_streams/tree/master

다른 것이 없다면 데이터 모델과 활동 푸시 및 풀을 위해 제공된 API 측면에서 구현을 살펴볼 것입니다.


특정 활동 스트림에 표시 될 모든 데이터를 포함하는 비정규 화 된 테이블 인 heyman과 비슷한 접근 방식을 가졌습니다. 활동이 제한된 작은 사이트에 적합합니다.

위에서 언급했듯이 사이트가 성장함에 따라 확장 성 문제에 직면 할 수 있습니다. 개인적으로 지금은 스케일링 문제에 대해 걱정하지 않습니다. 나중에 그것에 대해 걱정할 것입니다.

페이스 북은 분명히 훌륭한 스케일링 작업을 수행 했으므로 엔지니어링 블로그에 엄청난 양의 컨텐츠가 포함되어 있기 때문에 엔지니어링 블로그를 읽는 것이 좋습니다.-> http://www.facebook.com/notes.php?id=9445547199

위에서 언급 한 비정규 화 된 테이블보다 더 나은 솔루션을 찾고 있습니다. 내가 이것을 달성하는 또 다른 방법은 주어진 활동 스트림에있을 모든 내용을 단일 행으로 압축하는 것입니다. XML, JSON 또는 응용 프로그램에서 읽을 수있는 직렬화 된 형식으로 저장 될 수 있습니다. 업데이트 프로세스도 간단합니다. 활동이 발생하면 새 활동을 대기열에 넣고 (아마도 Amazon SQS 등을 사용하여) 다음 항목의 대기열을 계속 폴링합니다. 해당 항목을 잡고 구문 분석 한 후 해당 컨텐츠를 데이터베이스에 저장된 적절한 피드 오브젝트에 배치하십시오.

이 방법의 좋은 점은 일련의 테이블을 가져 가지 않고 특정 피드가 요청 될 때마다 단일 데이터베이스 테이블 만 읽으면된다는 것입니다. 또한 목록을 업데이트 할 때마다 가장 오래된 활동 항목이 나타날 수 있으므로 유한 활동 목록을 유지할 수 있습니다.

도움이 되었기를 바랍니다! :)


이러한 활동 스트림에 대한 두 가지 레일 캐스트가 있습니다.

이러한 솔루션에는 모든 요구 사항이 포함되어 있지 않지만 몇 가지 아이디어를 제공해야합니다.


내 생각 소리 접촉의 접근 방식은 흥미 롭다 : 그들은 Google 금융의 주식 차트처럼 많이 보이는 형식으로 전체 타임 라인을 제공합니다.

소셜 네트워킹 네트워크의 작동 방식을 확인하려면 Ning살펴볼 가치가 있습니다 . 개발자 페이지는 특히 도움이 보인다.


몇 달 전에이 문제를 해결했지만 구현이 너무 기본적이라고 생각합니다.
다음 모델을 만들었습니다.

HISTORY_TYPE

ID           - The id of the history type
NAME         - The name (type of the history)
DESCRIPTION  - A description

HISTORY_MESSAGES

ID
HISTORY_TYPE - A message of history belongs to a history type
MESSAGE      - The message to print, I put variables to be replaced by the actual values

HISTORY_ACTIVITY

ID
MESSAGE_ID    - The message ID to use
VALUES        - The data to use

MESSAGE_ID_1 => "User %{user} created a new entry"
ACTIVITY_ID_1 => MESSAGE_ID = 1, VALUES = {user: "Rodrigo"}

여러 애플리케이션에서 소셜 피드, 마이크로 블로그 및 협업 기능을 사용하기 위해 활동 스트림을 구현 한 후 기본 기능이 매우 일반적이며 API를 통해 활용하는 외부 서비스로 전환 될 수 있음을 깨달았습니다. 스트림을 프로덕션 애플리케이션에 빌드하고 고유하거나 매우 복잡한 요구가없는 경우 검증 된 서비스를 사용하는 것이 가장 좋습니다. 관계형 데이터베이스를 기반으로 간단한 솔루션을 롤링하는 것보다 프로덕션 응용 프로그램에 이것을 권장합니다.

우리 회사 인 Collabinate ( http://www.collabinate.com )는이 실현으로 성장했으며이를 달성하기 위해 그래프 데이터베이스 위에 확장 가능한 고성능 활동 스트림 엔진을 구현했습니다. 실제로 엔진을 구축하기 위해 Graphity 알고리즘의 변형 (여기서 답변을 제공 한 @RenePickhardt의 초기 작업에서 수정)을 사용했습니다.

엔진을 직접 호스팅하거나 특수한 기능이 필요한 경우 핵심 코드는 실제로 비상업적 목적을위한 오픈 소스이므로 살펴볼 수 있습니다.

참고 URL : https://stackoverflow.com/questions/202198/whats-the-best-manner-of-implementing-a-social-activity-stream

반응형