QCon 2017分享總結——分散式系統設計的幾點思考
在QCon2017的基礎設施專場,筆者以表格存儲[1]為基礎分享了分散式系統設計的幾點考慮,主要是擴展性、可用性和性能。每個點都舉了一個具體的例子來闡述。這裡對這次分享做一次簡單的總結,細節見文後slice。
首先,說到了表格存儲產生的背景。
上面介紹,大規模、弱關係數據,對靈活schema變動的需求,傳統資料庫無法很好的滿足,NOSQL的出現是一個很好的補充。NOSQL不是為了取代SQL,也無法取代SQL,是已有資料庫生態的很好補充。我認為未來會出現更多種類的資料庫,面向不同的業務,使用不同的硬體,資料庫市場將迎來更多的成員。
下面描述了表格存儲的功能、生態、架構以及數據模型,有了這些基礎才能更好的理解後面的內容,比如面向公共雲服務的產品和面向企業內部的產品在架構設計的時候會有不同的權衡。
下面介紹分散式系統第一個要素,擴展性。擴展性是個很廣泛的話題,我們只討論系統能否儘快的利用更多的機器資源。很多分散式系統都有分區的概念(Partition, Segment, Range ...),分區就是將單體切割為多個子單位,這樣才有可能利用多個物理機器。但是何時切割、如何切割、切割後怎麼辦都是值得討論的問題。下面討論的是其中一個子問題,就是如何切割。
熟悉HBase的同學知道,HBase在一次分裂之後,需要做Compaction才能繼續分裂,而Compaction時間持續可能數個小時,也就意味著數個小時內無法進一步分裂從而分擔讀寫壓力。表格存儲支持連續分裂,也就是1個分區分裂成2個後,可以立刻繼續分裂。那麼,為什麼表格存儲要支持連續分裂呢?主要原因在於公有雲多租戶服務和企業內自用產品的不同。對於表格存儲而言,用戶點點滑鼠就可以開通,業務訪問隨時可能大幅上漲,用戶不會提前告訴我們,即使告訴了我們也沒那麼多人隨時響應。而訪問量上漲有很大的可能導致分區內訪問熱點,這些熱點會導致延時上漲或者訪問錯誤,需要系統能夠快速的處理,否則就要賠錢。這時候系統必須具備連續分裂的能力,1個分裂成2個,2個分裂成4個... 。HBase更多的是作為一個軟體,在企業內部由專門的DBA獨立運維。而在企業內部,業務一般可以預期,很難出現運維不期望的巨量上升,所以對於HBase而言,連續分裂的必要性就降低了。這個不同,看似技術的不同,實際則是用戶不同、產品形態不同帶來的的不同選擇。
再介紹分散式系統第二個要素,可用性。可用性就更是一個關乎全局的話題,全鏈路上任何一點風吹草動都可能影響可用性。我們這裡將可用性的討論局限在硬體故障,局限在機器down這個很小的層面上。眾所周知,分散式系統能夠自主應對少部分機器down而不需要任何人工干預(如果不是,那一定是假分散式系統),以儘可能的減少因為機器down而產生的服務中斷問題。此時,不同的系統有不同的設計抉擇,服務中斷時間各不相同,作為用戶會希望服務中斷時間越短越好。
我們這裡以谷歌的BigTable以及開源的HBase為例來介紹。谷歌BigTable和開源HBase都採用在worker層聚合日誌以提高性能。這個思路很好理解,就是將多個分區的日誌聚合在一起,寫入文件系統中,這樣就能減少文件系統的IOPS,提高性能。但是,這對可用性是個很大的傷害,因為一旦機器發生down機,日誌文件需要被讀出來按照分區進行分割,這些分割完的日誌文件再被相應的分區replay,然後相應分區才能提供服務。顯然,上面這個過程會使得機器down時分區不可用的時間變長(想想看誰來分割日誌呢?這是否會成為瓶頸?)。如果考慮到全集群重啟,或者交換機down導致較多機器失聯,那麼其對可用性的影響將十分可觀。這裡是一個可用性和性能的權衡,表格存儲在設計之初,是選擇了可用性的,也就是每個分區有獨立的日誌文件,以降低在機器failover場景下不可服務時間。但是這是否意味著性能的下降?是的,但是我們相信可用性優先順序更高,而性能總會被解決,後來我們也找到了非常不錯的辦法,見下面描述。
本節討論分散式系統設計的第三個問題,性能。性能總是能讓程序員熱血沸騰,吭哧吭哧碼了那麼多代碼,如果性能有了顯著的提升,真是讓人十分開心的事情。前面說,為了可用性,我們放棄了性能,難道就一直忍受嗎?作為有骨氣的程序員,顯然是不能接受的。現在難題是必須在不傷害可用性的前提下,提高性能。其實說到性能,有兩個基本的招數,就是聚合和拆分,然而在哪裡聚,在哪裡拆是一個設計的抉擇。
如上圖所示,就是聚合時機選擇的問題。BigTable和HBase的核心思想是聚合以減少IOPS,從而提高性能;那麼聚合是否一定要做在table server這一層做呢?是否可以下推做到分散式文件系統層?結論是當然可以,而且效果更好,受益方更多。具體架構見附件裡面的說明,我們通過將聚合下推到文件系統、RPC層小包聚合、Pipeline傳輸等大幅改進了性能,在可用性和性能之間取得了很好的平衡。當然,隨著硬體的演進,未來可能磁碟控制器就把聚合做好了,上面的應用都不需要關心,這樣受益方就更多了。
至此,我們聊到了分散式系統的擴展性、可用性和性能,並以實際的例子進行了分析。下面就介紹一個表格存儲的特性,PK串列自增列,在消息推送、分散式ID生成、Feed系統中非常有用。這是一個很好地例子,來展示作為一個平台,如何向用戶學習。附件中給出了PK自增列用於消息推送系統的例子,這方面我們寫過不少文章,見[3][4]。
以上就是分享的核心內容,大多是筆者的一些實踐總結,沒有上升到理論高度,難免有一定的片面性,歡迎探討。表格存儲釘釘交流群:搜索群號11789671加入,群名是「表格存儲公開交流群」。目前表格存儲引擎組在北京、杭州均有團隊,我們也在努力尋找KV存儲/SQL引擎優化人才,歡迎討論。
[1]. 表格存儲:https://www.aliyun.com/product/ots
[2]. QCon 2017資料: http://ppt.geekbang.org/qconsh2017
[3]. 高並發IM架構:https://yq.aliyun.com/articles/66461[4]. 打造千萬級Feed流系統:https://yq.aliyun.com/articles/224132
[5]. 演講PPT下載:http://ppt.geekbang.org/slide/show/1122 (QCon)或https://yq.aliyun.com/attachment/download/?spm=5176.100239.blogcont238951.6.Rr7vD3&id=4523 (雲棲)推薦閱讀:
※[跟吉姆一起讀LevelDB]2.LSM Tree與leveldb::DB::Open操作(1)
※redis4.0、codis、阿里雲redis 3種redis集群對比分析
※B+樹並發協議
※怎樣操作leveldb資料庫,實現增刪改查?
※終於等到你——MySQL 5.7與PostgreSQL 9.6的百萬QPS大比拼