聊聊分散式 SQL 資料庫Doris(三)

2023-11-21 18:01:43

在 Doris 的儲存引擎規則:

  • 表的資料是以分割區為單位儲存的,不指定分割區建立時,預設就一個分割區.
  • 使用者資料首先被劃分成若干個分割區(Partition),劃分的規則通常是按照使用者指定的分割區列進行範圍劃分,比如按時間劃分。
  • 在每個分割區內,資料被進一步的按照Hash的方式分桶,分桶的規則是要找使用者指定的分桶列的值進行Hash後分桶。每個分桶就是一個資料分片(Tablet),也是資料劃分的最小邏輯單元。
  • Partition 可以視為是邏輯上最小的管理單元。資料的匯入與刪除,都可以或僅能針對一個 Partition 進行。
  • Tablet直接的資料是沒有交集的,獨立儲存的。Tablet也是資料移動、複製等操作的最小物理儲存單元。

Table (邏輯描述) -- > Partition(分割區:管理單元) --> Bucket(分桶:儲存,每個分桶就是一個資料分片:Tablet,資料劃分的最小邏輯單元。稱為子表) ,如下圖:

語法與範例

語法:

-- 該表記錄了某個時間點,在某個站點上各個使用者的pv資料
CREATE TABLE demo.test_tbl(
    sdate      DATE,  -- 日期
    site       INT,  -- 站點id
    city       VARCHAR(64),  -- 城市
    user       VARCHAR(32)  DEFAULT '', -- 使用者名稱
    pv         BIGINT -- pv量
) ENGINE=olap DUPLICATE KEY(sdate, site, city)
[PARTITION_DESC]
[BUCKET_DESC]
PROPERTIES ("replication_num" = "1");

[PARTITION_DESC] 表示建立分割區的詳細語句,[BUCKET_DESC] 表示建立分桶的語句.

動態分割區:

PARTITION BY RANGE(sdate)()

-- 剩餘引數需要在PARTITION進行設定:
PROPERTIES (
  "dynamic_partition.enable" = "true",
  "dynamic_partition.time_unit" = "DAY",
  "dynamic_partition.start" = "-30",
  "dynamic_partition.end" = "3",
  "dynamic_partition.prefix" = "p",
  "dynamic_partition.create_history_partition"="true",
  "replication_num" = "1"
);

分桶:

DISTRIBUTED BY HASH(site) BUCKETS 20

此時指定以 site 列的雜湊值作為分桶,並且分桶個數設定為 20 個.

官方範例:

CREATE TABLE tbl1
(
    k1 DATE,
    -- ...
)
PARTITION BY RANGE(k1) ()
DISTRIBUTED BY HASH(k1)
PROPERTIES
(
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.start" = "-7",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.buckets" = "32"
);

批次分割區與自動分桶

批次分割區使得使用者能夠批次操作表的分割區結構,一次性建立多個分割區,而不是逐個單獨建立。

-- 當然,分割區建立個數受到max_multi_partition_num引數控制,該值預設為4096,有需求可以修改
PARTITION BY RANGE(sdate)
(
   FROM ("2013-01-01") TO ("2023-01-01") INTERVAL 1 DAY
)
-- 從這個 case 來看,批次分割區功能的語法更為簡潔,但該功能的易用性和靈活性遠不止於此。

自動分桶是基於表中某個列(或在建立表時指定咧)的值範圍進行的。系統會根據該列的資料分佈情況,將資料劃分到不同的資料桶中。

-- 舊版本指定分桶個數的建立語法
DISTRIBUTED BY HASH(site) BUCKETS 20

-- 新版本使用自動分桶推算的建立語法
DISTRIBUTED BY HASH(site) BUCKETS AUTO
properties("estimate_partition_size" = "100G")

關鍵邏輯

查詢路由

一個分割區的資料不會跨多個不同的BE節點儲存.

在 Apache Doris 中,當請求到來時,查詢某個分割區的資料時,Doris 使用以下的過程來定位到相應的 Backend(BE)節點:

  1. 分割區鍵(Partition Key): 在 Doris 中,表的分割區是按照某一列的值範圍進行劃分的,這個列通常被稱為分割區鍵。使用者在建立表時可以選擇分割區鍵。

  2. 查詢請求中的分割區鍵值: 當查詢請求到達 Doris 時,請求中通常包含了要查詢的分割區鍵值。

  3. 分割區鍵值與分割區對映關係: Doris 通過分割區鍵值與分割區的對映關係,確定具體的分割區。這個對映關係通常儲存在系統的後設資料中,其中包括每個分割區所在的 BE 節點資訊。

  4. BE 節點負責的分割區: 根據分割區鍵值的對映關係,Doris 確定了負責該分割區的 BE 節點。

  5. 查詢計劃的生成和執行: Doris 生成查詢計劃,其中包含了具體的查詢操作。該計劃會被傳送到負責該分割區的 BE 節點上執行。

在 Apache Doris 中,一個表的多個分割區資料通常會儲存在不同的 Backend(BE)節點上,以實現分散式儲存和查詢的優勢。每個分割區的資料都會被劃分並儲存在負責該分割區的一個 BE 節點上。具體來說:

  1. 表的分割區: Doris 中的表通常根據某一列的值範圍進行分割區。每個分割區是表的邏輯組織單元,用於提高查詢效能、管理資料、支援按範圍刪除等操作。

  2. 分散式儲存: Doris 的設計目標之一是分散式儲存和查詢。因此,一個表的多個分割區資料會被分佈儲存在不同的 BE 節點上。這樣的設計有助於提高系統的橫向擴充套件性,允許系統有效地處理大規模資料和高並行的查詢請求。

  3. 負責分割區的 BE 節點: Doris 通過後設資料資訊記錄每個分割區所在的 BE 節點。當執行查詢請求時,Doris 會根據查詢涉及的分割區,確定負責這些分割區的 BE 節點。每個 BE 節點負責儲存和管理分配給它的分割區資料。

  4. 分散式計算: 查詢請求在涉及多個分割區時,Doris 可以通過分散式計算的方式,在多個 BE 節點上並行執行查詢計劃,以提高查詢效能。

分桶演演算法

暫時只支援HASH.

分割區演演算法

暫時只支援List, RANGE. 常用的有四種: (a) Round-Robin、(b) Range、(c) List、(d) Hash .

參考:
Doris資料分佈


詳細內容閱讀: Apache Doris 分割區分桶新功能資料劃分. 本文在此基礎上做總結與自我思考的延伸.