나는 우리의 페이지 (소셜 게임 타입)를위한 페이스 북 스타일 알림 시스템을 구축하기 시작했고 이제 그러한 시스템을 디자인하는 가장 좋은 방법이 무엇인지 연구하고있다. 사용자에게 알림을 보내는 방법에 관심이 없습니다 (현재조차도). 서버에 시스템을 구축하는 방법 (알림 저장 방법, 저장 위치, 가져 오는 방법 등)을 연구 중입니다.
그래서 … 우리가 가지고있는 몇 가지 요구 사항 :
- 성수기에는 약 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를 사용하고 있지만, 여기서 큰 요소는 아닙니다.
답변
누군가 (행위자)에 의해 변경되고 (동사 = 추가, 요청 ..) 무언가 (객체 = 이벤트, 우정 ..)에 관한 알림은 사용자 (제목)에게보고됩니다. 다음은 표준화 된 데이터 구조입니다 (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를 연결합니다.
답변
이것은 실제로 추상적 인 질문이므로 수행해야 할 것과 수행하지 말아야 할 것을 지적하는 대신 논의해야 할 것 같습니다.
귀하의 우려에 대해 다음과 같이 생각합니다.
-
예, 알림 시스템은 복잡하지만 지옥은 아닙니다. 이러한 시스템을 모델링하고 구현하는 데는 여러 가지 접근 방식이있을 수 있으며 중간 정도에서 높은 수준의 복잡성을 가질 수 있습니다.
-
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
있습니다. 거기에서 나는 방금{}
변수 및#
참조 링크로; -
예, 성능은 해야 하고 있어야합니다 확인합니다. 알림을 생각할 때 서버가 머리에서 발끝으로 밀리는 것을 생각합니다. 아약스 요청이나 다른 작업으로 수행하려는 경우 성능에 대해 걱정해야합니다. 그러나 저는 이것이 두 번째로 우려되는 부분이라고 생각합니다.
물론 내가 디자인 한 모델은 여러분이 따를 수있는 유일한 모델이 아니며 최고도 아닙니다. 나는 적어도 내 대답이 올바른 방향으로 당신을 따르기를 바랍니다.
답변
╔════════════════════╗
║notification ║
╟────────────────────╢
║Username ║
║Object ║
║verb ║
║actor ║
║isRead ║
╚════════════════════╝
이것은 2 개의 컬렉션을 갖는 것이 아니라 좋은 답변입니다. 사용자 이름, 객체 및 isRead로 쿼리하여 새로운 이벤트를 얻을 수 있습니다 (예 : 보류중인 친구 요청 3 개, 질문 4 개 등).
이 스키마에 문제가 있는지 알려주십시오.
