用 Redis 輕鬆實現秒殺系統的構思

秒殺系統的架構設計

秒殺系統,是典型的短時大量突發訪問類問題。對這類問題,有三種優化性能的思路:linux

1. 寫入內存而不是寫入硬盤、算法

2. 異步處理而不是同步處理、sql

3. 分佈式處理緩存

用上這三招,不論秒殺時負載多大,都能輕鬆應對。更好的是,Redis可以知足上述三點。所以,用Redis就能輕鬆實現秒殺系統。 用我這個方案,不管是電商平臺特價秒殺,12306火車票秒殺,都不是事:)性能優化

下面介紹一下爲何上述三種性能優化思路可以解決秒殺系統的性能問題:服務器

  • 寫入內存而不是寫入硬盤 傳統硬盤的讀寫性能是至關差的。SSD硬盤比傳統硬盤快100倍。而內存又比SSD硬盤快10倍以上。所以,寫入內存而不是寫入硬盤,就能使系統的能力提高上千倍。也就是說,原來你的秒殺系統可能須要1000臺服務器支撐,如今1臺服務器就能夠扛住了。 你可能會有這樣的疑問:寫入內存而不是持久化,那麼若是此時計算機宕機了,那麼寫入的數據不就所有丟失了嗎?若是你就這麼倒黴碰到服務器宕機,那你就沒秒到了,有什麼大不了? 最後,後面真正處理秒殺訂單時,咱們會把信息持久化到硬盤中。所以不會丟失關鍵數據。 Redis是一個緩存系統,數據寫入內存後就返回給客戶端了,可以支持這個特性。
  • 異步處理而不是同步處理 像秒殺這樣短時大併發的系統,在性能負載上有一個明顯的波峯和長期的波谷。爲了應對至關短期的大併發而準備大量服務器來應對,在經濟上是至關不合算的。 所以,對付秒殺類需求,就應該化同步爲異步。用戶請求寫入內存後馬上返回。後臺啓動多個線程從內存池中異步讀取數據,進行處理。如用戶請求多是1秒鐘內進入的,系統實際處理完成可能花30分鐘。那麼一臺服務器在異步狀況下其處理能力大於同步狀況下1800多倍! 異步處理,一般用MQ(消息隊列)來實現。Redis能夠看做是一個高性能的MQ。由於它的數據讀寫都發生在內存中。
  • 分佈式處理 好吧。也許你的客戶不少,秒殺系統即便用了上面兩招,仍是捉襟見肘。不要緊,咱們還有大招:分佈式處理。若是一臺服務器撐不住秒殺系統,那麼就多用幾臺服務器。10臺不行,就上100臺。分佈式處理,就是把海量用戶的請求分散到多個服務器上。通常使用hash實現均勻分佈。 這類系統在大數據雲計算時代的今天已經有不少了。無非是用Paxos算法和Hash Ring實現的。 Redis Cluster正是這樣一個分佈式的產品。

使用Redis實現描述系統

Redis和Redis Cluster(分佈式版本),是一個分佈式緩存系統。其支持多種數據結構,也支持MQ。Redis在性能上作了大量優化。所以使用Redis或者Redis Cluster就能夠輕鬆實現一個強大的秒殺系統。 基本上,你用Redis的這些命令就能夠了。 RPUSH key value 插入秒殺請求網絡

當插入的秒殺請求數達到上限時,中止全部後續插入。 後臺啓動多個工做線程,使用 LPOP key 讀取秒殺成功者的用戶id,進行後續處理。 或者使用LRANGE key start end命令讀取秒殺成功者的用戶id,進行後續處理。 每完成一條秒殺記錄的處理,就執行INCR key_num。一旦全部庫存處理完畢,就結束該商品的本次秒殺,關閉工做線程,也再也不接收秒殺請求。數據結構

要是還撐不住,該怎麼辦

也許你會說,咱們的客戶不少。即便部署了Redis Cluster,仍然撐不住。那該怎麼辦呢? 記得某個偉人曾經說過:辦法總比困難多!架構

下面,咱們具體分析下,還有哪些狀況會壓垮咱們架構在Redis(Cluster)上的秒殺系統。併發

腳本攻擊

如如今有不少搶火車票的軟件。它們會自動發起http請求。一個客戶端一秒會發起不少次請求。若是有不少用戶使用了這樣的軟件,就可能會直接把咱們的交換機給壓垮了。

這個問題其實屬於網絡問題的範疇,和咱們的秒殺系統不在一個層面上。所以不該該由咱們來解決。不少交換機都有防止一個源IP發起過多請求的功能。開源軟件也有很多能實現這點。如linux上的TC能夠控制。流行的Web服務器Nginx(它也能夠看作是一個七層軟交換機)也能夠經過配置作到這一點。一個IP,一秒鐘我就容許你訪問我2次,其餘軟件包直接給你丟了,你還能壓垮我嗎?

交換機撐不住了

可能大家的客戶併發訪問量實在太大了,交換機都撐不住了。 這也有辦法。咱們能夠用多個交換機爲咱們的秒殺系統服務。 原理就是DNS能夠對一個域名返回多個IP,而且對不一樣的源IP,同一個域名返回不一樣的IP。如網通用戶訪問,就返回一個網通機房的IP;電信用戶訪問,就返回一個電信機房的IP。也就是用CDN了! 咱們能夠部署多臺交換機爲不一樣的用戶服務。 用戶經過這些交換機訪問後面數據中心的Redis Cluster進行秒殺做業。

總結

有了Redis Cluster的幫助,作個支持海量用戶的秒殺系統其實So Easy! 這裏介紹的方案雖然是針對秒殺系統的,但其背後的原理對其餘高併發系統同樣有效。 最後,咱們再重溫一下高性能系統的優化原則: 寫入內存而不是寫入硬盤、異步處理而不是同步處理、分佈式處理。

羣內提供免費的Java架構學習資料,QQ羣:643459718 (裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼, MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)

相關文章
相關標籤/搜索