Designing Data-Intensive Applications 讀後心得 (4)
比較重要的核心心得已寫在前三篇文章 (文末有附連結)。這篇依章節摘要每章在說什麼,順便寫些個人觀點。
本文附圖皆取自書中。
Part I. Foundations of Data Systems
1. Reliable, Scalable, and Maintainable Applications
描述開發應用程式關注的指標。分析 response time 時,用百分位數 (percentiles) 較好。像是 response time 由低到高排,99% 和 99.9% 各為多少 (簡寫為 p99、p999)?
產品上線後是否容易維護也要列入考慮。我有點懷疑在專業分工的情況,RD 和 DevOps 是否能合作融洽?像因為測試分給 SET (SE in Test) 和 QA,RD 不會在設計初期考慮測試,增加 SET/QA 執行的難度。這考驗三個團隊之上的技術主管在三個領域的功力,或是三個團隊主管之間的合作。
這章有個個案分析 twitter 顯示 timeline,還滿有趣的。
方案一是使用者要看 timeline 時去抓新 tweets:
這作法 query 次數太多而沒效率,因此改用方案二: 主動寫入新訊息到每個使用者的 timeline cache:
這個作法遇到名人的情況,會有極入量寫入,短時間內負擔太重。
最後的作法是合併兩者:
- 用方法二處理一般使用者發的 tweets。
- 用方法一處理名人。等使用者要讀 timeline 時再查詢,然後合併兩個方法的結果到 timeline。
2. Data Models and Query Languages
用資料的關聯性來區分不同的 data models:
- 若應用程式大多是 one-to-many relationship (像是個人履歷),適合用 Document databases,以 key-value 方法存資料。value 是一個 document,可以是 XML、JSON 或其它格式。one-to-many relationship 直接存在一起。
- 若有較多 many-to-one / many-to-many relationships,適合用傳統常用的 relational database。
- 若有非常多 many-to-many relationship,彼此相連串接多個物件,這時就適合用 Graph databases。
不管那種 model,都有 query language,讓開發者專注在應用,然後由 query optimizer 處理效率問題和簡化取資料的程式。
用適合的 model 效率佳且有適合的查詢語言。書中有舉例說明 Graph databases 用 4 行表達 relational databases 用 29 行描述的查詢。
Document databases 共非沒有 schema,而是 schema-on-read,也就是讀取時用 schema; relational databases 則是 schema-on-write。schema-on-read 不需作 schema migration,而是讀取時加條件容許不多版本格式。
我想對多數情況來說,用 document/relational database 可能沒差那麼多?選個老字號、穩定、用的順手的比較重要。還需實戰才知。
3. Storage and Retrieval
這章很有意思,用 shell script 寫一個超迷你的 database,然後逐步說明如何補強它。推薦一讀。這裡省去不提。
介紹兩種常見 storage engine:
- log-structed: 像 SSTables、LSM-trees、 LevelDB。採用 append-only 方式更新。append-only 是滿有趣的作法,常出現在很多領域。基本上要最快的寫入速度,只能用 append 了。
- fixed-size pages: 例如 B-trees。
介紹 OLTP (Online Transaction Processing) 和 OLAP (Online Analytic Processing) 的差異 (下圖 ETL 是指 Extract-Transform-Load) :
OLTP 和 OLAP 需求不同,因此通常適合用不同系統處理。Data warehouse 產品的例子有 Amazon RedShift。
資料量多到破兆和超過 PB 時,儲存的方式不同。例如會以欄 (column) 為單位分開存,這樣在查詢特定欄時,會有效率很多。書上有說明 column-oriented storage 的格式、壓縮方法等事。
4. Encoding and Evolution
就標題的意思,沒什麼特別的,不看應該沒影響。有寫網路程式多少會獲得相關知識。
Part II. Distributed Data
5. Replication、6. Partitioning、7. Transactions
8. The Trouble with Distributed Systems
談各種困難,有寫網路程式多少會有相關知識。
例如:
- request-response 過程有各種出錯的地方,但不會知道掛在那一步。所以只能用 timeout 識別成功或失敗。
- 像是要檢查網路程式之間的健康狀態,要用 application-level heartbeat,不要依賴 TCP/OS 層級的保證。例如: 不能仰賴會正確收到 close socket 的事件。
- 時間同步不準確。
- 程式可能因 runtime 作 GC、VM 被中斷等原因而暫停,導致程式自己不知道兩個操作之間過了很久。
9. Consistency and Consensus
見之前的心得。
Part III. Derived Data
10. Batch Processing
分散式批次處理系統需要解決的兩大問題是 paritioning (切分互無關聯的資料給不同機器處理) 和 fault tolerance (自動重跑失敗的工作)。
介紹這領域的元老 MapReduce,提到它執行過程產生太多中介檔案而沒效率。後來新的系統 (例如 Spark) 避免產生中間檔案而快上不少。作者認為 MapReduce 概念簡單但不好用,不適合表達 dataflow。後來的系統 (例如 Spark) 比較適合使用。
作者還有提到針對特殊應用 (如 machine learning),另有其它高階的工具,是基於 Spark 等系統。有需要時再查,像 awesome-spark 有列些相關專案。
11. Stream Processing
相較於 batch processing 的源頭資料是固定大小 (bounded),streaming processing 是源源不絕沒有結束 (unbounded)。所以用的系統不同。
使用 publish/subscribe model 時,要考慮兩個問題:
- 當 producer 生產速度 > consumer 消化時,consumer 有幾種選擇: drop、buffer 或 backpressure (卡住 producer 不要生新資料)。像 TCP 就是有個小 buffer,滿了採 backpressure。
- 有節點掛掉的時候,是否會遺失資料?
相較於 producer 和 consumer 直接連在一起,在它們中間加上 message broker 較好。這樣 producer/consumer 可來來去去 (斷線/掛掉),比較有彈性。還有讓專業的 broker 處理 durability。producer 將資料傳給 broker 就沒事了。
說起來我以前作 remote browser 的 download-to-cloud 時 (由 linux server 的 browser 直接傳大檔案給 cloud storage,省去 手機/桌機 應用程式經手大檔案),有寫一個 server 作為 remote browser 和 Dropbox/Google Drive 之間的中介 server。現在看來,它有點像 message broker,只是當時沒這麼系統地理解我在幹嘛。
如下圖所示,broker 可幫忙處理 load balancing,或是廣播給所有 consumer:
相較於 message 處理完就刪掉的 broker (AMQP/JMS-style message broker),log-based message broker 採用 partitioned logs,也就是將每個 message 依 key 分類,用附加的方式寫到不同節點的 logs 裡。記錄各別 consumer 讀的位置,讓 consumer 可以重覆讀取資料:
Kafka 採用這一類架構。這樣可擁有和 batch processing 系統一樣,可重覆執行的好處。從開發和除錯的角度來說,這樣的架構比較方便。附帶一提,Kafka Connect 可用來整合 Change Data Capture (CDC)。這可解決不同系統之間同步的問題,例如同步更新資料庫和搜尋索引:
感覺 Kafka / Kafka Connect 是頗不錯的工具,有需要時看看。
12. The Future of Data Systems
講未來一些發展和作者主觀的看法。我還沒讀完這章,之後有空再補完。
結語
看完本書最大的收獲是全面性地了解分散式系統在解決什麼問題和設計的思維,才能因事制宜。此外,這個領域有一堆 buzzwords,了解之後比較不會被唬弄。
相關文章
- Designing Data-Intensive Applications 讀後心得 (1): 談分散式系統的 replication 和 partitioning。
- Designing Data-Intensive Applications 讀後心得 (2): 談單一節點的 transactions 是什麼。
- Designing Data-Intensive Applications 讀後心得 (3): 談跨節點維持一致資料的方法。
- Designing Data-Intensive Applications 讀後心得 (4): 前三篇挑重點章節講,這篇依章節順序摘要各章內容,大概做個記錄。