200,000명이 넘는 푸시 사용자가 어떻게 2단계 동시성을 달성할 수 있나요? 이 문서에서는 Redis가 실시간 구독 푸시를 구현하는 세 가지 방법, 즉 MQ, 기존 예약 작업 및 Redis의 SortSet 대기열을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
![실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의](https://img.php.cn/upload/article/000/000/024/605c06c4a015c653.jpg)
【관련 추천: Redis 동영상 튜토리얼】
얼마 전 회사 쿠폰 센터 프로젝트를 개발했는데 이 프로젝트는 redis를 핵심 기술로 구현했습니다.
먼저 쿠폰수집센터 프로젝트에 대해 이야기해보겠습니다. 이 프로젝트는 물론 JD.com 앱의 쿠폰수집센터와 유사합니다. 물론 사진은 회사의 것이 아닙니다. . .
![](/img/remote/1460000039677010)
![161664369845615실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의 실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의](https://img.php.cn/upload/image/649/743/657/161664369845615%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B5%AC%EB%8F%85%20%ED%91%B8%EC%8B%9C%EB%A5%BC%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%20%EC%9C%84%ED%95%9C%20Redis%EC%9D%98%20%EC%84%B8%20%EA%B0%80%EC%A7%80%20%EB%B0%A9%EB%B2%95%EC%97%90%20%EB%8C%80%ED%95%9C%20%EA%B0%84%EB%9E%B5%ED%95%9C%20%EB%85%BC%EC%9D%98)
쿠폰받기에는 구독푸시라는 기능이 있습니다.
쿠폰구독 푸시란?
사용자가 쿠폰 푸시 알림을 구독했다는 의미이며, 알림 정보는 쿠폰을 받기 1분 전에 사용자의 앱으로 푸시됩니다.
원래 이 구독 기능은 메시지센터에서 구현하기로 되어 있었는데 단시간에 구현할 수 없다고 하더군요. 그래서 쿠폰담당자가 해냈습니다-.-!. 구체적인 계획은 특정 푸시 시점에 도달하는 것입니다. 쿠폰 시스템은 메시지 센터의 푸시 인터페이스를 호출하여 정보를 푸시합니다.
이 기능의 비즈니스 시나리오를 분석해 보겠습니다. 회사에는 현재 6000W 이상의 등록 사용자가 있으므로 누구인지 묻지 마십시오. . . 예를 들어, 주문 시 20위안 즉시 할인을 제공하는 무제한 할인 쿠폰이 있다면 더 많은 사람들이 이 쿠폰을 갖게 될 것이며 보수적으로 추정하면 100,000+일 것이라고 말하기는 어렵습니다. 백만 위안. 초기 목표는 20만 명이므로 이 20만 개의 푸시 메시지가 1분 안에 푸시됩니다! 그리고 한 명의 사용자가 여러 쿠폰을 구독할 수 있습니다. 따라서 우리는 이 구독 기능에 두 가지 뛰어난 어려움이 있다는 것을 알고 있습니다.
그러나 푸시의 양은 푸시의 효율성에 영향을 미칩니다. 정말 머리가 아프네요!
그럼 하나씩 문제를 풀어보도록 할게요!
푸시 실효성 문제: 사용자가 쿠폰수집센터에서 쿠폰수집알림을 구독하면 사용자에게 푸시정보가 전송되는 시점을 기록하는 사용자의 구독알림 기록이 백그라운드에서 생성됩니다. . 따라서 문제는 시스템이 실시간으로 푸시할 레코드를 어떻게 신속하게 선택할 수 있는지에 관한 것입니다!
옵션 1:
MQ 배송이 지연되었습니다. MQ는 메시지 지연 전달을 지원하지만 그 규모가 1초 5초 10초 30초 1분으로 너무 커서 정확한 시점 전달에는 사용할 수 없습니다! 그리고 사용자가 구독을 실행한 후 구독을 취소하면 전송된 MQ 메시지를 삭제하는 작업이 다소 번거롭고 단시간에 구현하기 어렵습니다! 그리고 사용자는 취소한 후 구독할 수 있으며, 이 경우에도 중복 제거 문제가 발생합니다. 따라서 MQ의 계획은 거부됩니다.
옵션 2:
기존 예약 작업. 이는 비교적 간단합니다. 예약된 작업을 사용하려면 사용자의 구독 알림 레코드를 db에 로드하고 현재 푸시할 수 있는 레코드를 선택하세요. 하지만 잘 어울리는 속담이 있습니다. 실제 사업과 동떨어진 디자인은 모두 불량품입니다. 기존의 예약된 작업이 우리 비즈니스에 적합한지 분석해 보겠습니다. 동시에 실행되는 여러 컴퓨터를 지원할 수 있습니까? 일반적으로 동시에 단일 컴퓨터에서만 실행할 수 있습니다.
스토리지 데이터 소스 |
| 는 일반적으로 mysql 또는 기타 기존 데이터베이스이며 단일 테이블 스토리지입니다.
주파수 | 는 초, 분, 시간, 일을 지원하며 일반적으로 너무 빠르지는 않습니다 |
요약하자면, 기존의 예약된 작업에는 일반적으로 다음과 같은 단점이 있다는 것을 알고 있습니다.
1. 성능 병목 현상. 단 한 대의 머신에서만 처리하고 있어 많은 양의 데이터를 처리할 수 없습니다!
2. 효율성이 떨어집니다. 예약된 작업의 빈도는 너무 높아서는 안 됩니다. 너무 높으면 비즈니스 데이터베이스에 많은 부담을 줍니다.
3. 단일 실패 지점.
런닝 머신이 멈추면 전체 업무가 불가능합니다 -. - 이건 정말 끔찍한 일이에요! 따라서 기존의 예약된 작업은 이 비즈니스에 적합하지 않습니다. . . 그렇다면 우리는 어찌할 바를 모르는 걸까요? 사실은 아닙니다. 기존의 예약된 작업을 간단히 변환하면 됩니다! 동시에 여러 시스템에서 실행할 수 있는 예약된 작업 클러스터로 전환할 수 있으며 효율성은 두 번째 수준까지 정확하고 단일 실패 지점을 거부할 수 있습니다! 이를 위해서는 강력한 Redis의 도움이 필요합니다.
옵션 3:
예약된 작업 클러스터 먼저 예약된 작업 클러스터가 해결해야 하는 세 가지 문제를 정의해야 합니다!
1. 효율성이 높아야 합니다
2. 처리량이 커야 합니다
3. 서비스가 안정적이어야 하며 단일 장애 지점이 없어야 합니다. 예약된 작업 클러스터.
![161664392982223실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의 실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의](https://img.php.cn/upload/image/681/243/439/161664392982223%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B5%AC%EB%8F%85%20%ED%91%B8%EC%8B%9C%EB%A5%BC%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%20%EC%9C%84%ED%95%9C%20Redis%EC%9D%98%20%EC%84%B8%20%EA%B0%80%EC%A7%80%20%EB%B0%A9%EB%B2%95%EC%97%90%20%EB%8C%80%ED%95%9C%20%EA%B0%84%EB%9E%B5%ED%95%9C%20%EB%85%BC%EC%9D%98)
아키텍처는 매우 간단합니다. Redis 클러스터의 sortedSet 대기열에 사용자의 구독 푸시 기록을 저장하고 알림 타임스탬프를 점수 값으로 사용한 다음 다음을 사용하여 각 비즈니스 서버에 타이머를 설정합니다. 두 번째 수준의 빈도, 내 설정은 1s이고 로드 밸런싱 후 푸시할 사용자 레코드를 대기열에서 가져와 푸시합니다. 다음으로 다음 아키텍처를 분석합니다.
1. 성능: 대역폭 및 기타 요소를 제외하면 기본적으로 머신 수와 선형적으로 관련됩니다. 머신 수가 많을수록 처리량이 많아집니다. 머신 수가 적으면 상대적인 처리량이 감소합니다.
2. 효과: 2단계로 개선되었으며, 효과는 인정됩니다.
3. 단일 실패 지점? 존재하지 않습니다! Redis 클러스터나 모든 서버가 다운되지 않는 한. . . .
redis를 사용하는 이유에 대한 분석은 다음과 같습니다.
첫째, redis는 MySQL보다 성능이 훨씬 좋고, 지속성을 지원하며 안정성이 좋은 고성능 스토리지 DB로 활용 가능합니다.
두 번째 redis SortedSet 대기열은 자연스럽게 시간 기반 정렬을 조건으로 지원하므로 푸시할 레코드를 선택하는 데 있어 완벽하게 만족합니다.
알겠습니다~ 이제 계획이 가능해졌으니 어떻게 하루 안에 실행할 수 있을까요? 네, 이 계획을 설계하고 기본 코딩을 완료하는 데 하루밖에 걸리지 않았습니다. . . 시간이 너무 늦었거든요.
먼저 user_id를 키로 사용한 다음 대기열 번호 해시를 redis SortedSet 대기열로 수정합니다. 왜 그럴까요? 사용자가 두 개의 쿠폰을 동시에 구독하고 푸시 시간이 매우 가까우면 두 개의 푸시가 하나로 병합될 수 있고~ 해시가 상대적으로 균일하기 때문입니다. 다음은 코드 일부의 스크린샷입니다.
![161664396164468실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의 실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의](https://img.php.cn/upload/image/200/643/330/161664396164468%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B5%AC%EB%8F%85%20%ED%91%B8%EC%8B%9C%EB%A5%BC%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%20%EC%9C%84%ED%95%9C%20Redis%EC%9D%98%20%EC%84%B8%20%EA%B0%80%EC%A7%80%20%EB%B0%A9%EB%B2%95%EC%97%90%20%EB%8C%80%ED%95%9C%20%EA%B0%84%EB%9E%B5%ED%95%9C%20%EB%85%BC%EC%9D%98)
그런 다음 대기열 수를 결정해야 합니다. 일반적으로 처리 서버 수만큼 대기열을 정의합니다. 대기열이 너무 적으면 대기열 경쟁이 발생할 수 있으므로 너무 많으면 레코드가 적시에 처리되지 않을 수 있습니다. 그러나 가장 좋은 방법은 대기열 수를 동적으로 구성할 수 있다는 것입니다. 온라인 클러스터 시스템의 수가 자주 변경되기 때문입니다.
대규모 프로모션 때 기계를 더 추가할 예정이죠? 그리고 사업 규모가 커지면 기계 수도 늘어나겠죠~? 그래서 타오바오의 다이아몬드를 빌려 대기열 수를 동적으로 구성했습니다.
![161664397035289실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의 실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의](https://img.php.cn/upload/image/932/450/191/161664397035289%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B5%AC%EB%8F%85%20%ED%91%B8%EC%8B%9C%EB%A5%BC%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%20%EC%9C%84%ED%95%9C%20Redis%EC%9D%98%20%EC%84%B8%20%EA%B0%80%EC%A7%80%20%EB%B0%A9%EB%B2%95%EC%97%90%20%EB%8C%80%ED%95%9C%20%EA%B0%84%EB%9E%B5%ED%95%9C%20%EB%85%BC%EC%9D%98)
매번 대기열에서 가져오는 레코드 수도 동적으로 구성할 수 있습니다.
![161664401628364실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의 실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의](https://img.php.cn/upload/image/358/181/541/161664401628364%EC%8B%A4%EC%8B%9C%EA%B0%84%20%EA%B5%AC%EB%8F%85%20%ED%91%B8%EC%8B%9C%EB%A5%BC%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%20%EC%9C%84%ED%95%9C%20Redis%EC%9D%98%20%EC%84%B8%20%EA%B0%80%EC%A7%80%20%EB%B0%A9%EB%B2%95%EC%97%90%20%EB%8C%80%ED%95%9C%20%EA%B0%84%EB%9E%B5%ED%95%9C%20%EB%85%BC%EC%9D%98)
이러한 방식으로 전체 클러스터의 처리량은 실제 생산 상황에 따라 언제든지 조정할 수 있습니다~. 따라서 예약된 작업 클러스터에는 여전히 동적 조정을 지원하는 기능이 있습니다~. 마지막 핵심 구성요소는 로드 밸런싱입니다. 이것은 매우 중요합니다!
이 작업이 제대로 수행되지 않으면 여러 시스템이 동시에 대기열을 처리하기 위해 경쟁하게 되어 전체 클러스터의 효율성에 영향을 미칠 수 있기 때문입니다! 시간이 매우 부족할 때 redis를 사용하여 키를 자동으로 증가시킨 다음 대기열 수를 수정하는 간단하고 실용적인 알고리즘을 사용했습니다. 이렇게 하면 두 대의 기계가 동시에 대기열을 두고 경쟁하지 않게 됩니다~.
![1616643983585300.png 실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의](https://img.php.cn/upload/image/491/407/899/1616643983585300.png)
더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 비디오를 방문하세요! !
위 내용은 실시간 구독 푸시를 구현하기 위한 Redis의 세 가지 방법에 대한 간략한 논의의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!