高併發性能提高和超賣的解決方案

背景介紹:
       對於一個互聯網平臺來講,高併發是常常會遇到的場景。最有表明性的好比秒殺和搶購。高併發會出現三個特色:
   一、高併發讀取
   二、高併發寫入(一致性)
   三、出現超賣問題
      如何有效的解決這三個問題是應對高併發的關鍵。
通常系統都分爲前端和後端。
前端如何應對?
一、緩存靜態數據,例如圖片,html頁面,js等
二、搭建負載均衡集羣,目前採用較多的爲nginx
三、進行ip限制,限制同一個ip單位時間內發起的請求數量。或者創建ip黑名單,避免惡意攻擊
四、考慮系統降級。好比當達到系統負載的時候返回一個靜態處理頁面
後端如何應對?
一、採用mysql讀寫分離,可是當高併發的時候mysql性能會下降。 通常來講,MySQL的處理性能會隨着併發thread上升而上升,可是到了必定的併發度以後會出現明顯的拐點,以後一路降低,最終甚至會比單thread的性能還要差。好比加減庫存的操做,一般併發量不高的作法爲:update xxx set count=count-xx where curcount>xx;這樣能夠充分利用mysql的事務鎖來避免出現超賣的狀況。可是併發量上了後,會由於排他鎖等待而大大下降性能。
二、採用redis數據庫,前置到mysql。思路以下:
      2.1系統啓動後,初始化sku信息到redis數據庫,記錄其可用量和鎖定量
      2.2使用樂觀鎖,採用redis的watch機制。邏輯爲:
           1.定義門票號變量,設置初始值爲0。watchkey
           2.watch該變量,watch(watchkey);
           3.使用redis事務加減庫存。首先獲取可用量和搶購量比較,若是curcount>buycount,那麼正常執行減庫存和加鎖定量操做:
               multi;
               redis incr watchkey;
               redis decrby curcount buycount;
               redis incrby  lockcount buycount;
               exec;
     因爲上述操做都在事務內進行,一旦watchkey被其餘的事務修改過,那麼exec將返回nil,如此就放棄本次請求。通常都是在循環中重複嘗試直到成功或沒有可用量。
     最後經過訂單信息流,保證mysql數據庫的最終一致性。
三、其餘方式但願你們補充!
相關文章
相關標籤/搜索