알림 시스템 구축 [폐쇄]


170

나는 우리의 페이지 (소셜 게임 타입)를위한 페이스 북 스타일 알림 시스템을 구축하기 시작했고 이제 그러한 시스템을 디자인하는 가장 좋은 방법이 무엇인지 연구하고있다. 사용자에게 알림을 보내는 방법에 관심이 없습니다 (현재조차도). 서버에 시스템을 구축하는 방법 (알림 저장 방법, 저장 위치, 가져 오는 방법 등)을 연구 중입니다.

그래서 ... 우리가 가지고있는 몇 가지 요구 사항 :

  • 성수기에는 약 1k 명의 동시 로그인 한 사용자 (및 더 많은 게스트가 있지만 알림을받지 않으므로 여기에서는 중요하지 않음)가 많은 이벤트를 생성합니다.
  • 다른 유형의 알림이있을 것입니다 (사용자 A는 친구로 당신을 추가했습니다. 사용자 B는 프로필에 댓글을 달았습니다. 사용자 C는 이미지를 좋아했습니다. 사용자 D는 게임 X에서 당신을 때렸습니다 ...)
  • 대부분의 이벤트는 1 명의 사용자에 대해 1 개의 알림을 생성하지만 (사용자 X는 이미지를 좋아했습니다), 하나의 이벤트가 많은 알림을 생성하는 경우가 있습니다 (예 : 사용자 Y의 생일)
  • 알림은 함께 그룹화해야합니다. 예를 들어 일부 이미지와 같은 4 명의 다른 사용자가 해당 이미지의 소유자에게 4 개의 사용자가 이미지를 좋아하고 4 개의 별도의 알림이 아니라는 것을 나타내는 하나의 알림을 받아야합니다 (FB처럼)

내가 생각했던 것은 이벤트가 발생할 때 이벤트를 저장하는 일종의 큐를 만들어야한다는 것입니다. 그런 다음 배경 작업을 할 것입니다 ( gearman 해당 대기열을보고 해당 이벤트를 기반으로 알림을 생성 ?)이 있습니다. 그런 다음이 작업은 각 사용자에 대해 데이터베이스에 알림을 저장합니다 (따라서 이벤트가 10 명의 사용자에게 영향을주는 경우 10 개의 개별 알림이 있음). 그런 다음 사용자가 알림 목록이있는 페이지를 열면 그에 대한 모든 알림을 읽고 (100 개의 최신 알림으로 제한하려고 생각하는 경우) 그룹화 한 다음 마지막으로 표시합니다.

이 접근법에 관심이있는 것들 :

  • 지옥처럼 복잡한 :)
  • 데이터베이스가 여기에 가장 좋은 스토리지입니까 (MySQL을 사용하고 있습니다) 또는 다른 것을 사용해야합니까 (redis도 적합합니다)
  • 알림으로 무엇을 저장해야하나요? 사용자 ID, 이벤트를 시작한 사용자 ID, 이벤트 유형 (이벤트를 그룹화하고 적절한 텍스트를 표시 할 수 있도록)이지만 알림의 실제 데이터를 저장하는 방법을 모릅니다 (예 : 이미지의 URL 및 제목). 좋아했다). 알림을 생성 할 때 해당 정보를 "베이킹"해야하거나 영향을받는 레코드의 ID (이미지, 프로필 등)를 저장하고 알림을 표시 할 때 DB에서 정보를 가져와야합니다.
  • 알림 페이지를 표시 할 때 즉석에서 100 개의 알림을 처리해야하더라도 여기서 성능은 양호해야합니다.
  • 읽지 않은 알림 수를 사용자에게 표시해야하기 때문에 모든 요청에서 가능한 성능 문제 (알림을 그룹화하기 때문에 자체적으로 문제가 될 수 있음). 백그라운드에서 알림보기 (그룹화 된 위치)를 즉시 생성하지 않고 생성하면 피할 수 있습니다.

제안 된 솔루션과 우려 사항에 대해 어떻게 생각하십니까? 여기에 관련된 다른 언급이 필요하다고 생각되면 의견을 말하십시오.

아, 우리는 페이지에 PHP를 사용하고 있지만, 여기서 큰 요소는 아닙니다.


한 사람의 노력으로이 알림 시스템을 구축하는 데 시간이 얼마나 걸렸습니다. 나는 그에 따라 타임 라인을 만들 것으로 추정하고 싶습니다.
Shaharyar

@ Shaharyar 나는 그것이 알림 시스템의 복잡성에 달려 있다고 생각합니다.
tyan

우선 순위 기반 알림 시스템을 구축하기 위해 MySQL과 동일한 시스템을 사용했습니다. 좋은 점은 수천 명의 사용자로 확장되며, 그 이상으로 올라가면 특히 Android 및 GCM과 함께 폭발한다는 것입니다. 메시지 대기열, 기능의 종류를 자연스럽게 나타내는 redis, rabbitMQ, Kafka와 같은 MySQL의 대안을 알고 싶습니다.
Ankit Marothi

답변:


168

누군가 (행위자)에 의해 변경되고 (동사 = 추가, 요청 ..) 무언가 (객체 = 이벤트, 우정 ..)에 관한 알림은 사용자 (제목)에게보고됩니다. 다음은 표준화 된 데이터 구조입니다 (MongoDB를 사용했지만). 특정 사용자에게 변경 사항을 알려야합니다. 사용자 별 알림입니다. 100 명의 사용자가 참여한 경우 100 개의 알림을 생성합니다.

╔═════════════╗      ╔═══════════════════╗      ╔════════════════════╗
║notification ║      ║notification_object║      ║notification_change ║
╟─────────────╢      ╟───────────────────╢      ╟────────────────────╢
║ID           ║—1:n—→║ID                 ║—1:n—→║ID                  ║
║userID       ║      ║notificationID     ║      ║notificationObjectID║
╚═════════════╝      ║object             ║      ║verb                ║
                     ╚═══════════════════╝      ║actor               ║
                                                ╚════════════════════╝

(적합한 시간 필드를 추가하십시오)

기본적으로 개체 당 변경 사항을 그룹화하여 "친구 요청이 3 개 있습니다"라고 말할 수 있습니다. 액터별로 그룹화하는 것이 유용하므로 "James Bond 사용자가 침대를 변경했습니다"라고 말할 수 있습니다. 또한 원하는대로 알림을 번역하고 계산할 수 있습니다.

그러나 객체는 ID이므로 객체가 실제로 변경되고 해당 기록을 표시하지 않으려는 경우 별도의 호출로 원하는 객체에 대한 모든 추가 정보를 가져와야합니다 (예 : "사용자가 이벤트 제목을 ... ")

알림은 사이트의 사용자에게 실시간에 가깝기 때문에 변경 사항이 추가되면 모든 리스너에 대해 PHP를 업데이트하여 nodejs + websockets 클라이언트와 PHP를 연결합니다.


1
notification_object.object는 문자열 "friendship"과 같은 변경 유형을 식별합니다. 내가 이야기하는 추가 데이터가있는 변경된 오브젝트에 대한 실제 참조는 notification_change.notificationObjectID
Artjom Kurapov

2
이것은 멍청한 질문 일 수 있지만이 설정을 통해 사용자가 알림을 보거나 수행 한 후에는 무엇을합니까? 데이터베이스에서 데이터베이스를 제거하거나 날짜를 사용하여 알림이 작성된 후 사용자가 로그인했는지 확인합니까?
Jeffery Mills

4
나는이 주제가 이미 오래되었다는 것을 알고 있지만 첫 번째 테이블에 대해 약간 당황합니다.이 테이블의 목적은 정확히 무엇입니까? notification_object 테이블에 userID를 넣는 것과 비교하여 별도의 테이블로 사용하면 어떤 이점이 있습니까? 즉, 언제 알림에 새 항목을 작성하고 언제이 구조를 사용하여 오브젝트를 추가하고 기존 알림을 변경하게됩니까?
Bas Goossen

3
당신은 같은 상태 필드를 가질 수 @JefferyMills is_notification_readnotification테이블이있는 경우 적절하게 표시 unread, read또는 deleted.
Kevin

2
또한이 솔루션의 일부 측면을 이해하려고 애 쓰고 이에 대해 별도의 질문을했습니다. dba.stackexchange.com/questions/99401/…
user45623

27

이것은 실제로 추상적 인 질문이므로 수행해야 할 것과 수행하지 말아야 할 것을 지적하는 대신 논의해야 할 것 같습니다.

귀하의 우려에 대해 다음과 같이 생각합니다.

  • 예, 알림 시스템은 복잡하지만 지옥은 아닙니다. 이러한 시스템을 모델링하고 구현하는 데는 여러 가지 접근 방식이있을 수 있으며 중간 정도에서 높은 수준의 복잡성을 가질 수 있습니다.

  • Pesonally, 나는 항상 데이터베이스 중심의 물건을 만들려고 노력합니다. 왜? 진행중인 모든 것을 완벽하게 제어 할 수 있기 때문에 데이터베이스 관리 방식을 사용하지 않고도 제어 할 수 있습니다. 날 믿어, 당신은 그 사건을 통제하고 싶어 할거야.

  • 실제 사례를 예로 들어 어디에서든 시작할 수 있습니다. 작년에 나는 소셜 네트워크 (페이스 북이 아닌)에서 알림 시스템을 모델링하고 구현했습니다. 거기에 알림을 저장하는 데 사용한 방법은 무엇입니까? 나는 있었다 notifications나는 유지 테이블 generator_user_id(알림을 생성하는 사용자의 ID를)의 target_user_id(명백한의 종류, 그렇지?)를의 notification_type_id(통지 유형과 다른 테이블에 참조 있음), 모든 테이블에 필요한 정보 (타임 스탬프, 플래그 등) 내 notification_types테이블 notification_templates은 각 유형의 알림에 대한 특정 템플릿을 저장 한 테이블 과 관계가 있었습니다. 예를 들어, POST_REPLY템플릿 유형이 같은 유형이 {USER} HAS REPLIED ONE OF YOUR #POSTS있습니다. 거기에서 나는 방금{}변수 및 #참조 링크로;

  • 예, 성능은 해야 하고 있어야합니다 확인합니다. 알림을 생각할 때 서버가 머리에서 발끝으로 밀리는 것을 생각합니다. 아약스 요청이나 다른 작업으로 수행하려는 경우 성능에 대해 걱정해야합니다. 그러나 저는 이것이 두 번째로 우려되는 부분이라고 생각합니다.

물론 내가 디자인 한 모델은 여러분이 따를 수있는 유일한 모델이 아니며 최고도 아닙니다. 나는 적어도 내 대답이 올바른 방향으로 당신을 따르기를 바랍니다.


다른 데이터 저장소로 제어 할 수없는 이유는 무엇입니까?
Jan Hančič

글쎄, 나는 그렇게 말하지 않았다. 내가 말한 것은 데이터베이스 기반 접근 방식으로 만 데이터 제어를 보장 할 수 있다는 것입니다. 하지만 그건 나 뿐이야 나는 그것을 다시 말하겠습니다.
Daniel Ribeiro

@DanielRibeiro 알림 템플릿의 자리 표시 자 ({...})는 다른 종류의 알림에 대해 데이터베이스의 다른 테이블 집합에서 자리 표시 자의 데이터를 바꿔야합니다. 예를 들어 하나의 템플릿은 "{user} 님이 사진을 좋아했습니다."이고 다른 템플릿은 "귀하의 {Pagename}이 (가) 새로운 것입니다"입니다. 등 {PageName} 및 {user} 및 기타 자리 표시자는 다른 데이터베이스 테이블에서 매핑되므로 자리 표시 자 값을 동적으로 가져 오기위한 스키마는 무엇입니까?
Ashish Shukla

@Ashish Shukla에 의해 질문으로 DanielRibeiro 당신은 자리를 대체하는 방법
Shantaram TUPE

@AshishShukla 자리 표시자를 사용하거나 교체 했습니까?
Shantaram Tupe

8
╔════════════════════╗
║notification        ║
╟────────────────────╢
║Username            ║
║Object              ║
║verb                ║
║actor               ║
║isRead              ║
╚════════════════════╝

이것은 2 개의 컬렉션을 갖는 것이 아니라 좋은 답변입니다. 사용자 이름, 객체 및 isRead로 쿼리하여 새로운 이벤트를 얻을 수 있습니다 (예 : 보류중인 친구 요청 3 개, 질문 4 개 등).

이 스키마에 문제가 있는지 알려주십시오.


3
최고 답변은 정규화 된 데이터 구조를 사용했으며, 이는 테이블에 중복성이 없음을 의미합니다. 당신의 대답은 그렇게합니까?
Aaron Hall

4

나는 개인적으로 받아 들여진 대답에 대한 다이어그램을 잘 이해하지 못하므로 받아 들인 대답과 다른 페이지에서 배울 수있는 것을 기반으로 데이터베이스 다이어그램을 첨부 할 것입니다.

여기에 이미지 설명을 입력하십시오

개선은 잘 받았습니다.


message_template이 NotificationType 테이블에있는 것처럼 보입니다. 또한 main_url이 notifications 테이블에있는 것처럼 보이면 Notification_Message 테이블을 제거 할 수 있습니다. NotificationMessage 테이블이있는 이유를 설명 할 수 있습니까?
Jeff Ryan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.