레디 스 실시간 가입을 수행하는 방법의 강한 푸시로 탄생

최근이 회사는이 프로젝트의 핵심 레디 스 착륙으로 기술을 기반으로, 프로젝트 쿠폰 센터를받을 개발했다.
프로젝트가 그것의 쿠폰 센터를지도에 대해 나에게 이야기하자,이 프로젝트는 물론, 회사가 종료되지 않은 그림 Jingdong의 차단은 유사한 유가 증권 센터 Jingdong 응용 프로그램을 받게됩니다. . .
레디 스 실시간 가입을 수행하는 방법의 강한 푸시로 탄생

其中有一个功能叫做领劵的订阅推送。什么是领劵的订阅推送?就是用户订阅了该劵的推送,在可领取前的一分钟就要把提醒信息推送到用户的app中。本来这个订阅功能应该是消息中心那边做的,但他们说这个短时间内做不了。所以让我这个负责优惠劵的做了-.-!。具体方案就是到具体的推送时间点了,coupon系统调用消息中心的推送接口,把信息推送出去。
下面我们分析一下这个功能的业务情景。公司目前注册用户6000W+,是哪家就不要打听了。。。比如有一张无门槛的优惠劵下单立减20元,那么抢这张劵的人就会比较多,我们保守估计10W+,百万级别不好说。我们初定为20W万人,那么这20W条推送信息要在一分钟推送完成!并且一个用户是可以订阅多张劵的。所以我们知道了这个订阅功能的有两个突出的难点:
1、推送的实效性:推送慢了,用户会抱怨没有及时通知他们错过了开抢时机。
2、推送的体量大:爆款的神劵,人人都想抢!
然而推送体量又会影响到推送的实效性。这真是一个让人头疼的问题!
那就让我们把问题一个个解决掉吧!
推送的实效性的问题:当用户在领劵中心订阅了某个劵的领取提醒后,在后台就会生成一条用户的订阅提醒记录,里面记录了在哪个时间点给用户发送推送信息。所以问题就变成了系统如何快速实时选出哪些要推送的记录!
方案1:MQ的延迟投递。MQ虽然支持消息的延迟投递但尺度太大1s 5s 10s 30s 1m,用来做精确时间点投递不行!并且用户执行订阅之后又取消订阅的话,要把发出去的MQ消息delete掉这个操作有点头大,短时间内难以落地!并且用户可以取消之后再订阅,这又涉及到去重的问题。所以MQ的方案否掉。
方案2:传统定时任务。这个相对来说就简单一点,用定时任务是去db里面load用户的订阅提醒记录,从中选出当前可以推送的记录。但有句话说得好任何脱离实际业务的设计都是耍流氓~。下面我们就分析一下传统的定时任务到底适不适合我们的这个业务!

레디 스 실시간 가입을 수행하는 방법의 강한 푸시로 탄생

综上所述我们就知道了一般传统的定时任务存在以下缺点:

1、性能瓶颈。只有一台机在处理,在大体量数据面前力不从心!
2、实效性差。定时任务的频率不能太高,太高会业务数据库造成很大的压力!
3、单点故障。万一跑的那台机挂了,那整个业务不可用了-。- 这是一个很可怕的事情!
所以传统定时任务也不太适合这个业务。。。
那我们是不是就束手无策了呢?其实不是的! 我们只要对传统的定时任务做一个简单的改造!就可以把它变成可以同时多机跑,并且实效性可以精确到秒级,并且拒绝单点故障的定时任务集群!这其中就要借助我们的强大的redis了。
方案3:定时任务集群
首先我们要定义定时任务集群要解决的三个问题!
1、实效性要高
2、吞吐量要大
3、服务要稳定,不能有单点故障
下面是整个定时任务集群的架构图。
레디 스 실시간 가입을 수행하는 방법의 강한 푸시로 탄생

架构很简单:我们把用户的订阅推送记录存储到redis集群的sortedSet队列里面,并且以提醒用户提醒时间戳作为score值,然后在我们个每业务server里面起一个定时器频率是秒级,我的设定就是1s,然后经过负载均衡之后从某个队列里面获取要推送的用户记录进行推送。下面我们分析以下这个架构
1、性能:除去带宽等其它因素,基本与机器数成线性相关。机器数量越多吞吐量越大,机器数量少时相对的吞吐量就减少。
2、实效性:提高到了秒级,效果还可以接受。
3、单点故障?不存在的!除非redis集群或者所有server全挂了。。。。
这里解析一下为什么用redis?
第一redis 可以作为一个高性能的存储db,性能要比MySQL好很多,并且支持持久化,稳定性好。
第二redis SortedSet队列天然支持以时间作为条件排序,完美满足我们选出要推送的记录。
ok~既然方案已经有了那如何在一天时间内把这个方案落地呢?是的我设计出这个方案到基本编码完成,时间就是一天。。。因为时间太赶鸟。
首先我们以user_id作为key,然后mod队列数hash到redis SortedSet队列里面。为什么要这样呢,因为如果用户同时订阅了两张劵并且推送时间很近,这样的两条推送就可以合并成一条~,并且这样hash也相对均匀。下面是部分代码的截图:
레디 스 실시간 가입을 수행하는 방법의 강한 푸시로 탄생

然后要决定队列的数量,一般正常来说我们有多少台处理的服务器就定义多少条队列。因为队列太少,会造成队列竞争,太多可能会导致记录得不到及时处理。
然而最佳实践是队列数量应该是可动态配置化的,因为线上的集群机器数是会经常变的。大促的时候我们会加机器是不是,并且业务量增长了,机器数也是会增加是不是~。所以我是借用了淘宝的diamond进行队列数的动态配置。
레디 스 실시간 가입을 수행하는 방법의 강한 푸시로 탄생

때마다 우리는 많은 레코드를 동적으로 내부 대기열을 구성하는 방법을 취할
레디 스 실시간 가입을 수행하는 방법의 강한 푸시로 탄생

이는 전체 클러스터의 처리량을 조정할 수 있습니다 - 실제 생산을 기반으로. 그래서 ~ 우리는 일정한 직업을 가지고 또는 클러스터 기능은 동적 조정을위한 지원입니다.
마지막 핵심 구성 요소는로드 밸런싱입니다. 이것은 매우 중요합니다! 이것은 여러 컴퓨터가 동시에 큐 경쟁을 처리하기로 이어질 수 잘 될 것이기 때문에, 전체 클러스터의 효율성에 영향을 미칠! 아주 꽉 시간의 경우에는 내가 자동 증가 숫자 키를 누른 다음 모드 큐 알고리즘 레디 스 간단하고 실용성을 사용했다. 이것은 크게 동시에 두 개의 기계 ~ 큐를 위해 경쟁 할 것을 보장합니다.

레디 스 실시간 가입을 수행하는 방법의 강한 푸시로 탄생
마지막으로, 우리는 전체 클러스터의 처리량 계산
(10) (기계 번호) * 2000 (끌어 오기 수) = 20,000. 그런 다음, 메시지 센터에 MQ 푸시 메시지의 형태는 머리 MQ 비동기 다른 처리 수가 0.5 초이다.
사실, 푸시는 몇 가지의 20W (10)의 전송됩니다.
좋아 ~ 여기 우리는 기본 바닥보다 거의 전체 클러스터 일반 작업이다. 완벽한 아무것도 그 후 당신이 저를 요구하는 경우에, 다음은 :
1, 플러스 모니터링, 작업 ~ 쌓아 수행하는 방법에 문제가있는 경우, 나무가 할 수있는 방법을 모니터링 클러스터
2, 플러스 시각적 인터페이스.
(3)는 바람직하게 지능형 스케줄링, 태스크 우선 순위를 증가. 우선 순위가 높은 작업은 일을 실행합니다.
4, 자원 스케줄링, 기계, 힘의 수가 충분하지가 수행하는 중요한 작업을 보장에 우선 순위를 부여합니다.
프로젝트 ~, 원활한 운영 최전선에있다.

나는 찬양처럼 지원에 대한 감사를 문서 포인트를 기억!

추천

출처blog.51cto.com/14442094/2423482