設計數據密集型應用-Data-Intensive Application

不懂數據庫的全棧工程師不是好架構師 —— Vonng

週六停更 Spring Boot 從入門到實踐系列教程

讀一本好書《設計數據密集型應用》- Designing Data-Intensive Application

簡稱:DDIA

在正確的時候讀一本合適的書是一種幸運~

  • 作者: Martin Kleppmann
  • 原書名稱:《Designing Data-Intensive Application》
  • 譯者:馮若航
  • Gitbook地址:https://legacy.gitbook.com/book/vonng/ddia-cn/details(需要科學上網)
  • 建議使用Typora或Gitbook以獲取最佳閱讀體驗。
設計數據密集型應用-Data-Intensive Application

這本書的作者是少有的從工業界幹到學術界的牛人,知識面廣得驚人,也善於舉一反三,知識之間互相關聯,比如有個地方把讀路徑比作programming language的lazy evaluation而寫路徑比作eager evaluation,令人拍案。這一本數囊括了幾乎所有數據處理相關工作中可能遇到了的內容,而且也有非常棒的實操經驗。比如書的一開始,作者反覆強調監控中分位數的作用,可以揭示一些被平均數掩蓋的事實,我也正好有一個監控從都是監控平均值變成主要監控若干p99分位數的經歷,看到這裡,不由得掩卷嘆息。

這本書循循善誘的寫作手法應該是相當高超了,講解得非常深入淺出,一般照著提出問題 -> 解決方案 -> 這個方案的長處短處 -> 發散到其它方案這個模式講解,看起來可以說是不知不覺,非常輕鬆,也沒有有些作者的拽文習慣,幾乎全部是中學詞彙,句子也不復雜,保證非英語母語的人可以流暢閱讀,這點可以說是非常良心了。

作者在最後一小節還討論了大數據的倫理問題,儘管現實世界中,金錢利益面前,可能無人理會這些事情,但是這些夫子自道,還是很體現作者情懷。我覺得這是昇華整本書的地方。

每一個數據工程師和產品經理都應該把最後一節,Doing the right thing,讀十遍。

為了說服大家為什麼值得讀十遍,我摘抄幾句:

automated systems can systematically and arbitrarily exclude a person from participating in society without any proof of guilt, and with little chance of appeal

machine learning is like money laundering for bias

when services become good at predicting what content users want to see, they may end up showing people only opinions they already agree with, leading to echo chambers in which stereotypes, misinformation, and polarization can breed

Data is the pollution problem (as in Industrial Revolution) of the information age

作者最後說:

we should stop regarding users as metrics to be optimized, and remember that they are humans who deserve respect, dignity and agency.

做一個有情懷的工程師當如是啊!

內容簡介

1第一部分 數據系統的基石

本書前四章介紹了數據系統底層的基礎概念,無論是在單臺機器上運行的單點數據系統,還是分佈在多臺機器上的分佈式數據系統都適用。

  1. 第一章將介紹本書使用的術語和方法。可靠性,可擴展性和可維護性 ,這些詞彙到底意味著什麼?如何實現這些目標?
  2. 第二章將對幾種不同的數據模型和查詢語言進行比較。從程序員的角度看,這是數據庫之間最明顯的區別。不同的數據模型適用於不同的應用場景。
  3. 第三章將深入存儲引擎內部,研究數據庫如何在磁盤上擺放數據。不同的存儲引擎針對不同的負載進行優化,選擇合適的存儲引擎對系統性能有巨大影響。
  4. 第四章將對幾種不同的 數據編碼進行比較。特別研究了這些格式在應用需求經常變化、模式需要隨時間演變的環境中表現如何。

2第二部分: 分佈式數據

在本書的第一部分中,我們討論了數據系統的各個方面,但僅限於數據存儲在單臺機器上的情況。現在我們到了第二部分,進入更高的層次,並提出一個問題:如果多臺機器參與數據的存儲和檢索,會發生什麼?

你可能會出於各種各樣的原因,希望將數據庫分佈到多臺機器上:

可擴展性

如果你的數據量、讀取負載、寫入負載超出單臺機器的處理能力,可以將負載分散到多臺計算機上。

容錯/高可用性

如果你的應用需要在單臺機器(或多臺機器,網絡或整個數據中心)出現故障的情況下仍然能繼續工作,則可使用多臺機器,以提供冗餘。一臺故障時,另一臺可以接管。

延遲

如果在世界各地都有用戶,你也許會考慮在全球範圍部署多個服務器,從而每個用戶可以從地理上最近的數據中心獲取服務,避免了等待網絡數據包穿越半個世界。

擴展至更高的載荷

如果你需要的只是擴展至更高的載荷(load),最簡單的方法就是購買更強大的機器(有時稱為垂直擴展(vertical scaling)或向上擴展(scale up))。許多處理器,內存和磁盤可以在同一個操作系統下相互連接,快速的相互連接允許任意處理器訪問內存或磁盤的任意部分。在這種共享內存架構(shared-memory architecture)中,所有的組件都可以看作一臺單獨的機器。

i. 在大型機中,儘管任意處理器都可以訪問內存的任意部分,但總有一些內存區域與一些處理器更接近(稱為非均勻內存訪問(nonuniform memory access, NUMA)。 為了有效利用這種架構特性,需要對處理進行細分,以便每個處理器主要訪問臨近的內存,這意味著即使表面上看起來只有一臺機器在運行,分區(partitioning)仍然是必要的。

共享內存方法的問題在於,成本增長速度快於線性增長:一臺有著雙倍處理器數量,雙倍內存大小,雙倍磁盤容量的機器,通常成本會遠遠超過原來的兩倍。而且可能因為存在瓶頸,並不足以處理雙倍的載荷。

共享內存架構可以提供有限的容錯能力,高端機器可以使用熱插拔的組件(不關機更換磁盤,內存模塊,甚至處理器)——但它必然囿於單個地理位置的桎梏。

另一種方法是共享磁盤架構(shared-disk architecture),它使用多臺具有獨立處理器和內存的機器,但將數據存儲在機器之間共享的磁盤陣列上,這些磁盤通過快速網絡連接ii。這種架構用於某些數據倉庫,但競爭和鎖定的開銷限制了共享磁盤方法的可擴展性【2】。

ii. 網絡附屬存儲(Network Attached Storage, NAS),或存儲區網絡(Storage Area Network, SAN)

無共享架構

相比之下,無共享架構(shared-nothing architecture)(有時稱為水平擴展(horizontal scale) 或向外擴展(scale out))已經相當普及。在這種架構中,運行數據庫軟件的每臺機器/虛擬機都稱為節點(node)。每個節點只使用各自的處理器,內存和磁盤。節點之間的任何協調,都是在軟件層面使用傳統網絡實現的。

無共享系統不需要使用特殊的硬件,所以你可以用任意機器——比如性價比最好的機器。你也許可以跨多個地理區域分佈數據從而減少用戶延遲,或者在損失一整個數據中心的情況下倖免於難。隨著雲端虛擬機部署的出現,即使是小公司,現在無需Google級別的運維,也可以實現異地分佈式架構。

在這一部分裡,我們將重點放在無共享架構上。它不見得是所有場景的最佳選擇,但它是最需要你謹慎從事的架構。如果你的數據分佈在多個節點上,你需要意識到這樣一個分佈式系統中約束和權衡 ——數據庫並不能魔術般地把這些東西隱藏起來。

雖然分佈式無共享架構有許多優點,但它通常也會給應用帶來額外的複雜度,有時也會限制你可用數據模型的表達力。在某些情況下,一個簡單的單線程程序可以比一個擁有超過100個CPU核的集群表現得更好【4】。另一方面,無共享系統可以非常強大。接下來的幾章,將詳細討論分佈式數據會帶來的問題。

複製 vs 分區

數據分佈在多個節點上有兩種常見的方式:

複製(Replication)

在幾個不同的節點上保存數據的相同副本,可能放在不同的位置。 複製提供了冗餘:如果一些節點不可用,剩餘的節點仍然可以提供數據服務。 複製也有助於改善性能。 第五章將討論複製。

分區 (Partitioning)

將一個大型數據庫拆分成較小的子集(稱為分區(partitions)),從而不同的分區可以指派給不同的節點(node)(亦稱分片(shard))。 第六章將討論分區。

複製和分區是不同的機制,但它們經常同時使用。如圖II-1所示。

設計數據密集型應用-Data-Intensive Application

圖II-1 一個數據庫切分為兩個分區,每個分區都有兩個副本

理解了這些概念,就可以開始討論在分佈式系統中需要做出的困難抉擇。第七章將討論事務(Transaction),這對於瞭解數據系統中可能出現的各種問題,以及我們可以做些什麼很有幫助。第八章和第九章將討論分佈式系統的根本侷限性。

在本書的第三部分中,將討論如何將多個(可能是分佈式的)數據存儲集成為一個更大的系統,以滿足複雜的應用需求。 但首先,我們來聊聊分佈式的數據。

3第三部分:衍生數據

在本書的第一部分和第二部分中,我們自底向上地把所有關於分佈式數據庫的主要考量都過了一遍。從數據在磁盤上的佈局,一直到出現故障時分佈式系統一致性的侷限。但所有的討論都假定了應用中只用了一種數據庫。

現實世界中的數據系統往往更為複雜。大型應用程序經常需要以多種方式訪問和處理數據,沒有一個數據庫可以同時滿足所有這些不同的需求。因此應用程序通常組合使用多種組件:數據存儲,索引,緩存,分析系統,等等,並實現在這些組件中移動數據的機制。

本書的最後一部分,會研究將多個不同數據系統(可能有著不同數據模型,並針對不同的訪問模式進行優化)集成為一個協調一致的應用架構時,會遇到的問題。軟件供應商經常會忽略這一方面的生態建設,並聲稱他們的產品能夠滿足你的所有需求。在現實世界中,集成不同的系統是實際應用中最重要的事情之一。

記錄和衍生數據系統

從高層次上看,存儲和處理數據的系統可以分為兩大類:

記錄系統(System of record)

記錄系統,也被稱為真相源(source of truth),持有數據的權威版本。當新的數據進入時(例如,用戶輸入)首先會記錄在這裡。每個事實正正好好表示一次(表示通常是標準化的(normalized))。如果其他系統和記錄系統之間存在任何差異,那麼記錄系統中的值是正確的(根據定義)。

衍生數據系統(Derived data systems)

衍生系統中的數據,通常是另一個系統中的現有數據以某種方式進行轉換或處理的結果。如果丟失衍生數據,可以從原始來源重新創建。典型的例子是緩存(cache):如果數據在緩存中,就可以由緩存提供服務;如果緩存不包含所需數據,則降級由底層數據庫提供。非規範化的值,索引和物化視圖亦屬此類。在推薦系統中,預測彙總數據通常衍生自用戶日誌。

從技術上講,衍生數據是冗餘的(redundant),因為它重複了已有的信息。但是衍生數據對於獲得良好的只讀查詢性能通常是至關重要的。它通常是非規範化的。可以從單個源頭衍生出多個不同的數據集,使你能從不同的“視角”洞察數據。

並不是所有的系統都在其架構中明確區分記錄系統和衍生數據系統,但是這是一種有用的區分方式,因為它明確了系統中的數據流:系統的哪一部分具有哪些輸入和哪些輸出,以及它們如何相互依賴。

大多數數據庫,存儲引擎和查詢語言,本質上既不是記錄系統也不是衍生系統。數據庫只是一個工具:如何使用它取決於你自己。記錄系統和衍生數據系統之間的區別不在於工具,而在於應用程序中的使用方式。

通過梳理數據的派衍生關係,可以清楚地理解一個令人困惑的系統架構。這將貫穿本書的這一部分。

4關於作者

Martin Kleppmann是英國劍橋大學分佈式系統的研究員。此前他曾在互聯網公司擔任過軟件工程師和企業家,其中包括LinkedIn和Rapportive,負責大規模數據基礎架構。在這個過程中,他以艱難的方式學習了一些東西,他希望這本書能夠讓你避免重蹈覆轍。

Martin是一位常規會議演講者,博主和開源貢獻者。他認為,每個人都應該有深刻的技術理念,深層次的理解能幫助我們開發出更好的軟件。

設計數據密集型應用-Data-Intensive Application

往期精選

Spring Boot 從入門到實踐系列教程(1)- 課程目錄

Spring Boot 從入門到實踐系列教程(2)- 快速入門

Spring Boot 從入門到實踐系列教程(3)- Spring Boot Starters簡介

Spring Boot 從入門到實踐系列教程(4)- Spring Boot 執行器

Spring Boot 從入門到實踐系列教程(5)- 快速構建一個Spring Boot Web應用程序

Spring Boot 從入門到實踐系列教程(6)- 如何更改Spring Boot中的默認口

公眾號:【轉行程序員】專注新人轉行入門指導,老兵技術提升,包含各種新手學習資料,架構師技能提升系列文章,歡迎關注。


分享到:


相關文章: