聊聊并發(fā)編程兩原則,你明白了嗎?
之前寫過一篇文章, 并發(fā)編程的核心技術(shù) – 多版本(Multi Versioning), 本文繼續(xù)對并發(fā)編程做一次更全面的總結(jié), 這樣的總結(jié)并非具體的編程指導(dǎo), 而概括性的理論, 是筆記性質(zhì)的.
根據(jù)經(jīng)驗總結(jié), 并發(fā)編程的指導(dǎo)思想可以總結(jié)為兩個原則, 也即并發(fā)編程兩原則:
- Sharding/Partitioning
- Leveling
Sharding
Sharding 技術(shù)常見于分布式系統(tǒng), 如果我舉一個編程技巧里常用的技術(shù), 估計你會比較熟悉 - 哈希鎖. 例如 Java 語言里的 ConcurrentHashMap, 內(nèi)部就是把整個容器分成獨立的多個分段, 每個分段對應(yīng)一把鎖. 或者某些 KV 數(shù)據(jù)庫, 預(yù)先分配若干個鎖到數(shù)組中, 然后把每一個 key 根據(jù) hash 算法對應(yīng)不同的鎖上面, 當需要對 key 加鎖時, 加的是對應(yīng)的那把鎖, 兩個 key 概率上可以同時加鎖(并發(fā)).
分布式系統(tǒng)的核心之一就是 Sharding, 我曾經(jīng)說過"無 Sharding, 不分布式", 指出沒有嚴謹 Sharding 機制的多副本系統(tǒng)是偽分布式, 即使是所謂的強一致性多副本系統(tǒng), 如無 Sharding 便是"偽分布式". Sharding 也是計算機科學(xué)領(lǐng)域核心思想之一的分而治之思想.
所以, 如果你遇到因為鎖粒度太大導(dǎo)致多個并發(fā)操作相互阻塞的問題, 最直接的解決方案就是分析細化和拆分資源(做 Sharding), 不同的資源對應(yīng)不同的鎖, 這樣就解決了阻塞問題. 一些初學(xué)者非常害怕和排斥鎖, 我覺得沒有必要. 程序的本質(zhì)是串行化, 是鎖, 我們能做的無非是: 減小鎖粒度.
Sharding 是一種豎直分拆, 分拆出來的每一個 Shard 都是完全獨立的(shared-nothing). 這一點和接下來要提到的 Leveling 在空間上剛好垂直.
Leveling
Leveling 是一種水平分拆, 也叫 Layering(多層級). 在數(shù)據(jù)庫領(lǐng)域, 它也叫 Multi Versioning(MVCC). 和 Photoshop 里作圖類似, Leveling 包含多個 Level(層), 將不同的層級進行疊加(Merge), 最終形成一個統(tǒng)一的輸出對象.
和 Photoshop 類似, 我們可以獨立地操作每一個層, 如果需要加鎖, 那就加在層上面, 因此, 也達到了減小鎖粒度的效果. 看到了吧? 并發(fā)編程的唯一指導(dǎo)思想就是減小鎖粒度. 妄圖完全消除鎖, 將在指導(dǎo)思想上發(fā)生根本錯誤.
Leveling 和 Sharding 技術(shù)的區(qū)別, 就在于它們?nèi)绾螌ν庹宫F(xiàn). Leveling 需要將所有層進行合并, 才能輸出結(jié)果. 而 Sharding 技術(shù)中的每一個 Shard, 可以獨立地輸出結(jié)果. 顯然, 在這一點上 Sharding 技術(shù)要優(yōu)于 Leveling. 既然 Sharding 更優(yōu), 為什么還需要 Leveling 呢? 因為, 事物并不總是可以做 Sharding, 有時候你做不了 Sharding.
單點標記
單點標記不是并發(fā)編程的核心原則, 而是 Leveling 技術(shù)的常見優(yōu)化手段. 我們知道, Leveling 技術(shù)需要合并(Merge)操作, 合并操作可能成本較大, 這時, 我們需要把結(jié)果進行緩存. 但緩存和原始的層是同等地位的, 可能出現(xiàn)所謂的不一致(不相同)的問題, 所以, 需要引入一個單點標記, 對兩者是否一致進行確認(check point, commit point), 就好像把兩個子節(jié)點掛到了同一個父節(jié)點之下.
另外, 合并操作涉及很多算法, 某些算法不需要緩存, 僅僅是從多層(多個節(jié)點)之中選出一個 Winner, 以該 Winner 作為輸出結(jié)果. 這時, 單點標記就是輸出結(jié)果的指針, 指向 Winner.
總結(jié)
總結(jié)出簡潔的基礎(chǔ)理論, 對我們的工作有什么幫助呢? 我認為, 一是可以幫助我們記憶, 二是掌握了基礎(chǔ)理論之后, 可以隨時推導(dǎo)出已有的大量紛紜復(fù)雜的技術(shù), 不至于被亂花迷了眼.
另外, 并發(fā)編程和分布式系統(tǒng)本質(zhì)上如此相似, 后面我將寫一些文章, 用同樣的基礎(chǔ)理論對分布式系統(tǒng)進行分析.