[分佈式性能] 秒殺

秒殺的流程

“秒殺”其實是商家為了促銷,使用非常低的價格銷售商品,比如,1 元賣 iPhone,100 臺,於是來了一百萬人搶購。我們把技術挑戰放在一邊,先從用戶或是產品的角度來看一下,秒殺的流程是什麼樣的。首先,你需要一個秒殺的 landing page,在這個秒殺頁上有一個倒計時的按鈕。一旦這個倒計時的時間到了,按鈕就被點亮,讓你可以點擊按鈕下單。一般來說下單時需要你填寫一個校驗碼,以防止是機器來搶。從技術上來說,這個倒計時按鈕上的時間和按鈕可以被點擊的時間是需要後臺服務器來校準的,這意味著:前端頁面要不斷地向後端來請求,開沒開始,開沒開始……每次詢問的時候,後端都會給前端一個時間,以校準前端的時間。一旦後端服務器表示 OK 可以開始,後端服務會返回一個 URL。這個 URL 會被安置在那個按鈕上,就可以點擊了。點擊後,如果搶到了庫存,就進入支付頁面,如果沒有則返回秒殺已結束。這個不斷輪詢的過程,就好像大家等著搶。你想想,有 100 萬人來不停地詢問有沒有開始了這個事,估計後端也扛不住。

秒殺的技術挑戰

接下來,我們需要來看一下“秒殺”的技術挑戰。面對上面我們要解決的技術問題,我們的技術上的挑戰就是怎麼應對這 100 萬人同時下單請求?100 萬的同時併發會導致我們的網站瞬間就崩潰了,一方面是 100 萬人同時請求,我們的網絡帶寬不夠,另一方面是理論上來說要扛 100 萬的 TPS,需要非常多的機器。但是最恐怖的是,所有的請求都會集中在同一條數據庫記錄上,無論是怎麼分庫分表,還是使用了分佈式數據庫都無濟於事,因為你面對的是單條的熱點數據。這幾乎是一件無法解決的技術問題。

秒殺的解決方案

很明顯,要讓 100 萬用戶能夠在同一時間打開一個頁面,這個時候,我們就需要用到 CDN 了。數據中心肯定是扛不住的,所以,我們要引入 CDN。

在 CDN 上,這 100 萬個用戶就會被幾十個甚至上百個 CDN 的邊緣結點給分擔了,於是就能夠扛得住。然後,我們還需要在這些 CDN 結點上做點小文章。

一方面,我們需要把小服務部署到 CDN 結點上去,這樣,當前端頁面來問開沒開始時,這個小服務除了告訴前端開沒開始外,它還可以統計下有多少人在線。每個小服務會把當前在線等待秒殺的人數每隔一段時間就回傳給我們的數據中心,於是我們就知道全網總共在線的人數有多少。

假設,我們知道有大約 100 萬的人在線等著搶,那麼,在我們快要開始的時候,由數據中心向各個部署在 CDN 結點上的小服務上傳遞一個概率值,比如說是 0.02%

於是,當秒殺開始的時候,這 100 萬用戶都在點下單按鈕,首先他們請求到的是 CDN 上的這些服務,這些小服務按照 0.02% 的量把用戶放到後面的數據中心,也就是 1 萬個人放過去兩個,剩下的 9998 個都直接返回秒殺已結束。

於是,100 萬用戶被放過了 0.02% 的用戶,也就是 200 個左右,而這 200 個人在數據中心搶那 100 個 iPhone,也就是 200 TPS,這個併發量怎麼都應該能扛住了。

這就是整個“秒殺”的技術細節,是不是有點不敢相信?

說到這裡,我相信你一定會問我 12306 和奧運會搶票的問題。我覺得 2008 年奧運會搶票把服務器搶掛了是可以使用秒殺這個解決方案的。而 12306 則不行,因為他們完全不知道用戶來是要買哪張火車票的。不知道這個信息,很不好過濾用戶,而且用戶在買票前需要有很多查詢操作,然後在查詢中選擇自己的車票。

對此,12306 最好的應對方式,除了不要一次把所有的票放出來,而是分批在不同的時間段把票放出來,這樣可以讓人們不要集中在一個時間點來搶票,做到人肉分流,可以降低一些併發度。

另外,我一直覺得,12306 最好是用預售的方式,讓大家把自己的購票先輸入到系統中。系統並不真正放票,而是把大家的需求都收集好,然後做整體統籌安排,該增加車次的增加車次,該加車廂的加車廂,這樣可以確保大家都能走。實在不行,那就抽籤了。

更多的思考

我們可以看到,解決秒殺這種特定業務場景,可以使用 CDN 的邊緣結點來扛流量,然後過濾用戶請求(限流用戶請求),來保護數據中心的系統,這樣才讓整個秒殺得以順利進行

那麼,如果我們像雙 11 那樣,想盡可能多地賣出商品,那麼就不像秒殺了。這是要儘可能多地收訂單,但又不能超過庫存,其中還有大量的銀行支付,各大倉庫的庫存查詢和分配,這些都是非常慢的操作。為了保證一致性,還要能夠扛得住像雙 11 這樣的大規模併發訪問,那麼,應該怎麼做呢?

使用秒殺這樣的解決方案基本上不太科學了。這個時候就需要認認真真地做高併發的架構和測試了,需要各個系統把自己的性能調整上去,還要小心地做性能規劃,更要把分佈式的彈力設計做好,最後是要不停地做性能測試,找到整個架構的系統瓶頸,然後不斷地做水平擴展,以解決大規模的併發。

但是,從另一方面來說,像我們用邊緣結點來解決秒殺這樣的場景的玩法,是否也有一定的普適性?這裡,我想說,一定是有的。

但是,從另一方面來說,像我們用邊緣結點來解決秒殺這樣的場景的玩法,是否也有一定的普適性?這裡,我想說,一定是有的。

我覺得,隨著請求量越來越大,數據也越來越多,數據中心是有點到瓶頸了,而需要邊緣結點來幫忙了。而且,這個邊緣化解決方案的趨勢也會越來越有優勢。

[分佈式性能] 秒殺


分享到:


相關文章: