學會用數據說話-分布式鎖究竟可以多少並發?


程序員萌萌在瀏覽關於分布式鎖的文章,突然下面的話引起了萌萌的注意:
 
 
 

在鎖操作的客戶端打日志

獲取鎖:

T13:31:51.230redisname-lock:hsetnx

E13:31:51.230GetConnection10.X.X.X

T13:31:51.231redisname-lock:hsetnx

設置超時時間:

T13:31:51.230redisname-lock:hsetnx

E13:31:51.230GetConnection10.X.X.X

T13:31:51.231redisname-lock:hsetnx

釋放鎖:

T13:31:51.230redisname-unlock:hsetnx

E13:31:51.230GetConnection10.X.X.X

T13:31:51.231redisname-unlock:hsetnx

從上面數據可以看到一個正常分布式鎖操作,操作時間在1ms,因為是從客戶端獲取的,因為粒度只能是毫秒級。再從服務端看看是什么情況。

 
 

上面顯示了大於1ms的慢查詢情況,可以看到每秒幾百個的QPS不會造成分布式鎖本身的慢查詢。耗時超過1ms的都是集群操作,分布式鎖的lock和unlock操作時間都是us級。

    如果lock和unlock中間沒有任何邏輯的理想情況下,同一個鎖可以支持每秒:

   1000ms/ (1ms的lock+1ms的設置超時+1ms的unlock)=333(個)

結論

分布式鎖本身lock和unlock耗時是us級,在理想情況下大概可支持每秒1000個原子操作,300多個從分配到釋放流程結束。

 

舉個栗子🌰:

秒殺場景下,秒殺的產品有1000件。如果使用了分布式鎖,理想情況下可以在1m內處理完所有的秒殺成功請求,其他請求直接返回秒殺結束。

既然秒殺都沒有問題,一般情況下,分布式鎖不會是性能瓶頸。如果出現了性能問題,首先先排查業務邏輯。

 

目錄

1:一個線程里lock成功,unlock失敗?

2:有哪些抓手可以確定哪些邏輯耗時太多?

3:鎖內部要避免的操作有哪些?

4:循環獲取鎖的時間間隔怎么算合理?

5:獲取鎖重試次數怎么算合理?

6:多次獲取鎖失敗原因有哪些?

7:加了分布式鎖還出現了並發問題?

1:一個線程里lock成功,unlock失敗?

Q: 日志里報了多次的unlock失敗,什么原因?

A: 之前的代碼里try finally模式的unlock,是否lock成功都會unlock。

Q:加上了lock成功才unlock,還是有unlock失敗?

A:這是鎖住的邏輯耗時太多,超過了expire的時間,自動釋放鎖了。

2:有哪些抓手可以確定哪些邏輯耗時太多?

Q: 日志可以嗎?

A: 目前的日志可以找到有問題的traceId,看整個鏈路都進行了哪些處理,大概幾步時間消耗,但是具體sql的耗時分析沒有

Q:CAT監控可以嗎?

A:CAT監控可以找到耗時多的幾個請求,看到每條sql的耗時情況,超過5秒的sql都是需要注意的

3:鎖內部要避免的操作有哪些?

Q:邏輯上的?

A:避免顯式的和隱式的循環。如:.stream().

Q:性能上的?

A:數據查詢的條件是否建立了索引

4:循環獲取鎖的時間間隔怎么算合理?

A:獲取鎖與服務器通訊時間可以忽略不計,在跨機房的情況下理論上也不超過2ms

所以鎖可以獲取到的時間=一段分布式鎖中間執行時間平均值

5:獲取鎖重試次數怎么算合理?

A:獲取鎖的重試次數理論上如果獲取鎖時間間隔合理的話,就與允許的同時擴容最大容器數接近,不大於最大容器數20%。

6:多次獲取鎖失敗原因有哪些?

A:如果不符合可獲取到的時間間隔計算,則考慮是否特定場景下有耗時操作。具體可參考 3:鎖內部要避免的操作有哪些?

7:加了分布式鎖還出現了並發問題?

Q:鎖獲取失敗是怎么處理的?

A:鎖獲取失敗並沒有按請求失敗處理,而是在無鎖狀態下繼續執行會引發並發問題。

Q:鎖獲取成功了還是出現並發問題?

A:執行太慢了,超過了expire的時間鎖失效了。

 

 

簡介:

一個有邏輯、有觀點、有溫度、有調性的技術公眾號~

作者是一個有日本東京、美國硅谷工作經驗,有百項技術發明專利,十一年程序媛。

歡迎一起探索技術~

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM