前言
最近活真是多,忙裏偷閒,磨磨蹭蹭的終於把DDIA看完了,後面幾章看起來說實話比較費勁,還是需要結合實踐反覆理解,最後一節講到了道德約束,感覺就是像是武林前輩把絕世武功祕籍傳授給你之後,叮囑你一定不要把它用在邪門歪道上,23333
在此強調,書中的小結皆是精華,一定要反覆閱讀
十、派生數據
- 整合不同系統是大型應用中最爲關鍵的任務之一 P363
- 記錄系統 P363
- 一個記錄系統被稱爲真實數據系統,擁有數據的權威版本。
- 如果另一個系統與記錄系統之間存在任何差異,那麼以記錄系統中的數據值(按照定義)爲準
- 派生數據系統 P364
- 派生數據系統中的數據則是從另一個系統中獲取已有數據並以某種方式進行轉換或處理的結果
- 如果派生數據丟失,用戶可以從原始數據源進行重建。
- 一個典型的例子是緩存
- 在線服務/系統 P367
- 服務等待庫戶請求或指令的到達,收到請求或指令時,服務試圖儘快地處理它,並返回一個相應
- 響應時間和可用性是服務性能的主要衡量指標
- 批處理系統 P367
- 批處理系統接受大量的輸入數據,運行一個作業來處理數據,併產生輸出數據。
- 批處理作業的衡量標準通常是吞吐量
- 流處理系統 P368
- 介於在線與離線/批處理之間(有時稱爲近實時或近線處理)
- 著名的批處理算法MapReduce P368
- MapReduce值得深入理解,因爲他清晰的解釋了批處理爲什麼有用以及如何有用
- nginx默認訪問日誌格式 P369
- 簡單的日誌分析 P369
- 利用nginx日誌找出網站中前五個最受歡迎的網頁
- 令人驚訝的是,使用awk、sed、grep、sort、uniq、和xargs的組合,可以在幾分鐘內完成許多數據分析任務,並且表現令人十分滿意 P370
- 歸併排序在磁盤上有良好的順序訪問模式 P371
- 通過管道將程序連接起來的想法成爲如今的UNIX哲學,在開發人員和UNIX用戶中逐漸變得流行的一些列設計原則 P372
- UNIX哲學 P372
- 每個程序做好一件事。如果要做新的工作,則建立一個全新的程序,而不是通過增加新“特徵”使舊程序變得更加複雜。
- 期待每個程序的數據成爲另個尚未確定的程序的輸入。不要將輸出與無關信息混淆在一起。避免使用嚴格的表格狀或二進制輸入格式。不要使用交互式輸入
- 儘早嘗試設計和構建軟件,甚至是操作系統,最在幾周內完成。需要扔掉那些笨拙的部分時不要猶豫,並立即進行重建
- 優先使用工具來減輕編程任務,即使你不得不額外花費時間去構建工具,並缺預期在使用完成後會將其中一些工具扔掉
- MapReduce與分佈式文件系統 P375
- MapReduce有點像分佈在數千臺機器上UNIX工具。MapReduce作業可以和UNIX進程相媲美:需要一個或多個輸入,併產生一個或多個輸出。P375
- MapReduce作業執行流程 P376
- 要創建MapReduce作業,需要實現兩個回調函數,即mapper和reducer P377
- 當mapper完成肚臍輸入文件並寫入經過排序的輸出文件,MapReduce調度器就會通知reducer開始從mapper中獲取輸出文件。 P378
- MapReduce工作流 P379
- Mapreduce沒有索引概念,至少不是通常意義上的索引。 P380
- 當給定一組文件作爲MapReduce輸入時,他讀取所有文件的全部內容;數據庫將其稱爲全表掃描。 P380
- 讀取少量記錄代價昂貴
- 分析查詢場景下較爲合理
- 各種join P384~P386
- 對比Hadoop和分佈式數據庫 P390
- Haddop經常被用於實現ETL過程:來自事物處理系統的數據以某種原始形式轉儲到分佈式文件系統中,然後編寫MapReduce作業進行數據清理,將其轉換爲關係表單,並將其導入MPP數據倉庫以進行分析。數據建模仍然會發生,打它位於一個單獨步驟中,與數據收集是分離的。由於分佈式文件系統支持任何格式編碼的數據,所以這種解偶是可行的 P391
- Hadoop生態系統包括可以隨機訪問的OLTP數據庫,如HBse以及MPP模式的分析數據庫,如Impala
- HBase和Impala都不使用MapReduce,但都使用HDFS進行存儲。儘管它們份溫和處理數據的方法差異很大,但是可以共存並被集成到同一個系統中。 P392
- 與在線系統相比,批處理對故障的敏感度較低,因爲如果遇到失敗的任務,它們不會立即影響用戶,而且總是可以重新運行
- MapReduce被設計爲容忍意外任務終止的原因:不是因爲軟件不可靠,而是因爲任意種植進程的靈活性能夠更好的利用集羣資源
- 通過處理階段明確的建模數據的系統被稱爲數據流引擎。 P395
- 像MapReduce一樣,他們通過反覆調用用戶定義的函數在單個線程上一次處理一條記錄。他們通過對數據進行分區來進行並行工作,將一個功能輸出複製到網絡上,成爲另一個功能的輸入。 P395
- 回到UNIX類比,我們看到MapReduce就像是將每個命令的輸出寫入臨時文件,而數據流引擎看起來更像是UNIX管道。尤其Flink是圍繞流水線執行的思想建立起來的,也就是將運算符的數據遞增地傳遞給其他運算符,並且在開始處理之前不等待輸入完成。 P398
批量同步並行模型 P399
批處理引擎正被用於日益廣泛的算法領域的分佈式執行。隨着批處理系統獲得更豐富的內置功能和高級聲明式運算符,而MPP數據庫也變得更具可編程性和靈活性,兩者開始變得更加相似:最終,他們都是用於存儲和處理數據的系統。 P402 - 小結 P403
- 在UNIX世界中,允許多個程序組合在一起的統一接口是文件和管道;
- 在MapReduce中,該接口是分佈式文件系統。我們看到數據流引擎添加了自己的管道式數據傳輸機制,以避免在分佈式文件系統中將中間狀態實體化,而作業的出書輸入和最終輸出通常仍然是HDFS
- 分佈式批處理框架需要解決的兩個主要問題是:
- 分區
- 容錯
十一、流處理系統
- 一個可用的複雜系統總是從可用的簡單系統演進而來。反過來這句話也是正確的:從零開始設計的複雜系統從來都用不了,也沒辦法把它變成可用。 P413
- 批處理的問題:輸入的更改只會在一天之後的輸出中反映出來,這對於許多沒有耐心的用戶來說太慢了。
- 爲了減少這種延遲,可以更頻繁的運行處理,即在每秒鐘結束時(甚至是不間斷地)處理每秒的數據,完全放棄固定的時間片,每當有事件就開始處理。這就是流處理背後的思想。 P414
- 向消費者通知新事件的常見方法是使用消息系統:生產者發送包含事件的消息。 P415
- 消息代理 P416
- 不管保留多長時間的消息,因爲每個消息都被寫入到磁盤,因此日誌的吞吐量基本保持不變。這種行爲與將消息保存在內存中,僅當隊列變得過大時纔將他們寫入磁盤的穿系統系統相比,差異明顯:當隊列很短的時候這些系統是很快的,當開始寫入磁盤時,會變得很慢,因此吞吐量取決於保留的歷史記錄數量。 P423
- 沒有一個系統能夠滿足所有的數據存儲、查詢和處理請求。在實踐中,大多數重要的應用程序都需要結合多種不同的技術來滿足需求: P424
- 使用OLTP數據庫來爲用戶請求提供服務
- 使用緩存來加速常見請求
- 使用全文索引處理搜索查詢
- 使用數據倉庫用於分析
- 每個技術都有自己的數據副本,以自己的表示方法存儲,並且針對自己的設計目標而優化
- 日誌壓縮:存儲引擎定期查找具有相同key的日誌記錄,丟棄所有的重複項,並且只保留每個key的最新更新。 P428
- 事件溯源 P429
- 事件溯源的哲學史小心的區分事件和命令。 P430
- 事務日誌記錄了對數據庫所做的所有更改。 P432
- 高速追加是更改日誌的唯一方法,從這個角度來看,數據庫的內容保存了日誌中最新的記錄值緩存。
- 日誌是事實。數據庫是是日誌子集的緩存。
- 該緩存子集恰好是來自日誌的每個記錄和索引值的最新值
- 不變事件的優勢 p432
- 如果發生錯誤,通常不會刪除或更改錯誤的數據,而是增加新的數據彌補這些錯誤
- 覆蓋錯誤的數據將導致數據恢復變得更加的困難。
- 通過不可變事件的追加日誌,診斷問題和從問題中恢復就要容易的多
- 出於分析的目的,歷史記錄也能提供有用的消息
- 緩慢變化的維度 P446
- 批處理框架可以比較容易實現容錯:如果MapReduce作業中的任務失敗,可以簡單地在另一臺機器上重新啓動,並丟棄失敗任務的輸出。這種透明的重試是可能的,因爲輸入文件是不可變的。每個人物都將其輸出寫到HDFS上的單獨文件,並且輸出僅在任務成功完成時可見 P446
- 流處理的容錯 P446
- 小結 P449
- 在某些方面,流處理與批處理非常相似,但是它是對無限(永不停止)的流而不是固定大小輸入進行持續處理 P449
- 將數據表示爲流爲高效集成系統提供了更多的機會 P450
十二、數據系統的未來
- 第三章 日誌結構存儲、B-Tree、列式存儲
- 派生視圖允許逐步演變。如果想重新構建數據集,無需採用高風險的陡然切換。而是可以在同一個基礎數據上的兩個獨立派生視圖來同時維護新老兩種架構。
- 然後,逐步開始將少量用戶遷移到新視圖中,以測試其性能是否有錯誤,而大多數用戶將繼續路由到舊視圖。
- 之後,逐漸增加訪問新視圖的用戶比例,最終放棄舊視圖
- 這種逐漸遷移的美妙之處在於,如果出現問題,每個階段的過程都是可以輕易反轉:你總是有一個工作系統可以回退 P 468
- 分拆數據庫 P469
- 從最抽象的層面上理解,數據庫,Hadoop和操作系統都提供了相同的功能:他們保存某些數據,並支持處理和查詢 。
- 許多文件系統不能好很地處理包含一千萬個小文件的目錄,而包含一千萬條記錄的數據庫完全是正常的。
- 創建一個索引
- 想想在關係型數據庫中運行CREATED INDEX來創建新索引會發生什麼。
- 數據庫必須掃描表的一致性快照,挑選出所有被索引的字段值,對他們進行排序,然後得到索引。
- 接下來,必須處理從一致性快照創建以來所累計的寫入操作(假設表在創建索引時未被鎖定,所以寫操作可能會繼續)。
- 完成後,只要有事物寫入表中,數據庫就必須保持索引處於最新狀態。
- 構建你並不需要的擴展規模是在浪費精力,可能會把你限制在一個不靈活的設計當中。實際上,這是在做過早優化 P473
- 將stream operatoe組合成數據流系統與微服務理念有很多相似的特性。但是,底層的通信機制差異很大 P478
- 前者是單向、異步的消息流
- 後者是同步的請求/響應交互
- 首先創建派生數據集,很可能是因爲想在以後多次查詢它即讀路徑:當有用戶訪問請求時,從派生數據集中讀取數據,做些必要處理,然後返回處理後的結果以響應用戶。 P479
- 許多數據存儲支持的讀寫操作其實都是一個請求對應一個響應,但很少支持訂閱更改,即一段時間內會主動返回一系列的響應。 P482
- 爲了將寫路徑擴展到最終用戶,我們需要從根本上重新思考構建這些系統的方式:從請求/響應交互轉向發佈/訂閱數據流。我認爲更具響應性的用戶界面和更好的離線支持的優勢是絕對值得嘗試的。如果你正在設計數據系統,我希望你能夠記住訂閱更改這一方式,而不僅僅是查詢當前的狀態。 P482
- Exactly-onece 執行操作 P485
- TCP使用序列號來檢測網絡上是否有數據包丟失或重複,並最終確保數據包以正確的順序接受。 P486
- 唯一性約束需要達成共識:如果有多個具有相同值的併發請求,系統需要決定接受哪一個操作,並根據違法約束拒絕其他操作 P489
- 達成這一共識的最常見的方式是將單一節點作爲主節點,並負責作出所有的決定。 P489
- 日誌機制可以確保所有消費者以相同的順序查看消息,這種保證在形式上被稱爲全序關係廣播,他等價於共識問題 P490
- 多分區請求處理 P491
- 事實證明,使用分區日誌是可以實現同等的正確性,並卻不需要原子提交 P491
- 賬戶A向賬戶B轉賬的請求由客戶端賦予一個唯一的請求ID,基於該請求ID追加到對應的日誌分區
- 流處理系統讀取請求日誌。對於每個請求消息,它發出兩條輸出消息:到付款人賬戶A的付款指令(按照A進行分區),以及到收款人賬戶B(按照B進行分區)的信用指令。原始的請求ID都包含在這兩條消息中。
- 後續操作接受上述指令,並通過請求ID急性重複數據消除,將最後的更改應用於賬戶餘額。
- 數據流系統可以保證派生數據的完整性,無需原子提交,線性化或跨分區的同步協調 P 495
- 雖然嚴格的唯一性約束要求時效性和協調性,但是隻要整體上保證完整性,幾十發生暫時約束破壞,可以時候進行修復,因此許多應用實際上採用寬鬆式的約束並沒有問題 P495
- 算法囚籠 P501
- 小結 P509