【開卷有益】記錄一次高並發下的死結解決思考過程,開卷有益思考
開卷有益,好久沒寫部落格了,最近工作也挺忙的。
死結距離我不遙遠,終於還是在高並發時被我碰到了。
DeadLock Found!
儘管編程風格中會盡量避免死結,但是還是被我碰上了。文章可能看不出來我在做什麼事情,只是記錄自己的一個排除死結的過程。
事情起源於兩個聯動的緩衝+redis+非同步資料庫讀寫操作。
事務中的這句出現死結:
DELETE FROM table WHERE FROM key = ‘helloworld’
當初的思考解除死結的思路如下:
1)分析死結模型,假設1,2 兩個線程,假設A,B兩個鎖,通俗的說 :
1持有A鎖,等待B鎖 -- 2 持有B鎖,等待A鎖
於是掐這了,就癱了。
2)繼續思考,要真這麼簡單,也不好意思稱自己工程師了,實際開發中都是碰到死結環。什麼意思呢?繼續假設
1持有A,等B,
2持有B,等C,
3持有C,等A
Anyway,讀者可以自己假設還有4,5,6,7...
3)繼續思考,死結出現,第一步肯定是重審自己的代碼,這個時候一定要對使用的成熟的工具優先保持自信但要保留質疑的態度,怎麼重審,記錄我的過程
a,我們說代碼越簡潔,越不容易出錯,所以,秉著DRY原則,也要消除重複的代碼,能複用就絕對不看著行數而自得。
b,重構過後,一定是要資料層,邏輯層分離,不要在資料層包含邏輯處理,不要在邏輯層去做資料層做的事情。(這個時候會發現,腦中有設計模式思想和沒有這個 概念的人是有很大區別的)
c,迴歸正題,我代碼中的死結出現是高並發環境,存在熱點區,在重構過代碼後,肯定要對熱點資料進行預先處理,才進行非同步寫入資料庫。什麼是熱點區?我自己亂 叫的一個名字,就是很多時候,日誌也好,外來資料也好,很多時候會出現300ms以內出現100條99%相似度的資料。
d,繼續測試。發現死結依舊,立即建立新的緩衝,判斷到底哪裡出了問題。發現,邏輯並沒有問題。
e,持著質疑工具的態度,檢索使用的工具,高並發發生在非同步讀寫資料庫,那麼既然邏輯沒有問題,讀寫中操作的資料就不會有問題,那就是資料庫這裡的鎖機制出 了問題。閱讀資料庫鎖機制文檔,發現了事務操作中的頁面鎖和記錄鎖出了問題。
f,問題來了,既然是多線程,高並發,就不可能不讓事務持有記錄鎖和頁面鎖,此時怎麼辦?
解決辦法,放棄依據索引刪除,更新,改用主鍵進行刪除更新操作。
g,測試,正常。
整個過程,看了很多文檔,其中,最有用的:
http://hedengcheng.com/?p=844
文章寫完,覺得自己寫的挺扯的,好久沒寫文章了,出來冒個泡泡,表示自己還在。
後續腦袋清醒的時候要做一個高並發的專題,也算對自己這一段工作的總結。同時也會翻譯一篇看到的高並發的國外文章。
This is my word.