效能之殤(六)-- 現代計算機最親密的夥伴:區域性性與樂觀
2018-11-19/ 閱讀數:2 / 分類:作業系統
馮·諾依曼架構中,指令和資料均儲存在記憶體中,徹底打開了計算機“通用”的大門。這個結構中,“線性陣列”記憶體天生攜帶了一個渦輪:區域性性。
區域性性分類
空間區域性性
空間區域性性是最容易理解的區域性性:如果一段記憶體被使用,那麼之後,離他最近的記憶體也最容易被使用,無論是資料還是指令都是這樣。舉一個淺顯易懂的例子:
迴圈處理一個 Array
時間區域性性
如果一個變數所在的記憶體被訪問過,那麼接下來這一段記憶體很可能被再次訪問,例子也非常簡單:
$a = []; if ( !$b ) { $a[] = $b; }
在一個function
內,一個記憶體地址很可能被訪問、修改多次。
樂觀
“樂觀”作為一種思考問題的方式廣泛存在於計算機中,從硬體設計、記憶體管理、應用軟體到資料庫均廣泛運用了這種思考方式,並給我們帶來了十分可觀的效能收益。
樂觀的 CPU
第一篇文章中的 L1 L2 L3 三級快取和第二篇文章中的分支預測與流水線,均是樂觀思想的代表。
樂觀的虛擬記憶體
虛擬記憶體依據計算機記憶體的區域性性,將磁碟作為記憶體的本體,將記憶體作為磁碟的快取,用很小的效能代價帶來了數十倍併發程序數,是樂觀思想的集大成者。
樂觀的快取
Java 經典面試題 LRU 快取實現,也是樂觀思想的一種表達。
同樣,鳥哥的ofollow,noindex" target="_blank">yac 也是這一思想的強烈體現。
設計 Yac 的經驗假設
- 對於一個應用來說, 同名的Cache鍵, 對應的Value, 大小几乎相當.
- 不同的鍵名的個數是有限的.
- Cache的讀的次數, 遠遠大於寫的次數.
- Cache不是資料庫, 即使Cache失效也不會帶來致命錯誤.
Yac 的限制
- key的長度最大不能超過48個字元. (我想這個應該是能滿足大家的需求的, 如果你非要用長Key, 可以MD5以後再存)
- Value的最大長度不能超過64M, 壓縮後的長度不能超過1M.
- 當記憶體不夠的時候, Yac會有比較明顯的踢出率, 所以如果要使用Yac, 那麼儘量多給點記憶體吧.
樂觀鎖
樂觀鎖在併發控制和資料庫設計裡都擁有重要地位,其本質就是在特定的需求下,假定不會衝突,衝突之後再浪費較長時間處理,比直接每次請求都浪費較短時間檢測,總體的效能高。樂觀鎖在演算法領域有著非常豐富而成熟的應用。
樂觀的分散式計算
分散式計算的核心思想就是樂觀,由 95% 可靠的 PC 機組成的分散式系統,起可靠性也不會達到 99.99%,但是絕大多數場景下,99% 的可靠性就夠了,畢竟拿 PC 機做分散式比小型機便宜得多嘛。下一篇文章我會詳細介紹分散式計算的效能之殤,此處不再贅述。
樂觀的代價
出來混,早晚是要還的。
樂觀給了我們很多的好處,總結起來就是一句話:以微小的效能損失換來大幅的效能提升。但是,人在河邊走,哪有不溼鞋。每一個 2015 年 6 月入 A 股的散戶,都覺得大盤還能再翻一番,豈不知一週之後,就是股災了。
樂觀的代價來自於“微小的效能損失”,就跟房貸市場中“微小的風險”一樣,當大環境小幅波動的時候,他確實能承擔壓力,穩住系統,但是怕就怕突然雪崩:
- 虛擬記憶體中的記憶體的區域性性突然大幅失效,磁碟讀寫速度成了記憶體讀寫速度,系統卡死
- 分散式資料庫的六臺機器中的 master 掛了,系統在一秒內選舉出了新的 master,你以為系統會穩定執行?master 掛掉的原因就是壓力過大,這樣就會導致新的 master 瞬間又被打掛,然後一臺一臺地繼續,服務徹底失效。例如:「故障說明」對六月六日 LeanCloud 多項服務發生中斷的說明