讀書(shū)筆記 | 數(shù)據(jù)密集型應(yīng)用系統(tǒng)設(shè)計(jì)

?? 程序員必讀書(shū)籍?。。《拱暝u(píng)分9.7 ???? 好評(píng)如潮

?? 讀書(shū)筆記Xmind分享 ???? 讀書(shū)筆記 | 數(shù)據(jù)密集型應(yīng)用系統(tǒng)設(shè)計(jì) | 思維導(dǎo)圖?? ?口令: vP5C

?? 品質(zhì)讀物"Go"????《數(shù)據(jù)密集型應(yīng)用系統(tǒng)設(shè)計(jì)》

?? 關(guān)鍵詞匯 : 數(shù)據(jù)模型 / 數(shù)據(jù)存儲(chǔ) / 事務(wù) / 分布式

?? 歡迎關(guān)注 : 大摩羯先生

第一部分 數(shù)據(jù)系統(tǒng)基礎(chǔ)

第1章 可靠、可擴(kuò)展與可維護(hù)的應(yīng)用系統(tǒng)

背景

  • 應(yīng)用都屬于數(shù)據(jù)密集型,而非計(jì)算密集型

  • 核心在于數(shù)據(jù)量、數(shù)據(jù)的復(fù)雜度及數(shù)據(jù)的快速多變性

應(yīng)用構(gòu)建模塊

數(shù)據(jù)庫(kù)

持久化數(shù)據(jù)

  1. MySQL等關(guān)系型數(shù)據(jù)庫(kù)
  2. Hive/Clickhouse等大數(shù)據(jù)存儲(chǔ)

高速緩存

緩存熱點(diǎn)數(shù)據(jù)/操作復(fù)雜數(shù)據(jù)以供加快訪(fǎng)問(wèn)

  1. 應(yīng)用內(nèi)存一級(jí)緩存
  2. Redis、Memcache等二級(jí)緩存

索引

通過(guò)冗余存儲(chǔ)、異構(gòu)數(shù)據(jù)結(jié)構(gòu)來(lái)加快檢索

  1. ES倒排索引
  2. MySQL索引

流式處理

持續(xù)發(fā)送消息至另一個(gè)進(jìn)程,處理采用異步方式

  1. 基于RMQ可靠消息傳遞
  2. 基于Kafka流式數(shù)據(jù)傳遞

批處理

定期處理大量的累積數(shù)據(jù)

認(rèn)識(shí)數(shù)據(jù)系統(tǒng)

數(shù)據(jù)庫(kù)、隊(duì)列、高速緩存等都可以認(rèn)為是“數(shù)據(jù)系統(tǒng)”

設(shè)計(jì)數(shù)據(jù)系統(tǒng)或數(shù)據(jù)服務(wù)時(shí),三個(gè)棘手問(wèn)題

  • 可靠性

    出現(xiàn)異常時(shí),系統(tǒng)可以繼續(xù)正常運(yùn)轉(zhuǎn)

  • 可擴(kuò)展性

    隨著數(shù)據(jù)規(guī)模、流量、復(fù)雜性增長(zhǎng),能夠以合理的方式來(lái)匹配

  • 可維護(hù)性

    現(xiàn)有功能維護(hù)&新功能迭代、新老人員交替

第2章 數(shù)據(jù)模型與查詢(xún)語(yǔ)言

背景

應(yīng)用構(gòu)建是一層一層疊加“數(shù)據(jù)模型”來(lái)構(gòu)建的

關(guān)系模型&文檔模型

  • SQL

    數(shù)據(jù)被組織成關(guān)系,即表

    每個(gè)關(guān)系都是元組的無(wú)序集合,即行

  • RDBMS

    事務(wù)處理

    批處理

  • NoSQL

      1. 比關(guān)系數(shù)據(jù)庫(kù)有更好的拓展性,支持超大數(shù)據(jù)集或超高寫(xiě)入吞吐量
      1. 大多數(shù)免費(fèi)、開(kāi)源
      1. 關(guān)系模型不能很好支持一些特定查詢(xún)
      1. 突破關(guān)系模式限制性,期望更動(dòng)態(tài)和表達(dá)力的數(shù)據(jù)模型
  • 對(duì)象-關(guān)系不匹配

    開(kāi)發(fā)語(yǔ)言,普遍面向?qū)ο缶幊?/p>

    關(guān)系型數(shù)據(jù)庫(kù)需要ORM映射轉(zhuǎn)化

    關(guān)系模型的靈活性較差,非關(guān)系型可以更豐富的表達(dá)邏輯關(guān)系,如JSON、XML

  • 多對(duì)一與多對(duì)多關(guān)系

    維護(hù)關(guān)系ID而非純文本字符串

      1. 避免批量復(fù)制、更新帶來(lái)的消耗
      1. 容易維護(hù)
      1. 避免帶來(lái)數(shù)據(jù)不一致問(wèn)題
      1. 符合數(shù)據(jù)庫(kù)規(guī)范思想,消除重復(fù)
  • 文檔模型并不適合表達(dá)多對(duì)一的關(guān)系

    • 一些數(shù)據(jù)系統(tǒng)不支持聯(lián)結(jié)join這種操作,需要從數(shù)據(jù)層轉(zhuǎn)移到應(yīng)用層
  • 優(yōu)缺點(diǎn)對(duì)比

    • 關(guān)系數(shù)據(jù)庫(kù)

      • 依賴(lài)所使用的數(shù)據(jù)結(jié)構(gòu),強(qiáng)在聯(lián)結(jié)操作、多對(duì)一、多對(duì)多關(guān)系的簡(jiǎn)潔表達(dá)

      • 高度關(guān)聯(lián)數(shù)據(jù)

    • 文檔數(shù)據(jù)庫(kù)

      • 模式靈活性,局部性帶來(lái)較好性能

      • 無(wú)模式

      • 數(shù)據(jù)結(jié)構(gòu)是隱式的,讀取時(shí)才解釋

      • 一般為xml、json、二進(jìn)制變體等結(jié)構(gòu)化數(shù)據(jù)

      • 類(lèi)似文檔結(jié)構(gòu),即一系列關(guān)系數(shù)據(jù),適合使用文檔數(shù)據(jù)庫(kù),一次完成加載

      • 局限性在于嵌套層次的訪(fǎng)問(wèn)路徑,不能直接引用文檔中的嵌套項(xiàng)

      • 對(duì)于聯(lián)結(jié)支持不足

      • 適合一對(duì)多,無(wú)關(guān)系,不適合多對(duì)多關(guān)系的數(shù)據(jù)模型

數(shù)據(jù)查詢(xún)語(yǔ)言

聲明式

  • 聲明式語(yǔ)言只需要指定所需數(shù)據(jù)模式、結(jié)果滿(mǎn)足條件、數(shù)據(jù)轉(zhuǎn)換(排序、分組、聚合),而不需要關(guān)心具體實(shí)現(xiàn)過(guò)程和細(xì)節(jié)

  • 比命令式API更加簡(jiǎn)潔和容易使用,隱蔽了內(nèi)部實(shí)現(xiàn)細(xì)節(jié)

  • 例如數(shù)據(jù)庫(kù)系統(tǒng)的查詢(xún)優(yōu)化器會(huì)決定采取哪些索引和聯(lián)結(jié),以及用何種順序來(lái)執(zhí)行查詢(xún)的各個(gè)語(yǔ)句

命令式

  • 命令式語(yǔ)言告訴計(jì)算機(jī)以特定順序執(zhí)行某些操作,可以完全推理整個(gè)過(guò)程,逐行遍歷代碼、評(píng)估相關(guān)條件、更新對(duì)應(yīng)的變量等

MapReduce

  • 既不是聲明式查詢(xún)語(yǔ)言,也不是一個(gè)完全命令式的查詢(xún)API

  • 它介于兩者之間,查詢(xún)邏輯用代碼實(shí)現(xiàn),基于許多函數(shù)式編程語(yǔ)言中的map

  • MapReduce是一個(gè)相當(dāng)?shù)讓拥木幊棠P?,用于?jì)算集群上分布執(zhí)行

圖狀數(shù)據(jù)模型

例子

  • 社交網(wǎng)絡(luò)

    頂點(diǎn)是人,邊表示與其他人的關(guān)系

  • WEB圖

    頂點(diǎn)是網(wǎng)頁(yè),邊表示與其他頁(yè)面的HTML鏈接

  • 公路/鐵路網(wǎng)

    頂點(diǎn)是交叉路口,邊表示他們之間的公路或鐵路線(xiàn)

小結(jié)

數(shù)據(jù)模型演進(jìn)過(guò)程

  • 層次模型

    像一顆大樹(shù),不利于表示多對(duì)多關(guān)系

  • 關(guān)系模型

    文檔數(shù)據(jù)庫(kù)

    圖數(shù)據(jù)庫(kù)

第3章 數(shù)據(jù)存儲(chǔ)與檢索

數(shù)據(jù)庫(kù)核心:數(shù)據(jù)結(jié)構(gòu)

  • 索引

    • 優(yōu)點(diǎn):加快檢索

    • 缺點(diǎn):增加寫(xiě)入成本,影響性能

  • 種類(lèi)

    • 聚集索引

      索引中直接保存行數(shù)據(jù)

    • 非聚集索引

      存儲(chǔ)行數(shù)據(jù)的引用,需要再到實(shí)際存儲(chǔ)行數(shù)據(jù)的索引上檢索,回表查詢(xún)

  • 覆蓋索引

    檢索數(shù)據(jù)就在索引上存儲(chǔ)

  • 多列索引

  • 哈希索引

    • 優(yōu)點(diǎn):訪(fǎng)問(wèn)快

    • 缺點(diǎn):內(nèi)存占用、哈希沖突的解決、隨機(jī)IO訪(fǎng)問(wèn)、區(qū)間查詢(xún)效率不高不能高效范圍查詢(xún)

  • 全文搜索、模糊索引

  • 倒排表

    • Lucene是Elasticsearch和Solr的索引引擎

    • Key記錄詞條,Value記錄包含該詞條的文檔ID

      布隆過(guò)濾器

    • 避免頻繁無(wú)效操作

      SSTables(Sorted String Table) 排序字符串表

    • 要求每個(gè)鍵在每個(gè)段文件中只能出現(xiàn)一次

    • 合并后的鍵是有序的

    • LSM Tree(Log Structured Merge Tree)

      一種分層、有序、面向磁盤(pán)的數(shù)據(jù)結(jié)構(gòu) 其核心思想是充分利用磁盤(pán)的順序?qū)懶阅芤h(yuǎn)高于隨機(jī)寫(xiě)性能這一特性,將批量的隨機(jī)寫(xiě)轉(zhuǎn)換為一次性的順序?qū)?/p>

      參考 https://segmentfault.com/a/1190000040752799

    • CURD

      • 新增

        追加一條新記錄

      • 更新

        追加一條新記錄

      • 刪除

        追加一條刪除記錄

  • B-Tree

    • 將數(shù)據(jù)庫(kù)分解成固定大小的塊或頁(yè),一般為4KB

    • 頁(yè)是內(nèi)部讀寫(xiě)的最小單元

    • 這種數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)更接近底層硬件,因?yàn)橛脖P(pán)也是以固定大小的塊排列

    • 數(shù)據(jù)更新策略

    • 預(yù)寫(xiě)日志(WAL)+ 覆蓋頁(yè)

      重做日志

      僅支持追加修改的文件,每個(gè)B-Tree修改必須先更新WAL然后再修改樹(shù)本身的頁(yè), 當(dāng)數(shù)據(jù)庫(kù)崩潰后需要恢復(fù)時(shí),該日志用于將B+Tree恢復(fù)到最近一致的狀態(tài)

    • 寫(xiě)時(shí)復(fù)制

      修改的頁(yè)被寫(xiě)入不同的位置,樹(shù)中頁(yè)的新版本創(chuàng)建后指向新的位置

      這是類(lèi)似一種快照隔離、可重復(fù)讀的設(shè)計(jì)思想

    • B+Tree

      增加頁(yè)的額外指針來(lái)指向同層級(jí)左、右兄弟頁(yè),不用跳回父一級(jí)頁(yè)

  • 追加日志文件的實(shí)現(xiàn)

    • 重要問(wèn)題

        1. 文件格式。更快更簡(jiǎn)單的方法是使用二進(jìn)制格式
        1. 刪除記錄。進(jìn)行刪除的特殊標(biāo)記
        1. 崩潰恢復(fù)。 先寫(xiě)日志,通過(guò)日志來(lái)恢復(fù)和回放
        1. 部分寫(xiě)入問(wèn)題。 追加日志進(jìn)行校驗(yàn)和保證完整性
        1. 并發(fā)控制。 嚴(yán)格的先后順序追加,一個(gè)寫(xiě)線(xiàn)程,多個(gè)讀線(xiàn)程
    • 追加式設(shè)計(jì)優(yōu)點(diǎn)

      • 1.磁盤(pán)寫(xiě)入友好。 追加和分段合并主要是順序?qū)?,比隨機(jī)寫(xiě)入快,特別是在旋轉(zhuǎn)式磁性硬盤(pán)上

      • 2.并發(fā)、崩潰恢復(fù)友好。 不必?fù)?dān)心錯(cuò)寫(xiě)問(wèn)題

      • 3.避免碎片化。 根據(jù)規(guī)則進(jìn)行舊分段合并,避免磁盤(pán)碎片化,提高利用率

  • 事務(wù)處理與分析處理

    • 事務(wù)屬性

      ACID 原子性、一致性、隔離性、持久性

  • OLTP&OLAP

    • 數(shù)據(jù)倉(cāng)庫(kù)

      不影響OLTP業(yè)務(wù)

      一般數(shù)倉(cāng)是OLTP系統(tǒng)的只讀副本

      數(shù)據(jù)轉(zhuǎn)換,提取-轉(zhuǎn)換-加載

    • 列式存儲(chǔ)

      按列進(jìn)行數(shù)據(jù)聚合存儲(chǔ)

      列存儲(chǔ)壓縮

      同一列數(shù)據(jù)類(lèi)型一致,便于進(jìn)行壓縮

      列存儲(chǔ)排序

      縮小數(shù)據(jù)范圍

      利于進(jìn)行列壓縮

      隨機(jī)性大,不容易真正進(jìn)行壓縮

      列存儲(chǔ)寫(xiě)入

      寫(xiě)入相對(duì)困難

    • LSM-Tree解決方案

      位圖索引 & 游程編碼

      Clickhouse,Cassandra,Hbase

聚合

COUNT、SUM、AVG、MIN、MAX

物化視圖,其實(shí)就是預(yù)先查詢(xún)好,根據(jù)業(yè)務(wù)數(shù)據(jù)的更新來(lái)連鎖更新,將計(jì)算前置

小結(jié)

    1. OLTP面向用戶(hù),業(yè)務(wù)查詢(xún)、事務(wù)請(qǐng)求多,數(shù)據(jù)量小,對(duì)性能要求高
    1. OLAP面向數(shù)據(jù)決策用戶(hù),請(qǐng)求量低,但數(shù)據(jù)查詢(xún)量大
    1. OLTP主要存儲(chǔ)引擎
    • ① 日志結(jié)構(gòu)流派

      只允許追加式更新文件和刪除過(guò)時(shí)的文件,但不會(huì)修改已寫(xiě)入的文件

      BitCask、SSTables、LSM-Tree、LevelDB、Cassandra、HBase、Lucene

    • ② 原地更新流派

      將磁盤(pán)視為可覆蓋的一組固定大小的頁(yè),貼近硬件磁盤(pán)結(jié)構(gòu)的設(shè)計(jì)

      B-Tree、InnoDB

第4章 數(shù)據(jù)編碼與演化

數(shù)據(jù)編碼格式

  • 編碼數(shù)據(jù)格式

    JSON、XML、protobuf、Thrift、Avro

  • 數(shù)據(jù)存儲(chǔ)、通信場(chǎng)景

    Rest、RPC、消息傳遞

  • 編碼&解碼、序列化&反序列化

    語(yǔ)言的特定格式問(wèn)題

  • 不同語(yǔ)言之間格式的差異和通信

    為了在相同對(duì)象類(lèi)型中恢復(fù)數(shù)據(jù),解碼過(guò)程需要能夠?qū)嵗我獾念?lèi),這個(gè)過(guò)程存在一些安全問(wèn)題,容易遭到惡意攻擊

    缺乏數(shù)據(jù)變更帶來(lái)的向前、向后兼容問(wèn)題

    效率問(wèn)題,比如Java內(nèi)置序列化性能較差、編碼臃腫

    第三方序列化的問(wèn)題

    數(shù)字編碼的模糊之處

    XML、CSV無(wú)法區(qū)分?jǐn)?shù)字和由數(shù)字組成的字符串

    JSON區(qū)分字符串和數(shù)字,但不區(qū)分整數(shù)、浮點(diǎn)數(shù),并且不指定精度

    JSON、XML對(duì)Unicode字符串支持友好

    不支持二進(jìn)制字符串,通過(guò)Base64將二進(jìn)制數(shù)據(jù)編碼為文本來(lái)解決這個(gè)限制

  • 二進(jìn)制編碼

    結(jié)構(gòu)緊湊,效率高,節(jié)省空間

    可讀性差

  • JSON的二進(jìn)制編碼

    • MessagePack,二進(jìn)制編碼

    • Thrift、protobuf

      字段標(biāo)簽和模式演化

      字段位置、標(biāo)簽記錄

      數(shù)據(jù)類(lèi)型和模式演化

      精度丟失風(fēng)險(xiǎn)

    • Avro

      讀模式

      寫(xiě)模式

    延伸閱讀《深入理解序列化和反序列化》https://book.douban.com/subject/35303133/

數(shù)據(jù)流模式

  • 通過(guò)數(shù)據(jù)庫(kù)

  • 通過(guò)服務(wù)調(diào)用

    • 遠(yuǎn)程調(diào)用的問(wèn)題

        1. 網(wǎng)絡(luò)請(qǐng)求是不可預(yù)測(cè)的,遠(yuǎn)程服務(wù)響應(yīng)慢、網(wǎng)絡(luò)問(wèn)題丟失等
        1. 超時(shí)情況的處理
        1. 重試帶來(lái)的冪等處理
        1. 較大對(duì)象的傳輸問(wèn)題
        1. 不同進(jìn)程語(yǔ)言服務(wù)的數(shù)據(jù)轉(zhuǎn)換問(wèn)題
    • RPC的數(shù)據(jù)編碼和演化

      Thrift、gRPC和Avro RPC可以根據(jù)各自編碼格式的兼容性規(guī)則進(jìn)行演化

      在SOAP中,請(qǐng)求和響應(yīng)是用XML模式指定的

      Restful API通常使用JSON用于響應(yīng)

  • 通過(guò)消息隊(duì)列

    • 消息隊(duì)列比RPC的優(yōu)點(diǎn)

      1. 系統(tǒng)間的緩沖區(qū),如果接收方系統(tǒng)過(guò)載或不可用,可以暫時(shí)存儲(chǔ),提高系統(tǒng)整體可用性

      2. 自動(dòng)將消息重新發(fā)送到之前崩潰的系統(tǒng),防止消息丟失

      3. 發(fā)送方不需要知道接收方IP、端口信息等

      4. 支持一條消息同時(shí)發(fā)給多個(gè)接收方

      5. 發(fā)送方、接收方分離,解耦

    • 消息隊(duì)列比RPC的差異

      通信是異步的

      不關(guān)心響應(yīng)結(jié)果

      不強(qiáng)制特定數(shù)據(jù)格式

      消息隊(duì)列產(chǎn)品 RabbitMQ、ActiveMQ、Kafka

小結(jié)

  • 編程語(yǔ)言自身支持的序列化僅限自身語(yǔ)言中使用,無(wú)法跨語(yǔ)言使用,且缺乏向前、向后兼容

  • JSON、XML、CSV等文本格式非常普遍,主要特定數(shù)據(jù)類(lèi)型的兼容支持問(wèn)題

  • 二進(jìn)制編碼格式支持使用清晰定義來(lái)進(jìn)行向前、向后兼容性的變更且可以進(jìn)行緊湊、高效的編碼,但是對(duì)閱讀不友好

第二部分 分布式數(shù)據(jù)系統(tǒng)

分布式部署

目的

  • 擴(kuò)展性

    突破單機(jī)能力

  • 容錯(cuò)與高可用性

    避免單機(jī)帶來(lái)的故障、破壞問(wèn)題

  • 延遲考慮

    就近部署,提高響應(yīng)效率

第5章 數(shù)據(jù)復(fù)制

數(shù)據(jù)復(fù)制的方式

  • 主從復(fù)制

    • 主從復(fù)制原理

        1. 指定某一個(gè)副本為主副本(主節(jié)點(diǎn)),當(dāng)寫(xiě)數(shù)據(jù)時(shí),寫(xiě)請(qǐng)求由主節(jié)點(diǎn)來(lái)處理并把新數(shù)據(jù)寫(xiě)入主節(jié)點(diǎn)
        1. 其他副本則全部稱(chēng)為從副本(從節(jié)點(diǎn)),主副本寫(xiě)入本地存儲(chǔ)后將數(shù)據(jù)更改通過(guò)復(fù)制的日志或更改流發(fā)送給所有從副本,然后從節(jié)點(diǎn)嚴(yán)格保持和主節(jié)點(diǎn)一樣的寫(xiě)入順序?qū)懭氲綇墓?jié)點(diǎn)本地
        1. 客戶(hù)端讀取數(shù)據(jù)時(shí)可以從主節(jié)點(diǎn)、從節(jié)點(diǎn)上進(jìn)行,但是只有主節(jié)點(diǎn)接受寫(xiě)請(qǐng)求
    • 數(shù)據(jù)復(fù)制的問(wèn)題

      • 同步or異步

        • 同步復(fù)制

          同步復(fù)制的優(yōu)點(diǎn)是,確保副本之間數(shù)據(jù)一致性

          同步復(fù)制的缺點(diǎn)是,延時(shí)高,如果出現(xiàn)節(jié)點(diǎn)故障,寫(xiě)入將阻塞且始終無(wú)法成功

        • 半同步

          至少有兩個(gè)節(jié)點(diǎn)擁有最新的數(shù)據(jù)副本(即主節(jié)點(diǎn)和一個(gè)同步從節(jié)點(diǎn))

        • 全異步復(fù)制

          主節(jié)點(diǎn)一直可以響應(yīng)寫(xiě)請(qǐng)求,吞吐性好,但是從節(jié)點(diǎn)可能遠(yuǎn)遠(yuǎn)落后主節(jié)點(diǎn),也可能會(huì)有數(shù)據(jù)不一致、持久性問(wèn)題

          不靠譜較為折中的設(shè)計(jì),但是應(yīng)用也比較廣泛

      • 處理失敗副本

        • 從節(jié)點(diǎn)失效

          重啟后追趕主節(jié)點(diǎn)最新數(shù)據(jù)

        • 主節(jié)點(diǎn)失效

          1. 確認(rèn)主節(jié)點(diǎn)失效

            一般基于超時(shí)機(jī)制,節(jié)點(diǎn)之間頻繁地相互發(fā)送心跳存活消息, 如果發(fā)現(xiàn)某一個(gè)節(jié)點(diǎn)在一段時(shí)間內(nèi)沒(méi)有響應(yīng)則認(rèn)為該節(jié)點(diǎn)失效

          2. 選舉新的主節(jié)點(diǎn)

            通過(guò)共識(shí)機(jī)制來(lái)投票選舉

            候選節(jié)點(diǎn)最好與原主節(jié)點(diǎn)的數(shù)據(jù)差異最小,這樣可以最小化數(shù)據(jù)丟失風(fēng)險(xiǎn)

          3. 重新配置系統(tǒng)使新主節(jié)點(diǎn)生效

            請(qǐng)求路由控制

            多副本的一致性

        • 增加新的從節(jié)點(diǎn)

          1. 在某個(gè)時(shí)間點(diǎn)對(duì)主節(jié)點(diǎn)的數(shù)據(jù)副本產(chǎn)生一個(gè)一致性快照,這樣不會(huì)長(zhǎng)時(shí)間鎖定整個(gè)數(shù)據(jù)庫(kù)

          2. 將此快照拷貝到新的從節(jié)點(diǎn)

          3. 從節(jié)點(diǎn)從拷貝來(lái)的數(shù)據(jù)中追趕主節(jié)點(diǎn)的最新數(shù)據(jù)同步

實(shí)現(xiàn)

MySQL、SQL Server、Oracle

MongoDB

Kafka、RabbitMQ

  • 復(fù)制日志的實(shí)現(xiàn)

  • 基于語(yǔ)句的復(fù)制

    記錄每個(gè)寫(xiě)請(qǐng)求并將語(yǔ)句作為日志發(fā)送給從節(jié)點(diǎn)

    • 問(wèn)題

      非確定性函數(shù),如時(shí)間函數(shù)、隨機(jī)數(shù)函數(shù)不同副本可能產(chǎn)生不同結(jié)果

      副作用的語(yǔ)句,觸發(fā)器、存儲(chǔ)過(guò)程、用戶(hù)自定義函數(shù)等,也可能產(chǎn)生不同結(jié)果

      自增列,所有副本必須按照完全相同順序執(zhí)行,否則會(huì)產(chǎn)生不同結(jié)果

      如果存在多個(gè)并發(fā)執(zhí)行的事務(wù)時(shí),會(huì)有很大限制

  • 基于預(yù)寫(xiě)日志(WAL)復(fù)制

    • 適用

      日志結(jié)構(gòu)存儲(chǔ)引擎、采用覆蓋寫(xiě)磁盤(pán)+預(yù)寫(xiě)日志的存儲(chǔ)引擎都適合此類(lèi)復(fù)制方式

    • 缺點(diǎn)

      復(fù)制方案和存儲(chǔ)引擎緊密耦合,如果數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)、存儲(chǔ)引擎變化則會(huì)有很大影響和改變

    • 實(shí)現(xiàn)

      PostgreSQL、Oracle、MySQL

  • 基于行的邏輯日志復(fù)制

    • 復(fù)制和存儲(chǔ)引擎采用不同的日志格式,復(fù)制和存儲(chǔ)引擎邏輯剝離

    • 關(guān)系數(shù)據(jù)庫(kù)的邏輯日志一般指的是一系列記錄來(lái)描述數(shù)據(jù)表行級(jí)別的寫(xiě)請(qǐng)求

      對(duì)于行插入,日志包含所有相關(guān)列的新值

      對(duì)于行刪除,日志里有足夠的信息來(lái)唯一標(biāo)識(shí)已刪除的行,通常是靠主鍵

      對(duì)于行更新,日志包含足夠的信息來(lái)唯一標(biāo)識(shí)更新的行,以及所有的新值

      如果一條事務(wù)涉及多行的修改,會(huì)產(chǎn)生多條日志記錄

      實(shí)現(xiàn)

      • MySQL使用基于二進(jìn)制日志binlog進(jìn)行復(fù)制

      • 基于觸發(fā)器的復(fù)制

        可以考慮基于應(yīng)用層代碼邏輯實(shí)現(xiàn)和控制

多主節(jié)點(diǎn)復(fù)制

  • 特點(diǎn)

    多主節(jié)點(diǎn)接收寫(xiě)操作,復(fù)制流程類(lèi)似

    每個(gè)主節(jié)點(diǎn)同時(shí)也扮演其他主節(jié)點(diǎn)的從節(jié)點(diǎn)角色

    通常多主節(jié)點(diǎn)之間數(shù)據(jù)同步是異步復(fù)制

  • 適用場(chǎng)景

    一個(gè)數(shù)據(jù)中心使用多主節(jié)點(diǎn)基本沒(méi)有太大意義,其復(fù)雜性已經(jīng)超過(guò)所能帶來(lái)的好處

    適合多數(shù)據(jù)中心

    適合應(yīng)用與網(wǎng)絡(luò)斷開(kāi)后繼續(xù)工作的場(chǎng)景,如IM多端數(shù)據(jù)同步、文檔協(xié)作編輯

    多主主從復(fù)制 vs 單主主從復(fù)制

  • 性能

    容忍數(shù)據(jù)中心失效

    容忍網(wǎng)絡(luò)問(wèn)題

  • 問(wèn)題

    處理多主的寫(xiě)沖突,實(shí)現(xiàn)收斂沖突解決的方式

      1. 給每個(gè)寫(xiě)入分配唯一的ID,例如一個(gè)時(shí)間戳,一個(gè)足夠長(zhǎng)的隨機(jī)數(shù),一個(gè)UUID或者一個(gè)基于鍵-值的哈希,挑選最高ID的寫(xiě)入作為勝利者,并將其他寫(xiě)入丟棄
      1. 為每個(gè)副本分配一個(gè)唯一的ID,并制定規(guī)則,例如序號(hào)高德副本寫(xiě)入始終優(yōu)先于序號(hào)低的副本
      1. 以某種方式將這些值合并在一起,如5-7,A-C
      1. 保留所有沖突信息,交給用戶(hù)事后解決

        寫(xiě)入時(shí)檢查

        讀取時(shí)檢查

多主節(jié)點(diǎn)模型的拓?fù)浣Y(jié)構(gòu)

多節(jié)點(diǎn)容錯(cuò)性更好

多節(jié)點(diǎn)數(shù)據(jù)通信傳播復(fù)雜性增加

多節(jié)點(diǎn)數(shù)據(jù)復(fù)制覆蓋問(wèn)題

時(shí)間戳無(wú)法保證副本時(shí)鐘

版本向量控制

無(wú)主節(jié)點(diǎn)復(fù)制

放棄選擇主節(jié)點(diǎn),允許任何副本直接處理客戶(hù)端請(qǐng)求完成寫(xiě)處理

問(wèn)題

  • 多副本寫(xiě)入性能

  • 大部分ack

  • 失效節(jié)點(diǎn)恢復(fù)上線(xiàn)后進(jìn)行數(shù)據(jù)追趕修復(fù)

  • 最后寫(xiě)入者獲勝 last write win - LWW

實(shí)現(xiàn)

  • Cassandra

復(fù)制滯后問(wèn)題

  • 滿(mǎn)足最終一致性

    寫(xiě)主,讀從分?jǐn)倝毫?/p>

  • 追求一致性

    寫(xiě)后讀

    讀寫(xiě)均在主節(jié)點(diǎn)

  • 單調(diào)讀

    用戶(hù)數(shù)據(jù)讀取固定在一個(gè)副本執(zhí)行

    基于用戶(hù)ID、IP的哈希方法

    比強(qiáng)一致性弱,但比最終一致性強(qiáng)的保證

  • 順序一致讀

    順序?qū)懭耄荒墚a(chǎn)生亂序情況,包含數(shù)據(jù)上下文順序,還有數(shù)據(jù)自身更新順序

    解決方案是,具有因果順序關(guān)系的寫(xiě)入都交給一個(gè)分區(qū)副本來(lái)完成,但是效率和穩(wěn)定性有損失

第6章 數(shù)據(jù)分區(qū)

數(shù)據(jù)分區(qū)與數(shù)據(jù)復(fù)制

每個(gè)分區(qū)在多個(gè)節(jié)點(diǎn)都存有副本

鍵-值數(shù)據(jù)的分區(qū)

分區(qū)的目的是將海量數(shù)據(jù)平均分?jǐn)偟讲煌謪^(qū)節(jié)點(diǎn)

  • 分?jǐn)偛痪鶆虻那闆r叫做數(shù)據(jù)傾斜,導(dǎo)致部分分區(qū)效率性能?chē)?yán)重下降

  • 熱點(diǎn)數(shù)據(jù)也會(huì)導(dǎo)致系統(tǒng)資源使用不均勻,過(guò)于集中于部分分區(qū)出現(xiàn)問(wèn)題

基于關(guān)鍵字區(qū)間分區(qū)

  • 指定一段段連續(xù)區(qū)間范圍(最小值、最大值、時(shí)間戳)

  • 這些區(qū)間不一定非要均勻分布,因?yàn)閿?shù)據(jù)本身就可能不均勻

基于關(guān)鍵字哈希值分區(qū)

一個(gè)好的哈希函數(shù)可以處理數(shù)據(jù)傾斜并使其均勻分布,哈希能夠解決數(shù)據(jù)分布均勻的問(wèn)題,但是也破壞了連續(xù)性數(shù)據(jù)的區(qū)間特性

一致性哈希
哈希分區(qū)的熱點(diǎn),數(shù)據(jù)傾斜問(wèn)題
  • 需要在切分鍵上增加隨機(jī)數(shù)或取模后綴進(jìn)行再次rehash來(lái)打散

  • 需要額外維護(hù)元數(shù)據(jù)來(lái)映射打散數(shù)據(jù),還需要負(fù)責(zé)聚合這些數(shù)據(jù)

基于混合鍵分區(qū)

鍵的一部分標(biāo)識(shí)分區(qū),另一部分用來(lái)記錄排序后的順序

分區(qū)與二級(jí)索引

基于文檔分區(qū)的二級(jí)索引(本地索引)

  • 寫(xiě)數(shù)據(jù)時(shí),按切分鍵(如用戶(hù)ID)來(lái)路由到不同分區(qū),并在各自分區(qū)內(nèi)構(gòu)建二級(jí)索引(如性別-用戶(hù)ID關(guān)系)

  • 讀數(shù)據(jù)時(shí),如果使用到二級(jí)索引進(jìn)行檢索,會(huì)同時(shí)查詢(xún)所有分區(qū)中的二級(jí)索引拿到符合條件的數(shù)據(jù)然后做聚合返回

實(shí)現(xiàn)

MongoDB、Cassandra、Elasticsearch

  • 基于詞條的二級(jí)索引分區(qū)(全局索引)

    • 構(gòu)建全局索引,但是這個(gè)全局索引不僅僅存儲(chǔ)在某個(gè)單點(diǎn)上,而是根據(jù)索引檢索值路由到不同分區(qū)上

    • 優(yōu)點(diǎn):客戶(hù)端只需要對(duì)包含詞條索引的分區(qū)發(fā)出一次請(qǐng)求,不需要遍歷所有分區(qū)即可拿到索引命中的數(shù)據(jù),效率更高

    • 不足:寫(xiě)入速度較慢且非常復(fù)雜,主要是因?yàn)閱蝹€(gè)文檔更新時(shí),可能需要涉及多個(gè)二級(jí)索引的更新,而這些二級(jí)索引可能在不同分區(qū)節(jié)點(diǎn)上,造成寫(xiě)放大問(wèn)題;且這個(gè)更新過(guò)程一般都是異步的,不會(huì)立刻反應(yīng)在檢索上

  • 分區(qū)再平衡

動(dòng)態(tài)再平衡策略

為什么不用取模

  • 節(jié)點(diǎn)樹(shù)變化,數(shù)據(jù)到分區(qū)節(jié)點(diǎn)的路由關(guān)系變化,需要重新遷移進(jìn)行再平衡,成本巨大

  • 固定數(shù)量的分區(qū)

  • 創(chuàng)建遠(yuǎn)超實(shí)際節(jié)點(diǎn)數(shù)的分區(qū)數(shù),然后為每個(gè)節(jié)點(diǎn)分配多個(gè)分區(qū),比如10節(jié)點(diǎn)集群,每個(gè)節(jié)點(diǎn)分配100個(gè)邏輯分區(qū)

實(shí)現(xiàn)

Elasticsearch

  • 動(dòng)態(tài)分區(qū)

    • 每個(gè)分區(qū)只屬于一個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)可以管理多個(gè)分區(qū)

    • 如果一個(gè)節(jié)點(diǎn)中數(shù)據(jù)量過(guò)大,會(huì)被限制分區(qū)大小,避免傾斜

  • 按節(jié)點(diǎn)比例分區(qū)

    • 自動(dòng)與手動(dòng)再平衡操作

    • 維護(hù)成本,可操作維護(hù)性

  • 請(qǐng)求路由

  • 服務(wù)發(fā)現(xiàn)問(wèn)題

  • 處理策略

      1. 允許客戶(hù)端鏈接任意節(jié)點(diǎn),如果節(jié)點(diǎn)恰好擁有所請(qǐng)求的分區(qū),則直接處理該請(qǐng)求,否則會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到下一個(gè)合適的節(jié)點(diǎn)來(lái)處理
      1. 所有的客戶(hù)端請(qǐng)求都發(fā)送到一個(gè)路由層,由路由層負(fù)責(zé)請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的分區(qū)節(jié)點(diǎn)上。路由層不處理業(yè)務(wù),只負(fù)責(zé)請(qǐng)求分發(fā)
      1. 客戶(hù)端感知分區(qū)和節(jié)點(diǎn)分配關(guān)系??蛻?hù)端可以直接鏈接到目標(biāo)分區(qū)節(jié)點(diǎn),不需要任何中介
  • 并行查詢(xún)執(zhí)行

第7章 事務(wù)

深入理解事務(wù)

事務(wù)有其優(yōu)勢(shì),也有自身局限性

ACID的含義

原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)

BASE的含義

基本可用性(Basically Available)、軟狀態(tài)(Soft state)、最終一致性(Eventual consistency)

單對(duì)象、多對(duì)象事務(wù)操作

修改多個(gè)對(duì)象的整體一致性、隔離性等

單對(duì)象寫(xiě)入

修改單個(gè)對(duì)象的原子性、隔離性等

多對(duì)象事務(wù)的必要性

  • 關(guān)系數(shù)據(jù)模型中,外鍵關(guān)系要求數(shù)據(jù)更新必須聯(lián)動(dòng)

  • 文檔數(shù)據(jù)模型中,由于缺少join功能支持,需要同時(shí)維護(hù)反范式多對(duì)象來(lái)更新

  • 對(duì)于帶有二級(jí)索引的數(shù)據(jù)庫(kù),需要維護(hù)事實(shí)表和二級(jí)索引的更新

處理錯(cuò)誤和中止

  • 支持安全的重試機(jī)制才是中止流程的重點(diǎn)

  • 考慮返回客戶(hù)端失敗,但是重試執(zhí)行成功導(dǎo)致的響應(yīng)結(jié)果與實(shí)際數(shù)據(jù)狀態(tài)不一致情況

  • 重試需要設(shè)置次數(shù)上限,例如指數(shù)回退,避免給系統(tǒng)負(fù)載帶來(lái)超負(fù)荷壓力

  • 由臨時(shí)性故障引起的重試才有意義,永久性故障、錯(cuò)誤導(dǎo)致的重試毫無(wú)意義

  • 重試考慮冪等問(wèn)題,避免重復(fù)

  • 充分考慮重試的持久驅(qū)動(dòng),驅(qū)動(dòng)進(jìn)程也出現(xiàn)異常則再無(wú)可重試驅(qū)動(dòng)力

弱隔離級(jí)別

  • 并發(fā)問(wèn)題 / 競(jìng)爭(zhēng)條件

    多個(gè)不同事務(wù)同時(shí)讀取或操作同一數(shù)據(jù)

  • 弱隔離的目的

    提高性能,也要避免并發(fā)競(jìng)態(tài)帶來(lái)的問(wèn)題

  • 讀-提交

    最基本的事務(wù)隔離級(jí)別,提高兩個(gè)保證

      1. 讀數(shù)據(jù)庫(kù)時(shí),只能看到已成功提交的數(shù)據(jù),防止“臟讀”
      1. 寫(xiě)數(shù)據(jù)庫(kù)時(shí),只會(huì)覆蓋已成功提交的數(shù)據(jù),防止”臟寫(xiě)”
  • 實(shí)現(xiàn)讀-提交

    • 防止臟寫(xiě):對(duì)訪(fǎng)問(wèn)數(shù)據(jù)對(duì)象上鎖(如行級(jí)鎖)保證同一時(shí)間一個(gè)事務(wù)進(jìn)行事務(wù)操作

    • 防止臟讀:多版本快照提供非鎖定讀的支持,可以讀已提交事務(wù)的最新數(shù)據(jù),也可以讀最舊的數(shù)據(jù)

快照級(jí)別隔離與可重復(fù)讀

實(shí)現(xiàn) PostgreSQL、MySQL的InnoDB存儲(chǔ)引擎、SQL Server、Oracle

  • 實(shí)現(xiàn)快照級(jí)別隔離

    • 寫(xiě)鎖防止臟寫(xiě)

    • 讀不需要加鎖,是非阻塞的讀

    • 多版本并發(fā)控制 MVCC(Multi-Version Concurrency Control)

      記錄多個(gè)事務(wù)在不同時(shí)間點(diǎn)的數(shù)據(jù)對(duì)象提交版本

      唯一、單調(diào)遞增的事務(wù)ID(txid)

  • 一致性快照的可見(jiàn)性規(guī)則

      1. 每筆事務(wù)開(kāi)始時(shí),其他進(jìn)行中的事務(wù)對(duì)自身不可見(jiàn)
      1. 所有中止事務(wù)做的修改對(duì)自身不可見(jiàn)
      1. 較晚事務(wù)ID(晚于當(dāng)前事務(wù))所做的修改對(duì)自身不可見(jiàn)
      1. 其他所有的寫(xiě)入都對(duì)應(yīng)用查詢(xún)可見(jiàn)
  • 索引與快照級(jí)別隔離

    • 追加式的B-Tree,每個(gè)寫(xiě)入事務(wù)都會(huì)創(chuàng)建一個(gè)新的B-Tree root,代表該時(shí)刻數(shù)據(jù)庫(kù)的一致性快照

    • 查詢(xún)根據(jù)特定快照B-Tree來(lái)實(shí)現(xiàn)隔離

    • 需要后臺(tái)進(jìn)程來(lái)執(zhí)行壓縮和垃圾回收

  • 防止更新丟失

    • 寫(xiě)事務(wù)并發(fā)帶來(lái)的問(wèn)題

    • 解決方案

      • 原子寫(xiě)操作

        單線(xiàn)程,順序?qū)懭?/p>

      • 顯式加鎖

        FOR UPDATE

      • 原子比較更新和設(shè)置 CAS(compare and set)

        Update Table set content=2 where id = 1 and content=1

      • 多副本的沖突解決和復(fù)制

        多主節(jié)點(diǎn)或者無(wú)主節(jié)點(diǎn)中多副本,天然支持多個(gè)并發(fā)寫(xiě),通常以異步方式來(lái)同步更新,因此也會(huì)出現(xiàn)多個(gè)最新的數(shù)據(jù)副本情況 該場(chǎng)景下加鎖、原子比較不適用

        解決方案是保留多個(gè)沖突版本,由應(yīng)用層邏輯解決,或者依靠特定的數(shù)據(jù)結(jié)構(gòu)來(lái)解決,合并多版本

        最后寫(xiě)入獲勝(LWW)

        容易丟失更新,但是是多數(shù)多副本數(shù)據(jù)庫(kù)的默認(rèn)配置

寫(xiě)傾斜與幻讀

定義寫(xiě)傾斜

  • 原因

    多個(gè)事務(wù)讀取同一個(gè)數(shù)據(jù)對(duì)象,然后更新其中一部分或各自更新不同對(duì)象,造成寫(xiě)傾斜

    涉及多個(gè)對(duì)象,單對(duì)象的原子操作不起作用

    對(duì)參與原子操作的對(duì)象進(jìn)行加鎖

  • 總結(jié)

    由于有了不同隔離級(jí)別下支持的多版本非鎖定讀,拿到非鎖定讀數(shù)據(jù)只是整個(gè)事務(wù)操作的一步,且這個(gè)數(shù)據(jù)在事務(wù)外還會(huì)進(jìn)行變化,那就導(dǎo)致整體事務(wù)操作的原子性不可控,背離初衷產(chǎn)生一些問(wèn)題

    幻讀

    實(shí)體化沖突

    將競(jìng)態(tài)條件建立在可操作對(duì)象上進(jìn)行加鎖

串行化

最強(qiáng)的隔離級(jí)別

通過(guò)避免并發(fā)的方式解決并發(fā)問(wèn)題

  • 采用存儲(chǔ)過(guò)程封裝事務(wù)

    • 優(yōu)點(diǎn)

    • 缺點(diǎn)

      語(yǔ)義丑陋、過(guò)時(shí),缺乏函數(shù)庫(kù)支持

      管理、調(diào)試、測(cè)試?yán)щy,不易監(jiān)控和應(yīng)用層集成

      糟糕的存儲(chǔ)過(guò)程會(huì)給數(shù)據(jù)庫(kù)性能帶來(lái)極大影響

兩階段加鎖(2PL,tow-phase locking),比較標(biāo)準(zhǔn)的串行化方式

讀鎖定

寫(xiě)鎖定

謂詞鎖

百度什么是“謂詞”?

 數(shù)理邏輯中表示一個(gè)個(gè)體的性質(zhì)和兩個(gè)或兩個(gè)以上個(gè)體間關(guān)系的詞

 謂詞鎖不屬于某個(gè)特定對(duì)象,而是面向某些特殊的搜索條件命中的對(duì)象,這里的代表可以是范圍查詢(xún)返回的行數(shù)據(jù)
索引區(qū)間鎖(next-key locking)
  • 謂詞鎖性能不佳,事務(wù)中存在許多鎖,檢測(cè)匹配鎖就變得非常耗時(shí)

  • 索引區(qū)間鎖是對(duì)謂詞鎖的簡(jiǎn)化和優(yōu)化,它是對(duì)保護(hù)對(duì)象進(jìn)行擴(kuò)大化,優(yōu)化可以理解為是把一條條具體明細(xì)鎖變成了范圍區(qū)間鎖,效率是大大提升的

  • 目的是有效防止寫(xiě)傾斜、幻讀問(wèn)題

  • 當(dāng)沒(méi)有合適的索引(即沒(méi)有合適的加鎖對(duì)象)進(jìn)行區(qū)間鎖施加,會(huì)退化成鎖表操作

可串行化的快照隔離(Serializable Snapshot Isolation,SSI )

樂(lè)觀并發(fā)控制

第8章 分布式系統(tǒng)挑戰(zhàn)

故障與部分失效

不可靠的網(wǎng)絡(luò)

網(wǎng)絡(luò)問(wèn)題

    1. 請(qǐng)求可能在節(jié)點(diǎn)轉(zhuǎn)發(fā)中丟失
    1. 請(qǐng)求可能在某個(gè)隊(duì)列中等待,無(wú)法馬上發(fā)送
    1. 遠(yuǎn)程接受節(jié)點(diǎn)可能已經(jīng)宕機(jī)失效
    1. 遠(yuǎn)程接收節(jié)點(diǎn)可能暫時(shí)無(wú)法響應(yīng)(GC、負(fù)載過(guò)高等)
    1. 遠(yuǎn)程接收節(jié)點(diǎn)已經(jīng)完成處理請(qǐng)求,但回復(fù)消息在回傳過(guò)程中丟失
    1. 遠(yuǎn)程接收節(jié)點(diǎn)已經(jīng)完成處理請(qǐng)求,但是回復(fù)消息超時(shí)返回,發(fā)送方無(wú)法處理

不可靠的時(shí)鐘

時(shí)鐘和計(jì)時(shí)的重要性

  • 測(cè)量持續(xù)時(shí)間

  • 記錄業(yè)務(wù)時(shí)間節(jié)點(diǎn)

  • 特定時(shí)間觸發(fā)業(yè)務(wù)

單調(diào)時(shí)鐘與墻上時(shí)鐘

  • 墻上時(shí)鐘,根據(jù)某個(gè)日歷返回當(dāng)前的日期與時(shí)間

  • 服務(wù)器與NTP服務(wù)同步

  • 單調(diào)時(shí)鐘,保證總是向前計(jì)數(shù),不會(huì)出現(xiàn)回?fù)墁F(xiàn)象

  • 單調(diào)時(shí)鐘適合測(cè)量持續(xù)時(shí)間段

知識(shí),真相與謊言

拜占庭將軍問(wèn)題

第9章 一致性與共識(shí)

一致性保證

強(qiáng)一致性

弱一致性

最終一致性

可線(xiàn)性化(原子一致性、強(qiáng)一致性)

多副本下數(shù)據(jù)讀取結(jié)果在任何時(shí)刻都保持一致

對(duì)客戶(hù)端來(lái)說(shuō)就像只有一個(gè)數(shù)據(jù)副本一樣

可線(xiàn)性化 vs 可串行化

  • 可線(xiàn)性化

    • 讀寫(xiě)單個(gè)對(duì)象的最新值保證
  • 可串行化

    • 一般指事務(wù)隔離級(jí)別

    • 線(xiàn)性化的依賴(lài)條件

      加鎖與主節(jié)點(diǎn)選舉

      主節(jié)點(diǎn)選舉過(guò)程進(jìn)行加鎖保證線(xiàn)性化

      如使用Zookeeper

    • 約束與唯一性保證

      數(shù)據(jù)庫(kù)唯一索引

    • 跨通道的時(shí)間依賴(lài)

      如消息隊(duì)列中消息的順序性

    • 實(shí)現(xiàn)線(xiàn)性化系統(tǒng)

      主從復(fù)制(部分支持線(xiàn)性化)

      主節(jié)點(diǎn)復(fù)制到從節(jié)點(diǎn)滿(mǎn)足線(xiàn)性化

共識(shí)算法(可線(xiàn)性化)

通過(guò)共識(shí)協(xié)議防止多副本數(shù)據(jù)不一致,包含Zookeeper,etcd等

共識(shí)算法就是基于強(qiáng)一致性來(lái)實(shí)現(xiàn),一定是可線(xiàn)性化的

  • 多主復(fù)制(不可線(xiàn)性化)

    由于在多個(gè)節(jié)點(diǎn)執(zhí)行并發(fā)寫(xiě)入,數(shù)據(jù)異步復(fù)制到其他節(jié)點(diǎn),因此寫(xiě)入有可能出現(xiàn)沖突

  • 無(wú)主復(fù)制(可能不可線(xiàn)性化)

    需要讀取多個(gè)節(jié)點(diǎn)數(shù)據(jù),但是無(wú)法確定節(jié)點(diǎn)數(shù)據(jù)間的差異

  • CAP理論

    • 一致性(C)、可用性(A)、分區(qū)容錯(cuò)性(P),系統(tǒng)只能同時(shí)滿(mǎn)足兩個(gè)特性

    • P 是客觀存在的,無(wú)法避免的,在P不能滿(mǎn)足時(shí),只能選擇可用性(A)或者一致性(C)

    • 關(guān)于CAP理論對(duì)于分布式系統(tǒng)設(shè)計(jì)有重要指導(dǎo)作用,它已被更精確的研究成果所取代

順序保證

事實(shí)證明,排序、可線(xiàn)性化與共識(shí)之間存在著聯(lián)系

順序與因果關(guān)系

  • 因果關(guān)系對(duì)所發(fā)生的事件施加了某種排序

  • 發(fā)送消息先于收到消息

  • 問(wèn)題出現(xiàn)在答案之前

  • 如果系統(tǒng)服從因果關(guān)系所規(guī)定的的順序,則稱(chēng)之為因果一致性

  • 快照隔離提供了因果一致性,因?yàn)槭聞?wù)在數(shù)據(jù)讀取時(shí)可以按照事件發(fā)生的順序進(jìn)行選擇

  • 因果順序并非全序

全序和偏序的差異體現(xiàn)在不同數(shù)據(jù)一致性模型

  • 可線(xiàn)性化

    在一個(gè)可線(xiàn)性化的系統(tǒng)中,存在全序操作關(guān)系,能指出哪個(gè)操作在先,哪個(gè)在后

  • 因果關(guān)系

    兩個(gè)非并發(fā)的操作一定存在因果關(guān)系(前后次序),否則不可排序

    實(shí)現(xiàn)可線(xiàn)性化是要保持因果關(guān)系

    單調(diào)遞增序列號(hào)排序

  • 非因果序列發(fā)生器

    奇偶遞增,A:1,3,5 B:2,4,6

    時(shí)間戳遞增,最后寫(xiě)獲勝

    按區(qū)間分配遞增序列,A:1-1000 B:1001-2000

    Lamport時(shí)間戳

    全序關(guān)系廣播

    利用明確的順序關(guān)系

分布式事務(wù)與共識(shí)

需要集群節(jié)點(diǎn)達(dá)成一致的場(chǎng)景

  • 主節(jié)點(diǎn)選舉

  • 原子事務(wù)提交

    • 兩階段提交 2PC(two-phase commit)

        1. 啟動(dòng)一個(gè)分布式事務(wù)時(shí),向協(xié)調(diào)者請(qǐng)求全局唯一的事務(wù)ID
        1. 協(xié)調(diào)者向每個(gè)參與者發(fā)送執(zhí)行事務(wù)的一階段準(zhǔn)備請(qǐng)求
        1. 參與者返回是否要提交的反饋、投票,協(xié)調(diào)者記錄投票結(jié)果

          投票不可反悔、不可更改

        1. 協(xié)調(diào)者按照結(jié)果通知所有參與者二階段完成或者取消請(qǐng)求
    • 三階段提交 3PC

      分布式事務(wù)概念

      數(shù)據(jù)庫(kù)內(nèi)部的分布式事務(wù)

      MySQL Cluster的NDB存儲(chǔ)引擎

    • 異構(gòu)分布式事務(wù)

      存在兩種及以上不同的參與者實(shí)現(xiàn)技術(shù)

      數(shù)據(jù)庫(kù) 、緩存、消息隊(duì)列等

      Exactly-once消息處理

      XA交易

         并不是網(wǎng)絡(luò)協(xié)議,而是與事務(wù)協(xié)調(diào)者進(jìn)行通信的API
      
         停頓時(shí)仍持有鎖
      
         當(dāng)有節(jié)點(diǎn)不能正常工作時(shí),仍持有鎖阻止其他事務(wù)進(jìn)行并發(fā)操作
      

      從故障中恢復(fù)

         通過(guò)恢復(fù)日志、人為處理等方式
      

      分布式事務(wù)的限制

         協(xié)調(diào)者不支持?jǐn)?shù)據(jù)復(fù)制,意味著單點(diǎn)運(yùn)行,本身就不是高可用
      
         協(xié)調(diào)者需要依賴(lài)日志進(jìn)行中斷事務(wù)的恢復(fù)和保證
      
         2PC并不是完備的事務(wù)提交保證機(jī)制,需要考慮它的異常場(chǎng)景帶來(lái)的問(wèn)題
      
    • 支持容錯(cuò)的共識(shí)

      共識(shí)算法的性質(zhì)

         協(xié)商一致性
      
             所有節(jié)點(diǎn)都接受相同的協(xié)議
      
         誠(chéng)實(shí)性
      
             所有節(jié)點(diǎn)不能反悔,對(duì)一項(xiàng)提議不能有兩次決定
      
         合法性
      
             如果決定了某個(gè)值,則一定是由某個(gè)節(jié)點(diǎn)提議的
      
         可終止性
      
         節(jié)點(diǎn)如果不崩潰最終一定可以達(dá)成協(xié)議
      
    • 共識(shí)算法

    VSR、Paxos、Raft、Zab

    • 全序關(guān)系廣播

      消息按照相同的順序發(fā)送到所有節(jié)點(diǎn),有且只有一次

      相當(dāng)于持續(xù)的多輪共識(shí)

      由于協(xié)商一致性,所有節(jié)點(diǎn)決定以相同的順序發(fā)送相同的消息

      由于誠(chéng)實(shí)性,消息不會(huì)改變

      由于合法性,消息不會(huì)被破壞和造假

      由于可終止性,消息不會(huì)丟失

    • 主從復(fù)制與共識(shí)

      主節(jié)點(diǎn)寫(xiě)入,同步給從節(jié)點(diǎn),是滿(mǎn)足共識(shí)的,這里主節(jié)點(diǎn)相當(dāng)于獨(dú)裁者角色

      但是分布式場(chǎng)景下,選主過(guò)程中要避免出現(xiàn)多主

      世紀(jì)編號(hào)(epoch number)

      保證每個(gè)是世代里,主節(jié)點(diǎn)是唯一確定的

      更高編號(hào)將獲勝

    • 共識(shí)的局限性

      投票過(guò)程是一個(gè)同步復(fù)制過(guò)程,節(jié)點(diǎn)數(shù)據(jù)復(fù)制大部分是異步的,故障切換時(shí)有數(shù)據(jù)丟失風(fēng)險(xiǎn)

      共識(shí)體系需要嚴(yán)格的節(jié)點(diǎn)數(shù)才能運(yùn)行,因此會(huì)引入投票限制的節(jié)點(diǎn)部署代價(jià)

      共識(shí)體系中節(jié)點(diǎn)不能動(dòng)態(tài)添加、刪除,否則會(huì)影響選舉結(jié)果甚至出現(xiàn)問(wèn)題

      共識(shí)體系依賴(lài)超時(shí)機(jī)制來(lái)檢測(cè)節(jié)點(diǎn)失效,超時(shí)時(shí)間的配置和網(wǎng)絡(luò)情況對(duì)故障切換和感知有很大影響

    • 成員與協(xié)調(diào)服務(wù)

      Zookeeper、ETCD、Consul

      保存少量、可完全載入內(nèi)存(最終要寫(xiě)入磁盤(pán)以支持持久性)的數(shù)據(jù)設(shè)計(jì)

      采用容錯(cuò)的全序廣播算法在所有節(jié)點(diǎn)上復(fù)制這些數(shù)據(jù)從而實(shí)現(xiàn)高可靠

      適用場(chǎng)景

         節(jié)點(diǎn)任務(wù)分配
      
         作業(yè)調(diào)度
      
         負(fù)載平衡
      
         服務(wù)發(fā)現(xiàn)
      
         成員服務(wù)
      

第三部分 派生數(shù)據(jù)

第10章 批處理系統(tǒng)

第11章 流處理系統(tǒng)

第12章 數(shù)據(jù)系統(tǒng)的未來(lái)

本文由博客一文多發(fā)平臺(tái) OpenWrite 發(fā)布!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容