高併發系統中的常見問題


    本文一共分析了三個案例,分別介紹併發系統中的共享資源併發訪問、計算型密集型任務緩存訪問 、單一熱點資源峯值流量問題和解決方案。


Q1:訂票系,某車次只有一火車票,假定有1w我的同打開12306網站來票,如何解決並發問題前端

A1: 首先介紹數據庫層面的併發訪問,解決的辦法主要是樂觀鎖和悲觀鎖。sql

樂觀鎖數據庫

假設不會發生併發衝突,只在提交操做時檢查是否違反數據完整性。緩存

樂觀鎖使用一個自增的字段表示數據的版本號(或者timestamp),更新的時候檢查版本號是否一致,好比數據庫中版本號爲4,更新時版本號使用版本號version=5,與數據庫中的版本號version+1=(5)作比較,若是相等,則能夠更新,若是不相等,其餘程序已更新該記錄,返回錯誤。微信

觀鎖網絡

假定會發生併發衝突,屏蔽一切可能違反數據完整行的操做。併發

通常須要使用數據庫的鎖機制,好比MysqlInnoDB引擎的行級鎖。分佈式

結論:在實際生產環境中,若是併發量不大且不容許髒讀(原始數據爲5,AB兩個事務,B其餘事務更新數據爲2,事務未提交時,A讀取到的仍然爲5),可使用悲觀鎖。併發訪問量大時,使用悲觀鎖有很是大的性能問題,能夠選擇樂觀鎖。性能

其次,介紹一下Memcached的CAS機制網站

CAS,又稱Compare-and-Swap,表明一種原子操做。

Memcached的CAS機制解決的問題及其原理:

1. 實現了Check-and-Set原子操做功能;
2. 其使用方式爲:首先使用gets指令一個key-value及key對應value的版本號;其次操做產生新的value值;最後使用cas指令從新提交key-value,並附帶剛剛得到到的版本號;
3. 當服務端判斷cas操做中的版本號不是最新的時,則認爲改key的值已經被修改,本次cas操做失敗。程序設計人員經過CAS機制可實現自增和自減的原子操做;

能夠看到MemCache的CAS機制和數據庫的樂觀鎖實現原理很是相似。

 

Q2:假設系統中圖片存儲在TFS(Taobao File System)中,接口提供縮略圖服務,首先在緩存中查找是否有縮略圖,若是沒有,則從TFS加載原圖片,而後請求縮略圖服務,縮略圖計算完成後,設置回緩存服務中。

遇到的問題:當一張圖片分享給100w我的之後,同一時間有1w個併發請求,因爲縮略圖計算耗時較長(假設1s), 在這1s內,每一個請求查詢緩存都沒有找到而後申請計算縮略圖,致使重複的縮略圖計算量和資源消耗。

  

A2: 對於縮略圖這種耗時的服務,很是適合使用緩存,不過在使用的時候,對於同一個圖片,原則上只須要計算一次縮略圖,在縮略圖未計算完成時,能夠對每張圖片作 額外的標記表示其正在Processing,併發請求遇到縮略圖Processing時,能夠等待縮略圖計算完成(這是建議的方式)後從緩存直接讀取,也 能夠是直接返回錯誤,經過客戶端重試來解決。

     本案例中,若是縮略圖請求在上傳圖片1分鐘後才發生,則能夠在後臺預先計算縮略圖並存儲到緩存。另外就是在上傳圖片的時候計算縮略圖,不過會增長上傳圖片的時間。

 

Q3:單點峯值流量,在併發系統中,除了請求總體的併發量高,還常見單一熱點資源的併發請求量很高。例如,1萬我的每人分享了一張圖片,其中9999張圖片的縮略圖請求在10 QPS之內,剩下的一張圖片爲新聞熱點圖片,峯值請求在10萬QPS左右, 系統會遇到的容量問題包括:1)接口前端機容量不夠;2)緩存資源單實例遇到瓶頸。

A3:針對單點峯值流量可能遇到的性能瓶頸,解決方案以下。

1)接口層容量不夠:這個問題比較簡單,只要接口層設計是無狀態的,當容量達到預警線,能夠經過快速水平擴容解決。

2)緩存資源單實例遇到性能瓶頸:若是使用的是分佈式緩存,當但願突破單一key的訪問瓶頸時(這個瓶頸既有多是CPU資源緊張,也有多是單機網絡帶寬跑滿,還有多是磁盤IO吞吐不夠),一個辦法是分佈式緩存作多副本(x3)冗餘設計,這樣系統的吞吐量(x3)能夠提升3倍,不過成本也提升3倍。另一個辦法是針對極熱點數據,除了分佈式緩存,同時在前端機上打開localCache,依靠數量衆多的前端機來抗極熱點請求。


        純ad:歡迎你們關注微信公衆號:neihanrukou 

相關文章
相關標籤/搜索