成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我是如何用Redis做實時訂閱推送的

開發 架構 Redis
文中分別介紹了MQ、傳統定時任務以及Redis的SortSet隊列三種方案,一一分析可行性,并且最后給出了Redis的邏輯與部分代碼實現。

 前陣子開發了公司領劵中心的項目,這個項目是以 redis 作為關鍵技術落地的。

先說一下領劵中心的項目吧,這個項目就類似京東 app 的領劵中心,當然圖是截取京東的,公司的就不截了。。。

其中有一個功能叫做領劵的訂閱推送。

什么是領劵的訂閱推送?

就是用戶訂閱了該劵的推送,在可領取前的一分鐘就要把提醒信息推送到用戶的 app 中。

本來這個訂閱功能應該是消息中心那邊做的,但他們說這個短時間內做不了。所以讓我這個負責優惠劵的做了 -.-!。具體方案就是到具體的推送時間點了,coupon 系統調用消息中心的推送接口,把信息推送出去。

下們我們分析一下這個功能的業務情景。公司目前注冊用戶 6000W+,是哪家就不要打聽了。。。比如有一張無門檻的優惠劵下單立減 20 元,那么搶這張劵的人就會比較多,我們保守估計 10W+,百萬級別不好說。我們初定為 20W 萬人,那么這 20W 條推送信息要在一分鐘推送完成!并且一個用戶是可以訂閱多張劵的。所以我們知道了這個訂閱功能的有兩個突出的難點:

  1.  推送的實效性:推送慢了,用戶會抱怨沒有及時通知他們錯過了開搶時機。
  2.  推送的體量大:爆款的神劵,人人都想搶!

然而推送體量又會影響到推送的實效性。這真是一個讓人頭疼的問題!

那就讓我們把問題一個個解決掉吧!

推送的實效性的問題:當用戶在領劵中心訂閱了某個劵的領取提醒后,在后臺就會生成一條用戶的訂閱提醒記錄,里面記錄了在哪個時間點給用戶發送推送信息。所以問題就變成了系統如何快速實時選出哪些要推送的記錄!

方案 1:

MQ 的延遲投遞。MQ 雖然支持消息的延遲投遞但尺度太大 1s 5s 10s 30s 1m,用來做精確時間點投遞不行!并且用戶執行訂閱之后又取消訂閱的話,要把發出去的 MQ 消息 delete 掉這個操作有點頭大,短時間內難以落地!并且用戶可以取消之后再訂閱,這又涉及到去重的問題。所以 MQ 的方案否掉。

方案 2:

傳統定時任務。這個相對來說就簡單一點,用定時任務是去 db 里面 load 用戶的訂閱提醒記錄,從中選出當前可以推送的記錄。但有句話說得好任何脫離實際業務的設計都是耍流氓~。下面我們就分析一下傳統的定時任務到底適不適合我們的這個業務!

能否支持多機同時跑 一般不能,同一時刻只能單機跑。
存儲數據源 一般是 mysql 或者其它傳統數據庫,并且是單表存儲
頻率 支持秒、分、時、天,一般不能太快

綜上所述我們就知道了一般傳統的定時任務存在以下缺點:

  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 進行隊列數的動態配置。 

我們每次從隊列里面取多少條記錄也是可以動態配置的 

這樣就可以隨時根據實際的生產情況調整整個集群的吞吐量~。  所以我們的定時任務集群還是具有一個特性就是支持動態調整~。

最后一個關鍵組件就是負載均衡了。這個是非常重要的!因為這個做得不好就會可能導致多臺機競爭同時處理一個隊列,影響整個集群的效率!在時間很緊的情況下我就用了一個簡單實用的利用 redis 一個自增 key 然后 mod 隊列數量算法。這樣就很大程度上就保證不會有兩臺機器同時去競爭一條隊列~.

最后我們算一下整個集群的吞吐量

10(機器數) * 2000(一次拉取數) = 20000。然后以 MQ 的形式把消息推送到消息中心,發 MQ 是異步的,算上其它處理 0.5s。

其實發送 20W 的推送也就是 10 幾 s 的事情。

ok~ 到這里我們整個定時任務集群就差不多基本落地好了。如果你問我后面還有什么可以完善的話那就是:

  •  加監控, 集群怎么可以木有監控呢,萬一出問題有任務堆積怎么辦~
  •  加上可視化界面。
  •  最好有智能調度,增加任務優先級。優先級高的任務先運行嘛。
  •  資源調度,萬一機器數量不夠,力不從心,優先保證重要任務執行。

目前項目已上前線,運行平穩~。 

 

責任編輯:龐桂玉 來源: JAVA高級架構
相關推薦

2017-05-02 13:38:51

CSS繪制形狀

2015-04-14 09:31:10

AWSAWS PaaSSaaS可視化編排

2020-06-28 08:34:07

架構師阿里軟件

2018-08-10 14:57:03

UnixMySQL命令

2012-05-24 14:58:55

開源代碼

2021-07-06 10:03:05

軟件開發 技術

2017-05-02 20:56:36

機器學習HR簡歷

2014-12-23 14:14:54

2022-07-30 10:08:06

MQTT?協議物聯網

2017-04-11 17:22:57

編程程序員語言

2012-11-28 01:47:35

軟件測試測試

2021-06-09 10:15:26

優化性能顆粒度

2019-09-15 14:07:49

2022-02-20 19:02:16

RollupVue 2JavaScrip

2016-09-17 00:12:46

2021-06-22 15:06:13

Redis客戶端 Redis-clie

2015-08-10 14:56:31

Google

2020-04-21 08:30:32

AI人工智能語言

2023-05-10 09:04:10

promise場景業務

2013-01-10 12:57:23

產品經理App產品設計
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一级观看 | 欧美成人二区 | 国产7777 | 日韩一 | 国产精品久久久久一区二区三区 | 四虎永久在线精品免费一区二 | 亚洲免费精品 | 国产良家自拍 | 亚洲在线电影 | 亚洲视频一区在线 | 在线亚洲电影 | 国产美女一区二区 | 国产精品区二区三区日本 | 天堂网avav| 免费在线观看av片 | 天天干免费视频 | 色吧色综合 | 日本黄色一级视频 | 少妇午夜一级艳片欧美精品 | 国产成人免费 | 亚洲精彩免费视频 | 桃色五月| 亚洲巨乳自拍在线视频 | 毛片一级片 | 成人午夜精品一区二区三区 | 韩国电影久久 | 91在线看片| 成人不卡| 国产精品久久久久一区二区三区 | 欧美中文字幕一区二区三区 | 欧美成人免费 | 国产欧美在线 | 国产成人一区二区三区精 | 中文字幕99 | 天天躁日日躁狠狠躁2018小说 | 久久精品99国产精品 | 一区二区三区在线看 | 综合成人在线 | 操人网 | 久色 | 日本精品在线观看 |