CockRoachDB簡介


概述

  • CockroachDB是一個分布式關系型數據庫,主要設計目標是可擴展,強一致和高可靠。

  • 在無人干預情況下, 能以極短的中斷時間容忍磁盤、主機、機架甚至整個數據中心的故障。

  • 采用完全去中心化架構, 集群中各個節點的地位完全對等。

  • 所有功能封裝在一個二進制文件中, 可以做到盡量不依賴盤配置文件直接部署。

  • 對外提供標准SQL接口,集群中任意節點都可以作為接入節點處理用戶的SQL請求。

    • 接入節點把SQL請求轉換為KV操作,並且在必要時將該操作發送至其它節點進行處理,完成后將結果返回給客戶端。
    • CockroachDB底層將數據組織成有序的Key-Value對形成一個KV map,其中Key和Value均為字節串。
    • KV map邏輯上按照范圍被切分成大量的Key空間,每個Key空間稱為Range。
    • 每個Range數據由本地KV存儲引擎(RocksDB,LevelDB的變體)存儲。
    • 每個Range被復制多份分布到多個CockroachDB節點上,Range副本數量可配置。
    • 每個Range默認大小為64M,合理的Range大小有利於加速節點故障恢復和擴容,及均衡讀寫負載
    • Range大小應該根據系統壓力進行設置,以便管理更多Range。
  • 支持水平擴展

    • 添加更多節點可以提升整個集群的存儲容量, 理論上最大可以支撐4EB的數據存儲
    • 客戶端的查詢請求可以發送到集群任意節點, 且每個查詢可獨立並發執行, 集群的吞吐能力可以隨着節點數的增加線性提升
    • 查詢以分布式任務的方式在各個數據節點並發執行,可以通過增加節點數來提升單個查詢的性能。
  • 支持強一致性

    • Range的多個副本之間使用Raft一致性協議, 所有一致性狀態都存儲在RocksDB中。
    • 對同一個Range內數據的單一或批量修改, 由Raft保證Range操作的ACID語義。
    • 涉及多個Range的操作, CockroachDB使用高效的無鎖分布式事務保障ACID語義。
  • 支持高可用

    • 將Range副本分布在一個數據中心, 可以確保低延遲復制, 同時能容忍磁盤或機器故障。
    • 如果將副本分布在不同機架, 即使某些網絡交換機故障, CockroachDB仍可提供服務。
    • Range副本可以跨數據中心和跨地域分布, 以應對來自數據中心電源中斷或網絡中斷, 以及區域電力故障等問題。
  • 隔離級別

    • 基於歷史快照時間和當前時間, 提供外部一致的無鎖讀寫。

    • 快照隔離(SI) [Snapshot Ioslation]

      • SI提供無鎖讀寫, 但是存在寫偏序問題(write skew)
    • 串行快照隔離(SSI) [Serializable Snapshot Isolation]

      • SSI消除了寫偏序, 但在競爭激烈的系統中會存在性能問題
    • SSI是默認的隔離級別, 用戶須根據實際性能情況, 選擇合適的隔離級別。CockroachDB只提供有限的linearizability(嚴格的順序一致性)。

架構

  • 架構圖

    https://mmbiz.qpic.cn/mmbiz_png/xoB0BH4icmV6icxM7fcAVlrr4vmSrbkhELibFV2iah3sCOxGzjpa1BYNDPAaEuEkeZDhgun9wxRe45H0cgwey54ZIQ/0?wx_fmt=png

  • 采用分層架構

  • SQL層

    • CockroachDB支持標准SQL, 當CockroachDB集群的某個節點收到SQL請求時,會經過SQL解析、SQL執行計划生成、SQL執行等重要步驟。
    • CockroachDB兼容PostgreSQL協議,對於報文的封裝和解析完全按照PostgreSQL的方式進行,所以用戶可以直接使用PostgreSQL的客戶端訪問CockroachDB。
    • CockroachDB對於用戶的SQL語句按照PostgreSQL的語法進行解析,解析完成后生成抽象語法樹(AST)
    • CockroachDB 會根據不同的語法樹生成對應的執行計划。目前執行計划基本是基於規則的方式來生成的。
      • 對於OLAP的SQL Statement, CockroachDB會將邏輯計划轉化為物理執行計划,即通過分布式任務的方式進行並行執行。
    • 當執行計划生成完畢后,CockroachDB會按照約定的方式開始執行,此時CockroachDB將調用事務性的KV接口。執行完成后通過協議層將執行結果返回給客戶端。
  • 分布式KV存儲

    • 負責Range路由尋址,提供統一的key-value存儲。

    • 可以由任意數量的CockroachDB物理節點組成,每個節點包含一個或多個Store(通常一個Store獨占一塊磁盤)

    • 每個Store包含多個Range,Range為KV層數據管理的最小單元,每個Range的多個副本之間使用Raft協議進行同步

    • Range示意圖

      img

      • 這個其實可以類比下hdfs的分片和elasticSearch的分片, 思想上都是相似的。
      • 節點和Range可以根據不同的物理網絡拓撲結構進行編排,從而在可靠性和性能之間折衷。
      • 假設一個Range包含三個副本,每個副本可以位於不同的位置:
        • 如果副本分布於同一台服務器上的多塊磁盤,可以容忍單塊磁盤故障。
        • 如果副本分布於同一機架上的不同服務器,可以容忍單台服務器故障。
        • 如果副本分布於同一個數據中心不同機架,可以容忍單個機架電源和網絡故障。
        • 如果副本分布於不同數據中心,可以容忍大規模網絡中斷或斷電。

關鍵字

  • CockroachDB key可以是任意字節數組

  • key有兩種類型:系統表key和用戶表key

    • 系統表key被CockroachDB用於內部數據結構和元數據。用戶表key包含用戶表數據(以及索引數據)
    • 系統表key和用戶表key通過前綴區分,並保證系統表key始終小於用戶表key
  • 系統表key有以下幾種類型:

    • Global key存儲集群級別的數據,例如“meta1”和“meta2” ,以及系統級別的key,例如節點和Store 的ID標識。
    • Store local key用於標識該Store的本地元數據(例如,StoreIdent結構),該部分元數據與所處Store生命周期相關,因此無需復制,即不會通過Raft同步到其它Store。
    • Range local key存儲Range的元數據,並與Global key(實際存儲層的全局Key)相關聯。Range local key由一個特殊前綴,加Global key及一個特殊后綴組成。例如,事務記錄是Range local key,形如: \x01k txn-
    • Replicated Range ID local key存儲Range元數據(RangeDescriptor),該元數據包含Range所有副本的元信息,這些元數據的變更會通過Raft同步。例如Range lease狀態和事務的abort緩存記錄。
    • Unreplicated Range ID local key存儲該Range副本的元數據,例如Raft狀態機的狀態信息以及持久化后的Raft日志。
  • 用戶表key用於存儲所有非系統數據

多版本數據

  • CockroachDB維護了數據的歷史版本,版本之間通過事務的提交時間戳區分。

  • 指定快照時間可以讀取此時間戳之前的最新版本數據。

  • 所有版本都有一個最小有效期,當系統進行compaction時,過期的版本數據會被系統回收。

  • 為了防止長時間數據掃描(例如MapReduce)中歷史數據被清理,用戶也可自行指定數據有效期。

  • 通過RocksDB存儲每個key的提交時間戳和GC有效期,支持多版本數據。

無鎖分布式事務

  • CockroachDB提供無鎖分布式事務
  • 支持的兩種事務隔離界別
    • 快照隔離級別(SI)
      • 隔離級別實現簡單,性能較好, 但是存在write skew 問題。
    • 串行化快照隔離級別(SSI)
      • 實現上稍微復雜一些, 但仍然能保證較高性能 (讀寫沖突嚴重的情況下稍弱), 但是不存在write skew問題。
  • 默認使用SSI隔離級別
    • 在對性能要求較高,並且沒有write skew的情況下可使用SI隔離級別。
    • 在沖突較少的情況下,SSI和SI性能相當,不需要加鎖或額外寫操作。
    • 在沖突激烈的情況下,SSI仍然不需要加鎖,但是會有更多事務被終止。
    • 在任何長事務場景中,SI和SSI都能防止事務餓死。
    • SI和SSI之間的核心區別在於事務提交時SI允許事務的候選時間戳變大,而SSI不允許
  • SI和SSI都要求緩存該Range上發生的讀操作結果
    • 如果寫操作時間戳比最近一次讀操作時間戳要小, 則寫操作失敗。
    • 每個Range都有一個緩存 (timestamp cache), 保存該Range中key被讀取的最新時間戳。
    • 讀操作會更新相應的timestamp cache, 部分寫操作 (例如Range刪除) 也會更新timestamp cache。
      • timestamp cache中最老時間戳會被優先剔除。
  • 每一個CockroachDB事務開始時都會分配一個隨機優先級和一個“候選時間戳”。
    • 候選時間戳是接收事務請求時節點分配的本地當前時間戳 (HLC), 作為事務提交的臨時時間戳。
    • 如果沒有事務沖突,在事務完成所有操作后,該時間戳會成為事務的最終提交時間戳。
  • 在跨多個節點的分布式事務執行過程中, 候選時間戳可能會變大, 但不會回退。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM