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

소셜 활동 스트림을 구현하는 가장 좋은 방법 인 귀하의 의견을 듣고 싶습니다 (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에 사용 가능한 클라이언트가 있습니다.

또한이 높은 확장 성 게시물을 살펴보면 관련된 디자인 결정 중 일부를 설명했습니다
. 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 , 유형 ID ObjectId가 주체 – 동사 – 개체 이벤트가 캡처 (나중에 쿼리) 할 수 있도록. 각 작업으로 인해 여러 개의 StreamEvent 인스턴스가 생성 될 수 있습니다.

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

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

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

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

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


답변

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

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

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