請求一下子太多了,資料庫危

七淅在學Java發表於2022-06-27

大家好,我是七淅(xī)。

如標題所說,和大家分享一個我曾優化過的業務場景。

當然,具體業務細節不重要,重要的是優化的思路。如果大家以後有遇到類似特點的場景,能夠想到七淅這篇優化文章,那我就覺得很值了。

接下來我就直接進入主題,要分享得優化思路就是請求合併

弱弱說一句,由於優化效果特別明顯,這一優化我直接寫到簡歷上了。

之前面試有不少面試官都會來問我是怎麼做的,你看這不就給我機會發揮了嗎?所以大家懂的,有合適場景記得用起來,以後面試也和麵試官談笑風生。

1. 什麼是請求合併

首先說明一下,這並不是什麼高階的優化方式,不難,樸實無華,但有用。

如字面意思,就是(把多個)請求合併(成一個請求去處理)。

現在含義你知道了,現在我們看下文章標題:「請求一下子太多了,資料庫危」

聰明的你是不是已經猜到七淅要怎麼優化了?

2. 業務背景

我有一個推送業務,會把每次推送記錄都存到 MongoDB 中。

PS:不用在意是 MongoDB 哈,可能有的讀者可能沒接觸過,沒關係。反正它也是一個資料庫,就算換成 MySQL,優化一樣適用哈

而推送業務一個非常常見的場景就是定時傳送訊息給使用者,所以到點之後對應的每秒寫請求就特別高。

當初我這邊是有 8000 的每秒寫入量,後面通過請求合併優化到每秒寫 500。

3. 優化實現

現在問題來了,具體怎麼實現的呢?

理清有 3 個小點就好了,我們順著思路理一下:

1、首先,既然我們需要把多個請求合成一個,是不是需要有一個地方把這多個請求給存起來?

存資料的話,是不是就可以用資料庫、快取、佇列了。如下圖:

好了,現在資料存起來了,不可能一直存著吧,一直存著不處理,豈不是就是不處理請求了,那這肯定不對。

2、所以我們是不是就需要知道,什麼時候要處理存起來的資料?

「什麼時候」—— 用定時任務每隔多久取出來處理是不是就可以,或者當存夠多少資料量的時候,我們就集中處理。

我這裡的業務是用的定時任務來做的,那關於定時任務的實現也有多種方式。

我這裡是用的定時執行緒池,每隔 xx 秒,取 500 個請求進行處理。這裡你發現沒有,優化後的效果就是每秒寫 500,這個 500 就是這裡每次取得請求量來的。

所以說,優化效果要多少的處理量都是我們自己決定的。當然了,因為請求總量是不變得,所以每秒處理量越少,對應處理時間就越長。具體是什麼數字,這個就看具體業務啦

3、最後一點,多個請求存起來了,也知道什麼時機去處理,那這個「處理」是怎麼處理呢?

答案很簡單,把多個單次操作換成批量操作。比如資料庫批量插入,redis 的 mset。

以上 3 點,給大家整理個流程圖:

4. 適用場景

最後,上面得優化姿勢學廢后,那什麼業務場景可以用呢?

其實這個你想想,請求合併後的效果是怎樣的,差不多也就知道了。

一開始說含義:(把多個)請求合併(成一個請求去處理)

這樣的效果說明業務允許請求可以不用馬上處理,高階用語就是資料實時性要求不高 —— 這是第一個業務場景特點

第二個特點:「請求合併」,業務得有一定的併發場景才有機會給你合併呀。不然你說每分鐘才幾個請求,那這不是合了個寂寞嗎?(狗頭)

5. 文末休息區(求關注)

其實很多優化方式都是樸實無華的,第一次聽說時候可能會覺得牛蛙牛蛙,但實際接觸瞭解後,會發現其實也沒多高階。

不過,高階的優化方式肯定也是有的。就像我也很好奇,阿里京東這種億級秒殺,微博的粉絲關係,抖音的推薦等等是怎麼實現的。
倘若哪天真的有實際參與的大佬和我說,無非就是堆機器,沒什麼特別的,那我真的會尬住,哈哈哈哈。

如果覺得文章不錯,歡迎關注我的公眾號:七淅在學Java

相關文章