Citus 11 for Postgres 完全開源,可從任何節點查詢(Citus 官方部落格)

2022-06-21 12:00:50

Citus 11.0 來了! Citus 是一個 PostgreSQL 擴充套件,它為 PostgreSQL 新增了分散式資料庫的超能力。 使用 Citus,您可以建立跨 PostgreSQL 節點叢集透明分佈或複製的表。 Citus 11.0 是一個新的主版本,這意味著它帶有一些非常令人興奮的新功能,可以實現更高階別的可延伸性。

Citus 11.0 中最大的改進是您現在可以始終從叢集中的任何節點執行分散式查詢,因為schema & metadata 是自動同步的。我們已經在 Citus 11.0 測試版部落格文章中分享了一些細節,但對於那些使用不屬於初始測試版的 Citus 開源的人來說,我們也有很大的驚喜。

Citus 11.0 中最大的增強是,您現在可以始終從叢集中的任何節點執行分散式查詢,因為 schema 和 metadata 是自動同步的。我們已經在 Citus 11.0 beta部落格 中分享了一些細節,並對於那些使用 Citus 開源的人來說,我們也有很大的驚喜,而 Citus 開源的並不是最初 beta 版的一部分。

當我們釋出新的 Citus 版本時,我們通常會發布 2 個版本:開源版本和包含一些額外功能的企業版本。但是,Citus 11.0 將只有一個版本,因為 Citus 擴充套件中的所有內容現在都是完全開源的!

這意味著您現在可以在不阻塞寫入的情況下重新平衡分片、管理整個叢集的角色、將租戶隔離到他們自己的分片等等。 所有這一切都建立在 Citus 11.0 中已經大規模增強的基礎之上:您可以從任何節點查詢您的 Citus 叢集,從而建立真正分散式的 PostgreSQL 體驗。

在這篇博文中,我們將重點介紹:

  • 正在成為開源的 Citus 企業版功能
  • 從任何節點查詢分散式 Postgres 表
  • 隱藏預覽功能:觸發器!

如果您想了解所有新功能,可以檢視 Citus 11.0 的更新頁面,其中包含所有新功能和其他改進的詳細分類。

其餘 Citus Enterprise 功能現已開源

很久以前,Citus Data是一家企業軟體公司。隨著時間的推移,我們團隊的重點轉向開源,成為雲供應商,然後成為 Azure 不可或缺的一部分。有了新的關注點,我們的團隊開發了所有新功能,作為 Citus GitHub開源專案 的一部分。使 Citus 開源使您能夠直接與開發人員和社群互動,瞭解您執行的程式碼,避免鎖定問題,併為每個人創造更好的開發人員體驗。

去年,作為 Citus 10 版本的一部分,我們已經開源了分片重新平衡器,這是 Citus 的一個重要元件,它允許您通過將資料移動到新節點來輕鬆擴充套件叢集。 出於效能原因,分片重新平衡功能也很有用,可以在叢集中的所有節點之間平衡資料。

現在,作為 Citus 11.0 的一部分,其餘的企業功能也成為開源的:

我最喜歡的新開源功能是非阻塞分片重新平衡器

也許新開源功能中最令人興奮的是非阻塞分片移動。雖然我們在 Citus 10 中開源了分片重新平衡器,但在開源版本的分片移動期間,對正在移動的分片的寫入被阻止。現在在 Citus 11 中,Citus 通過使用邏輯複製來移動分片。這樣,當通過將現有資料移動到新節點來擴充套件叢集時,您的應用程式只會遇到短暫的寫入延遲。 一個先決條件是所有 Postgres 表都有主鍵。

現在分片重新平衡器的非阻塞方面已經開源,當您在本地、內部部署 、CI 環境或 Azure 中的託管服務中執行 Citus 時,您可以獲得完全相同的分片重新平衡功能。

從任何節點查詢分散式 Postgres 表

Citus 11 還帶有一個重要的新功能:自動 schema 和 metadata 同步。

在典型的 Citus 部署中,您的應用程式通過協調器執行分散式查詢。從應用程式的角度來看,通過協調器連線使得 Citus 在很大程度上與單節點 PostgreSQL 沒有區別。

圖 1:Citus 10.2 或更早版本中的 Citus 叢集,其中 users 和 items 是分散式表,它們的後設資料僅在協調器上。

協調器可以處理高分散式查詢吞吐量(100k/秒),但是有些應用程式仍然需要更高的吞吐量,或者有查詢需要在協調器上進行相對大量的處理(例如,使用大型結果集進行搜尋)。 幸運的是,Citus 11 中的分散式查詢可以由任何節點處理,因為分散式表 schema 和 metadata 從協調器同步到所有節點。 您仍然可以通過協調器執行 DDL 命令和叢集管理,但可以選擇跨工作節點負載均衡繁重的分散式查詢工作負載。

圖 2:Citus 11.0 叢集,其中 users 和 items 是分散式表 - 使用新的自動後設資料同步功能,他們的後設資料會同步到所有節點。

雖然後設資料同步在 Citus 11 之前已經作為一種特殊模式存在,但存在一些限制(我們有時將其稱為「Citus MX」),但它現在是通用且自動的。 任何 Citus 叢集都將始終在所有節點上具有分散式表後設資料,以及您的所有檢視、函數等,這意味著任何節點都可以執行分散式查詢。

Citus 11 beta 部落格文章詳細介紹了在從任何節點查詢時如何操作叢集。 部落格文章描述瞭如何檢視所有節點的活動,以及如何使用全域性程序識別符號 (GPID) 將內部查詢與分散式查詢相關聯。這篇文章還介紹瞭如何在 Citus 節點之間對來自應用程式的連線進行負載均衡。

最重要的是,這個新的後設資料同步/從任何節點查詢功能對您和您的應用意味著什麼?

升級到 Citus 11

如果您當前正在執行 Citus 叢集,升級到 Citus 11 很簡單。安裝新包並重啟 PostgreSQL 後,第一步是在所有節點上執行以下命令:

ALTER EXTENSION citus UPDATE;

然後當所有節點都升級後,第二步是連線到協調器並執行:

CALL citus_finish_citus_upgrade();

上面的第二步是 Citus 11 中的新步驟。citus_finish_citus_upgrade 函數將確保所有節點都有後設資料,這樣您現有的叢集的行為就與全新的 Citus 11 叢集相同。 我們建議在以後的任何 Citus 升級之後呼叫 citus_finish_citus_upgrade,因為我們可能會新增額外的步驟。

切換到 Citus 11 時無需更改應用程式。 您可以通過協調器繼續執行所有查詢,這對於大多數應用程式來說仍然是最簡單的方法。 升級後,您可以選擇通過工作節點執行部分或全部查詢,當然也可以使用所有新功能,例如非阻塞重新平衡器。

升級到 Citus 11 時要考慮的一件事是,一些很少使用的功能已被棄用:

  • 分片放置失效用於處理使用基於語句的分片複製複製的分片的寫入失敗。 當分片放置上的寫入失敗時,它將失效,以便系統可以繼續使用剩餘的副本。 雖然這種行為有一些可用性優勢,但它也有許多缺點。 Citus 仍然支援基於語句的分片複製來擴充套件讀取,因此可以升級使用分片複製的現有分散式表,但升級後分片放置將不再因失敗而失效。雖然這種行為有一些可用性優勢,但它也有許多缺點。 Citus 仍然支援基於語句的分片複製來擴充套件讀取,因此可以升級使用分片複製的現有分散式表,但升級後分片放置將不再因失敗而失效。
  • 追加分散式表是在載入新資料時需要頻繁建立新分片的分散式表。 這種方法的缺點是表的分片過多,並且由於沒有明確定義的分佈列,許多關係特性不可用。從 Citus 11.0 開始,現有的附加分散式表將是唯讀的。我們建議切換到雜湊分佈表。
  • 分散式 cstore_fdw 表是分散式表,其中分片是使用 cstore_fdw 擴充套件的外部表。 由於 Citus 具有內建的列存取方法,因此現在不推薦使用分散式表與 cstore_fdw 的組合。我們建議在升級到 Citus 11.0 之前轉換為列存取方法。

等等,我的分片在哪裡?

如果您以前使用過 Citus,您可能偶爾會連線到您的工作節點以檢視將資料儲存在分散式表和參照表中的分片。 每個工作節點都會有一組不同的分片,例如:

\d
            List of relations
┌────────┬──────────────┬───────┬───────┐
│ Schema │     Name     │ Type  │ Owner │
├────────┼──────────────┼───────┼───────┤
│ public │ citus_tables │ view  │ marco │
│ public │ ref_102040   │ table │ marco │
│ public │ test_102105  │ table │ marco │
│ public │ test_102107  │ table │ marco │
└────────┴──────────────┴───────┴───────┘

在 Citus 11 中,當您連線到任何工作節點時,您會看到分散式表和參照表,但看不到分片:

\d
            List of relations
┌────────┬──────────────┬───────┬───────┐
│ Schema │     Name     │ Type  │ Owner │
├────────┼──────────────┼───────┼───────┤
│ public │ citus_tables │ view  │ marco │
│ public │ ref          │ table │ marco │
│ public │ test         │ table │ marco │
└────────┴──────────────┴───────┴───────┘
(3 rows)

很酷的是叢集中的每個節點現在看起來都一樣,但是分片在哪裡?

我們發現使用者和各種工具會因為看到分散式表和分片的混合而感到困惑。例如,pg_dump 將嘗試轉儲分片和分散式表。因此,我們從目錄查詢中隱藏了分片,但它們仍然存在,如果需要,您可以直接查詢它們。

對於需要在特定應用程式中檢視分片的情況,我們引入了一個新設定:

-- show shards only to pgAdmin and psql (based on their application_name):
set citus.show_shards_for_app_name_prefixes to 'pgAdmin,psql';

-- show shards to all applications:
set citus.show_shards_for_app_name_prefixes to '*';

\d
            List of relations
┌────────┬──────────────┬───────┬───────┐
│ Schema │     Name     │ Type  │ Owner │
├────────┼──────────────┼───────┼───────┤
│ public │ citus_tables │ view  │ marco │
│ public │ ref          │ table │ marco │
│ public │ ref_102040   │ table │ marco │
│ public │ test         │ table │ marco │
│ public │ test_102105  │ table │ marco │
│ public │ test_102107  │ table │ marco │
└────────┴──────────────┴───────┴───────┘
(6 rows)

Citus 11 中的隱藏預覽功能:分散式表上的觸發器

觸發器是一個重要的 Postgres 特性,用於維護複雜的資料模型——以及更廣泛的關聯式資料庫。 當插入、更新或刪除行時,觸發器函數可以對資料庫執行其他操作。 由於所有 Citus 節點現在都有後設資料,分散式表的分片上的觸發器現在可以從儲存分片的工作節點對其他分散式表執行操作。

Citus 的觸發器方法可以很好地擴充套件,因為 Postgres 觸發器呼叫被下推到每個分片。然而,Citus 目前無法知道觸發器函數會做什麼,這意味著它可以做一些導致事務問題的事情。 例如,如果觸發器函數嘗試存取其他分片,它可能看不到一些未提交的寫入。 避免這種情況的方法是僅從觸發函數存取位於同一位置的分片鍵。目前,我們要求使用者使用 citus.enable_unsafe_triggers 設定顯式啟用觸發器:

CREATE TABLE data (key text primary key, value jsonb);
SELECT create_distributed_table('data','key');

CREATE TABLE data_audit (operation text, key text, new_value jsonb, change_time timestamptz default now());
SELECT create_distributed_table('data_audit','key', colocate_with := 'data');

-- we know this function only writes to a co-located table using the same key
CREATE OR REPLACE FUNCTION audit_trigger()
RETURNS trigger
AS $$
DECLARE
BEGIN
    INSERT INTO data_audit VALUES (TG_OP, Coalesce(OLD.key, NEW.key), NEW.value);
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

-- so, it is safe to enable triggers on distributed tables
SET citus.enable_unsafe_triggers TO on;

CREATE TRIGGER data_audit_trigger
AFTER INSERT OR UPDATE OR DELETE ON data
FOR EACH ROW EXECUTE FUNCTION audit_trigger();

只要您小心地只存取位於同一位置的鍵,使用 Citus 的觸發器為您提供了一種利用自動 schema 和 metadata 同步的好方法,而不必在節點之間進行負載均衡查詢。 通過將更多工作推入觸發函數,需要更少的分散式查詢和網路往返,從而提高整體可伸縮性。