DockerでPostgreSQL Citusを構築してみた

citus

DockerでPostgreSQL Citusを構築してみた際の備忘録です。yamlファイルと初期設定用のsqlファイルを準備しているので起動したらすぐに動作確認できます。※コピペで行けます。

構成はコーディネーター1台、ワーカー2台です。必要に応じてワーカーを増やしたり分散設定を変更してもらえればと思います。

下記は不要かも知れませんが、CItusの概要が続きます。

Citusとは?

近年、データ量の爆発的な増加に伴い、従来のデータベースシステムでは処理能力が限界に達するケースが増えています。そこで注目されているのが、PostgreSQLの拡張機能である「Citus」です。Citusは、PostgreSQLを分散データベースとして拡張し、大規模なデータ処理を効率的に行うことを可能にします。Citusは、PostgreSQLを分散データベースとして拡張するオープンソースの拡張機能です。Citusを使用することで、複数のPostgreSQLノードを連携させ、大規模なデータセットを効率的に処理することができます。Citusは、特に以下のような用途に適しています。

  • 大規模なデータ分析
  • リアルタイム分析
  • マルチテナントアプリケーション

Citusの主な特徴

  • 水平スケーラビリティ:複数のノードにデータを分散することで、処理能力を向上させます。
  • PostgreSQLとの互換性:既存のPostgreSQLアプリケーションをほとんど変更せずにCitusに移行できます。
  • SQLのサポート:標準的なSQLクエリを使用して、分散されたデータにアクセスできます。
  • 高い可用性:データのレプリケーションにより、ノード障害時でもデータ損失を防ぎます。

DockerでCitusを構築するメリット

Dockerを使用することで、Citusのクラスタ環境を簡単に構築・管理できます。Dockerコンテナを使用することで、異なる環境でも同じようにCitusをデプロイでき、環境構築の手間を大幅に削減できます。

構築手順

  1. Docker Desktopのインストールまず、Docker Desktopをインストールします。Docker Desktopは、WindowsやMacでDockerコンテナを実行するためのアプリケーションです。
  2. YAMLファイルの作成次に、Docker Composeを使用してCitusクラスタを構築するためのYAMLファイルを作成します。以下は、コーディネーター1台、ワーカー2台のCitusクラスタを構築するYAMLファイルの例です。

compose.yaml

services:
coordinator:
image: citusdata/citus:12.1
container_name: citus_coordinator
environment:
POSTGRES_PASSWORD: postgres
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql # 初期化SQLファイルをマウント
ports:
- "5432:5432"
networks:
citus-net:
aliases:
- coordinator
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -h citus_coordinator"]
interval: 10s
timeout: 5s
retries: 10
depends_on:
worker1:
condition: service_healthy
worker2:
condition: service_healthy

worker1:
image: citusdata/citus:12.1
container_name: citus_worker1
environment:
POSTGRES_PASSWORD: postgres
networks:
citus-net:
aliases:
- worker1
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -h citus_worker1"]
interval: 10s
timeout: 5s
retries: 10

worker2:
image: citusdata/citus:12.1
container_name: citus_worker2
environment:
POSTGRES_PASSWORD: postgres
networks:
citus-net:
aliases:
- worker2
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -h citus_worker2"]
interval: 10s
timeout: 5s
retries: 10

networks:
citus-net:
driver: bridge

services:コンテナの定義

coordinator:コーディネーターノードの設定

worker1, worker2:ワーカーノードの設定

image:使用するDockerイメージ

container_name:コンテナ名

environment:環境変数

volumes:ボリュームのマウント

ports:ポートのマッピング

networks:ネットワークの設定

depends_on:依存関係

networks:ネットワークの定義

citus-net:ネットワーク名

driver:ネットワークドライバ

3.初期化SQLファイルの作成Citusクラスタの初期設定を行うためのSQLファイルを作成します。以下は、初期化SQLファイルの例です。

init.sql

-- レプリケーションファクターの設定(重要)
SET citus.shard_replication_factor = 2;

-- ワーカーの準備待機
SELECT pg_sleep(20);

-- ワーカーノード登録
SELECT citus_set_coordinator_host('coordinator', 5432);
SELECT citus_add_node('citus_worker1', 5432); -- コンテナ名を明示
SELECT citus_add_node('citus_worker2', 5432); -- コンテナ名を明示

-- テストテーブル作成
CREATE TABLE test_table (
ID SERIAL PRIMARY KEY,
date DATE,
Agencyname TEXT,
amount NUMERIC
);

-- 分散設定(シャード数4指定)
SELECT create_distributed_table('test_table', 'id', shard_count => 4);

-- テストデータ挿入
INSERT INTO test_table (date, Agencyname, amount) VALUES
('2025-02-02', '営業部', 100000),
('2025-02-03', '開発部', 2500000),
('2025-02-04', '人事部', 980000),
('2025-02-05', '経理部', 1500000),
('2025-02-06', '広報部', 750000);

citus.shard_replication_factor:レプリケーションファクターの設定(データの複製数)

citus_set_coordinator_host:コーディネーターノードの登録

citus_add_node:ワーカーノードの登録

create_distributed_table:分散テーブルの作成

shard_count:シャード数(データの分割数)

4.Citusクラスタの起動YAMLファイルと初期化SQLファイルを作成したら、以下のコマンドを実行してCitusクラスタを起動します。docker-compose up -d このコマンドを実行すると、コーディネーターとワーカーのコンテナが起動し、Citusクラスタが構築されます。

5.Citusクラスタへの接続Citusクラスタが起動したら、psqlなどのPostgreSQLクライアントを使用してコーディネーターノードに接続します。psql -h localhost -p 5432 -U postgres -W 接続後、初期化SQLファイルで作成したテストテーブルにアクセスできることを確認します。

6.動作確認コーディネーターノードに接続し、以下のコマンドを実行して、分散テーブルの状態を確認します。SELECT * FROM citus_tables; このコマンドを実行すると、分散テーブルの情報が表示されます。また、以下のコマンドを実行して、ワーカーノードの状態を確認します。SELECT * FROM citus_workers; このコマンドを実行すると、ワーカーノードの情報が表示されます。

参考ログ

起動後のテストテーブル確認

postgres=# SELECT * FROM test_table;
id | date | agencyname | amount
----+------------+------------+---------
1 | 2025-02-02 | 営業部 | 100000
5 | 2025-02-06 | 広報部 | 750000
3 | 2025-02-04 | 人事部 | 980000
4 | 2025-02-05 | 経理部 | 1500000
2 | 2025-02-03 | 開発部 | 2500000
(5 rows)

起動後のテストテーブル確認

postgres=# SELECT * FROM pg_dist_node;
nodeid | groupid | nodename | nodeport | noderack | hasmetadata | isactive | noderole | nodecluster | metadatasynced | shouldhaveshards
--------+---------+---------------+----------+----------+-------------+----------+----------+-------------+----------------+------------------
1 | 0 | coordinator | 5432 | default | t | t | primary | default | t | f
2 | 1 | citus_worker1 | 5432 | default | t | t | primary | default | t | t
3 | 2 | citus_worker2 | 5432 | default | t | t | primary | default | t | t
(3 rows)

version確認

# SELECT version();
version
---------------------------------------------------------------------------------------------------------------------
PostgreSQL 16.6 (Debian 16.6-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
(1 row)

citus version確認

# SELECT citus_version();
citus_version
----------------------------------------------------------------------------------------
Citus 12.1.6 on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
(1 row)

シャーディング情報を確認

postgres=# SELECT * FROM pg_dist_shard;
logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue
--------------+---------+--------------+---------------+---------------
test_table | 102008 | t | -2147483648 | -1073741825
test_table | 102009 | t | -1073741824 | -1
test_table | 102010 | t | 0 | 1073741823
test_table | 102011 | t | 1073741824 | 2147483647
(4 rows)
クエリ結果から、テーブルが4つのシャード(102008, 102009, 102010, 102011)に分割されていることがわかります。
これは、初期設定で指定した「シャード数4」(shard_count => 4;)に対応しています。
※shardstorage t: 通常のテーブルとして格納されている(デフォルト値)

まとめ

需要があるかわかりませんが、Dockerを使用してPostgreSQL Citusのクラスタ環境を構築する手順を公開しました。

Dockerを使用することで、意外と簡単に構築することができますので興味のある方は使っていただけると幸いです。

© 2025 サプリスト通信