1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Azure Cosmos DB for PostgreSQL で Citus による PostgreSQL のシャーディングを試してみた

Last updated at Posted at 2025-07-23

Azure Cosmos DB for PostgreSQL で分散データベース(Citus)を動かしてみましたのでメモを共有します。

Azure Cosmos DB for PostgreSQL は、オープンソースの Citus により分散されたテーブルを提供する PostgreSQL のマネージドサービスです。詳細は以下のページをご確認ください。

今回使用したデータは、OpenStreetMap のデータです。ビルのポリゴンから、中心座標を計算して、簡易的なアルゴリズムでメッシュに分割したものを、分散テーブル(シャーディング)してみます。

準備

まずは、Azureのポータルで Azure Cosmos DB for PostgreSQL を作成した後に、OpenStreetMap のデータを PostgreSQL にインポートします。インポートには、imposm3を使用します。

Azure Cosmos DB for PostgreSQL を作成

まずは、Azure のポータルから、最小構成で作成してみます。

image.png

PostgreSQL は、バージョン 16、Scale は、1ノードの最小構成です。

image.png

作成する構成の見積もりが右側に表示されます。

image.png

自宅のPCからアクセスできるように、ネットワークの設定をしておきます。

image.png

今回は、デフォルトの設定にしています。

image.png

今回は、デフォルトの設定にしています。

image.png

作成する Azure Cosmos DB for PostgreSQL の構成を確認した後に作成します。

image.png

これで、Azure Cosmos DB for PostgreSQLが作成できました。
作成できたら Settings の Connection strings から接続方法をメモしておいてください。("Show connection strings for" の "*-c" は、コーディネータを示しています)

image.png

OpenStreetMap のデータを取得

OpenStreetMap の pbf ファイルをダウンロードします。今回は日本のデータを取得しています。

wget https://download.geofabrik.de/asia/japan-latest.osm.pbf

Azure Cosmos DB for PostgreSQL で PostGIS を有効にする

psql で Azure Cosmos DB for PostgreSQL のコーディネータに接続します。

psql "host=c-kentapgsql.xxx.postgres.cosmos.azure.com port=5432 dbname=gis user=citus password={your password} sslmode=require"

create_extensionを使ってExtentionを有効にします。

SELECT create_extension('postgis');

imposm3 で PostgreSQL にインポート

go でビルドとインストールを実行します。

go install github.com/omniscale/imposm3/cmd/imposm@latest

imposm3 の設定ファイルを使用したいので、リポジトリもクローンしておきます。

git clone https://github.com/omniscale/imposm3.git

Azure Cosmos DB for PostgreSQL の Connection strings を参考にして、imposm で OpenStreetMap のデータをインポートします。

imposm import \
-connection postgis://citus:{your password}@c-kentapgsql.xxx.postgres.cosmos.azure.com:5432/gis?sslmode=require \
-mapping ./imposm3/example-mapping.json \
-read japan-latest.osm.pbf \
-write

Azure Cosmos DB for PostgreSQL に インポートしたデータをプロダクションとしてデプロイ(テーブルのスキーマを変更)します。(imposm の仕組みのようですね)

imposm import \
-connection postgis://citus:{your password}@c-kentapgsql.xxx.postgres.cosmos.azure.com:5432/gis?sslmode=require \
-mapping ./imposm3/example-mapping.json \
-deployproduction

テーブルを分散させる準備

Azure Cosmos DB for PostgreSQL の Connection strings を参考にして、psqlコマンドで分散に使用するカラムを用意します。今回は、Geometry で分散させようと思いますので、Geometry をメッシュにして、メッシュで分散させようと思います。

psql で Azure Cosmos DB for PostgreSQL のコーディネータに接続します。

psql "host=c-kentapgsql.xxx.postgres.cosmos.azure.com port=5432 dbname=gis user=citus password={your password} sslmode=require"

imposm が作成した osm_buildings に mesh1 と mesh2 のカラムを作成します。

ALTER TABLE osm_buildings ALTER COLUMN mesh1 TYPE varchar(4);
ALTER TABLE osm_buildings ALTER COLUMN mesh2 TYPE varchar(6);

テーブルを確認してみると、以下のような感じになりました。

\d osm_buildings
                                     Table "public.osm_buildings"
  Column  |          Type           | Collation | Nullable |                  Default                  
----------+-------------------------+-----------+----------+-------------------------------------------
 id       | bigint                  |           | not null | nextval('osm_buildings_id_seq'::regclass)
 osm_id   | bigint                  |           | not null | 
 name     | character varying       |           |          | 
 type     | character varying       |           |          | 
 geometry | geometry(Geometry,3857) |           |          | 
 mesh1    | character varying(4)    |           |          | 
 mesh2    | character varying(6)    |           |          | 
Indexes:
    "osm_buildings_pkey" PRIMARY KEY, btree (osm_id, id)
    "osm_buildings_geom" gist (geometry)

geometry からメッシュを作成するための関数を用意します。(注意:今回は簡易的な実装として独自のメッシュアルゴリズムでメッシュIDを作成しているため、実際の地域メッシュとは異なります。)

-- 簡易的な1次メッシュ生成(本当は桁を合わせて0パディングしないといけない)
CREATE OR REPLACE FUNCTION meshcode1(geom geometry)
RETURNS varchar AS $$
DECLARE
    x_str varchar;
    y_str varchar;
    x_head varchar;
    y_head varchar;
BEGIN
    x_str := CAST(FLOOR(ST_X(ST_Centroid(geom))) AS TEXT);
    y_str := CAST(FLOOR(ST_Y(ST_Centroid(geom))) AS TEXT);
    x_head := SUBSTRING(x_str FROM 1 FOR 2);
    y_head := SUBSTRING(y_str FROM 1 FOR 2);
    RETURN x_head || y_head;
END;
$$ LANGUAGE plpgsql IMMUTABLE;

-- 簡易的な2次メッシュ生成(本当は桁を合わせて0パディングしないといけない)
CREATE OR REPLACE FUNCTION meshcode2(geom geometry)
RETURNS varchar AS $$
DECLARE
    x_str varchar;
    y_str varchar;
    x_head varchar;
    y_head varchar;
BEGIN
    x_str := CAST(FLOOR(ST_X(ST_Centroid(geom))) AS TEXT);
    y_str := CAST(FLOOR(ST_Y(ST_Centroid(geom))) AS TEXT);
    x_head := SUBSTRING(x_str FROM 1 FOR 3);
    y_head := SUBSTRING(y_str FROM 1 FOR 3);
    RETURN x_head || y_head;
END;
$$ LANGUAGE plpgsql IMMUTABLE;

関数の動作を確認してみます。

SELECT ST_AsText(ST_Centroid(geometry)), meshcode1(geometry), meshcode2(geometry) FROM osm_buildings LIMIT 10;

                  st_astext                   | meshcode1 | meshcode2 
----------------------------------------------+-----------+-----------
 POINT(15029170.262225706 4220685.79198919)   | 1542      | 150422
 POINT(15481058.600412643 4567618.2309200205) | 1545      | 154456
 POINT(14518889.312693825 3975316.5797044816) | 1439      | 145397
 POINT(14518989.374650465 3975587.9473769744) | 1439      | 145397
 POINT(14519045.061951755 3976202.229020028)  | 1439      | 145397
 POINT(15225775.071204912 4205006.365611101)  | 1542      | 152420
 POINT(15226012.945533827 4204902.760684182)  | 1542      | 152420
 POINT(15226580.36520575 4204711.103804201)   | 1542      | 152420
 POINT(15226487.838102747 4204611.561736697)  | 1542      | 152420
 POINT(15226000.069640627 4204607.961778946)  | 1542      | 152420
(10 rows)

うまく動いていそうなので、osm_buildings テーブルのカラムを更新します。

UPDATE osm_buildings SET mesh1 = meshcode1(geometry), mesh2 = meshcode2(geometry);

テーブルを分散化するために、一旦プライマリキーを削除します。

ALTER TABLE osm_buildings DROP CONSTRAINT osm_buildings_pkey;

mesh1 カラムを使用して分散化の設定をします。

SELECT create_distributed_table('osm_buildings', 'mesh1');

NOTICE:  Copying data from local table...
NOTICE:  copying the data has completed
DETAIL:  The local data in the table is no longer visible, but is still on disk.
HINT:  To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.osm_buildings$$)
 create_distributed_table 

プライマリキーを再度設定(ついでに mesh1 と mesh2 も追加)しておきます。

ALTER TABLE osm_buildings ADD PRIMARY KEY (mesh1, mesh2, osm_id, id);

テーブルの分散を解除するときは以下の SQL になります。

SELECT undistribute_table('osm_buildings');

構成毎の処理速度

最小構成からスケールアップしてスケールアウトする3段階で処理速度を確認してみようと思います。

1台の最小構成で処理速度を確認

1台 2vCore, 8GiB RAM、Storage 128 GiB、CoordinatorとWorker構成で処理速度確認

image.png

1台の最小構成の Azure Cosmos DB for PostgreSQL で処理速度を確認してみます。

\timing

Timing is on.
SELECT COUNT(DISTINCT mesh1) FROM osm_buildings;

 count 
-------
    47
(1 row)

Time: 6010.955 ms (00:06.011)
SELECT COUNT(DISTINCT mesh2) FROM osm_buildings;
 count 
-------
  1089
(1 row)

Time: 6515.639 ms (00:06.516)

テーブルのデータサイズも確認しておきます。

SELECT
  schemaname,
  relname AS table_name,
  pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
  pg_size_pretty(pg_relation_size(relid)) AS table_only_size,
  pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_and_toast_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;

    schemaname     |          table_name           | total_size | table_only_size | index_and_toast_size 
-------------------+-------------------------------+------------+-----------------+----------------------
 public            | osm_buildings                 | 7375 MB    | 5141 MB         | 2234 MB
 public            | osm_roads                     | 3189 MB    | 2456 MB         | 733 MB
 public            | osm_landusages                | 1178 MB    | 811 MB          | 367 MB
 public            | osm_waterways                 | 414 MB     | 354 MB          | 60 MB
 public            | osm_roads_gen1                | 220 MB     | 150 MB          | 70 MB
 public            | osm_roads_gen0                | 212 MB     | 142 MB          | 70 MB
 public            | osm_admin                     | 159 MB     | 26 MB           | 133 MB
 public            | osm_waterways_gen1            | 139 MB     | 91 MB           | 49 MB
 public            | osm_waterareas                | 135 MB     | 99 MB           | 36 MB
 public            | osm_waterways_gen0            | 125 MB     | 76 MB           | 49 MB
 public            | osm_landusages_gen1           | 103 MB     | 77 MB           | 26 MB
 public            | osm_transport_points          | 41 MB      | 24 MB           | 17 MB
 public            | osm_barrierways               | 30 MB      | 21 MB           | 9760 kB
 public            | osm_landusages_gen0           | 27 MB      | 23 MB           | 3584 kB
 public            | osm_barrierpoints             | 12 MB      | 6784 kB         | 5552 kB
 public            | osm_amenities                 | 9736 kB    | 5856 kB         | 3880 kB
 public            | osm_housenumbers              | 9144 kB    | 5760 kB         | 3384 kB
 public            | spatial_ref_sys               | 7144 kB    | 6896 kB         | 248 kB
 public            | osm_waterareas_gen1           | 6160 kB    | 5216 kB         | 944 kB
 public            | osm_transport_areas           | 4384 kB    | 3392 kB         | 992 kB
 public            | osm_places                    | 1968 kB    | 1152 kB         | 816 kB
 public            | osm_aeroways                  | 1816 kB    | 1344 kB         | 472 kB
 public            | osm_waterareas_gen0           | 1488 kB    | 1280 kB         | 208 kB
 public            | osm_housenumbers_interpolated | 40 kB      | 8192 bytes      | 32 kB
 cron              | job                           | 24 kB      | 0 bytes         | 24 kB
 partman           | part_config                   | 24 kB      | 0 bytes         | 24 kB
 cron              | job_run_details               | 16 kB      | 0 bytes         | 16 kB
 partman           | part_config_sub               | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | chunk                         | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | stripe                        | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | options                       | 8192 bytes | 0 bytes         | 8192 bytes
 columnar_internal | chunk_group                   | 8192 bytes | 0 bytes         | 8192 bytes
(32 rows)

1台でちょっとスケールアップした構成で処理速度を確認

1台 4vCore, 16GiB RAM、Storage 128 GiB、CoordinatorとWorker構成で処理速度確認します。

1台の最小構成の Azure Cosmos DB for PostgreSQL を、Settings の Scale から 1台 4vCore, 32GiB RAM、Storage 512 GiB、Coordinator+Worker構成にスケールアップしています。

image.png

同じように処理速度を確認します。

\timing

Timing is on.
SELECT COUNT(DISTINCT mesh1) FROM osm_buildings;

 count 
-------
    47
(1 row)

Time: 4011.069 ms (00:04.011)
SELECT COUNT(DISTINCT mesh2) FROM osm_buildings;

 count 
-------
  1089
(1 row)

Time: 4195.404 ms (00:04.195)

3台でスケールアウトした構成で処理速度を確認

さいごに、2台 4vCore, 32GiB RAM、Storage 512 GiB、Worker x 2 構成、1台 4vCore, 16GiB RAM、Storage 512 GiB、Coordinator x 1 で処理速度確認します。

image.png

分散ノードを確認します。

SELECT * FROM pg_dist_node;

 nodeid | groupid |                            nodename                            | nodeport | noderack | hasmetadata | isactive | noderole | nodecluster | metadatasynced | shouldhaveshards 
--------+---------+----------------------------------------------------------------+----------+----------+-------------+----------+----------+-------------+----------------+------------------
      1 |       0 | private-c-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com  |     5432 | default  | t           | t        | primary  | default     | t              | t
      2 |       1 | private-w0-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com |     5432 | default  | t           | t        | primary  | default     | t              | t
      3 |       2 | private-w1-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com |     5432 | default  | t           | t        | primary  | default     | t              | t
(3 rows)

分散テーブルの確認

SELECT logicalrelid::regclass AS table_name
FROM pg_dist_partition;

  table_name   
---------------
 osm_buildings
(1 row)

リバランス前(スケールを変更した直後)

image.png

スケールを変更した直後で処理時間を計測してみます。

\timing
Timing is on.
SELECT COUNT(DISTINCT mesh1) FROM osm_buildings;

 count 
-------
    47
(1 row)

Time: 4011.069 ms (00:04.011)
SELECT COUNT(DISTINCT mesh2) FROM osm_buildings;
 count 
-------
  1089
(1 row)

Time: 4195.404 ms (00:04.195)

コーディネーターのテーブルサイズを確認します。

 SELECT
  schemaname,
  relname AS table_name,
  pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
  pg_size_pretty(pg_relation_size(relid)) AS table_only_size,
  pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_and_toast_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;

    schemaname     |          table_name           | total_size | table_only_size | index_and_toast_size 
-------------------+-------------------------------+------------+-----------------+----------------------
 public            | osm_buildings                 | 7375 MB    | 5141 MB         | 2234 MB
 public            | osm_roads                     | 3189 MB    | 2456 MB         | 733 MB
 public            | osm_landusages                | 1178 MB    | 811 MB          | 367 MB
 public            | osm_waterways                 | 414 MB     | 353 MB          | 60 MB
 public            | osm_roads_gen1                | 220 MB     | 150 MB          | 70 MB
 public            | osm_roads_gen0                | 212 MB     | 142 MB          | 70 MB
 public            | osm_admin                     | 158 MB     | 25 MB           | 133 MB
 public            | osm_waterways_gen1            | 139 MB     | 90 MB           | 49 MB
 public            | osm_waterareas                | 135 MB     | 98 MB           | 36 MB
 public            | osm_waterways_gen0            | 124 MB     | 76 MB           | 49 MB
 public            | osm_landusages_gen1           | 103 MB     | 77 MB           | 26 MB
 public            | osm_transport_points          | 41 MB      | 24 MB           | 17 MB
 public            | osm_barrierways               | 30 MB      | 20 MB           | 9784 kB
 public            | osm_landusages_gen0           | 27 MB      | 23 MB           | 3608 kB
 public            | osm_barrierpoints             | 12 MB      | 6496 kB         | 5552 kB
 public            | osm_amenities                 | 9736 kB    | 5856 kB         | 3880 kB
 public            | osm_housenumbers              | 8992 kB    | 5608 kB         | 3384 kB
  public            | spatial_ref_sys               | 7144 kB    | 6896 kB         | 248 kB
 public            | osm_waterareas_gen1           | 6184 kB    | 5216 kB         | 968 kB
 public            | osm_transport_areas           | 4408 kB    | 3392 kB         | 1016 kB
 public            | osm_places                    | 1944 kB    | 1128 kB         | 816 kB
 public            | osm_aeroways                  | 1816 kB    | 1344 kB         | 472 kB
 public            | osm_waterareas_gen0           | 1512 kB    | 1280 kB         | 232 kB
 public            | osm_housenumbers_interpolated | 40 kB      | 8192 bytes      | 32 kB
 cron              | job                           | 24 kB      | 0 bytes         | 24 kB
 partman           | part_config                   | 24 kB      | 0 bytes         | 24 kB
 cron              | job_run_details               | 16 kB      | 0 bytes         | 16 kB
 partman           | part_config_sub               | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | chunk                         | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | stripe                        | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | options                       | 8192 bytes | 0 bytes         | 8192 bytes
 columnar_internal | chunk_group                   | 8192 bytes | 0 bytes         | 8192 bytes
(32 rows)

各ワーカーDBに直接接続して、各ワーカーノードのテーブルを確認します。

まずは、1台目のワーカーノードに接続します。

psql "host=w0-kentapgsql.xxx.postgres.cosmos.azure.com port=5432 dbname=gis user
=citus password={your password} sslmode=require"

1台目のワーカーノードの各テーブルのサイズを確認します。

 SELECT
  schemaname,
  relname AS table_name,
  pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
  pg_size_pretty(pg_relation_size(relid)) AS table_only_size,
  pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_and_toast_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;

    schemaname     |   table_name    | total_size | table_only_size | index_and_toast_size 
-------------------+-----------------+------------+-----------------+----------------------
 public            | spatial_ref_sys | 7144 kB    | 6896 kB         | 248 kB
 public            | osm_buildings   | 24 kB      | 0 bytes         | 24 kB
 cron              | job             | 24 kB      | 0 bytes         | 24 kB
 partman           | part_config     | 24 kB      | 0 bytes         | 24 kB
 cron              | job_run_details | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | stripe          | 16 kB      | 0 bytes         | 16 kB
 partman           | part_config_sub | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | chunk           | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | options         | 8192 bytes | 0 bytes         | 8192 bytes
 columnar_internal | chunk_group     | 8192 bytes | 0 bytes         | 8192 bytes
(10 rows)

2台目のワーカーノードに接続

psql "host=w1-kentapgsql.xxx.postgres.cosmos.azure.com port=5432 dbname=gis user=citus password={your password} sslmode=require"

各テーブルのサイズを確認

SELECT
 schemaname,
 relname AS table_name,
 pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
 pg_size_pretty(pg_relation_size(relid)) AS table_only_size,
 pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_and_toast_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;

   schemaname     |   table_name    | total_size | table_only_size | index_and_toast_size 
-------------------+-----------------+------------+-----------------+----------------------
public            | spatial_ref_sys | 7144 kB    | 6896 kB         | 248 kB
public            | osm_buildings   | 24 kB      | 0 bytes         | 24 kB
cron              | job             | 24 kB      | 0 bytes         | 24 kB
partman           | part_config     | 24 kB      | 0 bytes         | 24 kB
cron              | job_run_details | 16 kB      | 0 bytes         | 16 kB
columnar_internal | stripe          | 16 kB      | 0 bytes         | 16 kB
partman           | part_config_sub | 16 kB      | 0 bytes         | 16 kB
columnar_internal | chunk           | 16 kB      | 0 bytes         | 16 kB
columnar_internal | options         | 8192 bytes | 0 bytes         | 8192 bytes
columnar_internal | chunk_group     | 8192 bytes | 0 bytes         | 8192 bytes
(10 rows)

リバランス後(再分散)

分散データベースを「リバランス(再分散)」するには、Citus の rebalance_table_shards 関数や rebalance_table_shards_in_database 関数を使います。

特定テーブルのシャードをリバランスする

SELECT rebalance_table_shards('osm_buildings');

NOTICE:  Moving shard 102065 from private-c-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 to private-w0-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 ...
NOTICE:  Moving shard 102048 from private-c-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 to private-w1-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 ...
NOTICE:  Moving shard 102054 from private-c-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 to private-w1-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 ...
NOTICE:  Moving shard 102058 from private-c-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 to private-w0-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 ...
NOTICE:  Moving shard 102059 from private-c-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 to private-w1-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 ...
NOTICE:  Moving shard 102046 from private-c-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 to private-w0-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 ...
NOTICE:  Moving shard 102050 from private-c-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 to private-w1-kentapgsql.yjjdautcvi53fg.postgres.cosmos.azure.com:5432 ...
 rebalance_table_shards 
------------------------

また、データベース内のすべてのテーブルをリバランスする場合は、以下のコマンドで実行。クラスタ上のすべての分散テーブルのシャードが再分散されます。

SELECT rebalance_table_shards_in_database();

実行時の注意点

  • リバランス中は、対象テーブルへの書き込み/読み込みパフォーマンスが低下する場合があります。
  • 大規模データではリバランス完了まで時間がかかる場合があります。
  • 必ずコーディネータノードで実行してください。
  • 十分なバックアップがある状態での運用をおすすめします。

image.png

処理速度を計測してみます。

\timing
Timing is on.
SELECT COUNT(DISTINCT mesh1) FROM osm_buildings;

 count 
-------
    47
(1 row)

Time: 1932.354 ms (00:01.932)
SELECT COUNT(DISTINCT mesh2) FROM osm_buildings;
 count 
-------
  1089
(1 row)

Time: 1760.313 ms (00:01.760)

コーディネータのテーブルサイズを確認しておきます。

 SELECT
  schemaname,
  relname AS table_name,
  pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
  pg_size_pretty(pg_relation_size(relid)) AS table_only_size,
  pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_and_toast_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;

    schemaname     |          table_name           | total_size | table_only_size | index_and_toast_size 
-------------------+-------------------------------+------------+-----------------+----------------------
 public            | osm_buildings                 | 7375 MB    | 5141 MB         | 2234 MB
 public            | osm_roads                     | 3189 MB    | 2456 MB         | 733 MB
 public            | osm_landusages                | 1178 MB    | 811 MB          | 367 MB
 public            | osm_waterways                 | 414 MB     | 353 MB          | 60 MB
 public            | osm_roads_gen1                | 220 MB     | 150 MB          | 70 MB
 public            | osm_roads_gen0                | 212 MB     | 142 MB          | 70 MB
 public            | osm_admin                     | 158 MB     | 25 MB           | 133 MB
 public            | osm_waterways_gen1            | 139 MB     | 90 MB           | 49 MB
 public            | osm_waterareas                | 135 MB     | 98 MB           | 36 MB
 public            | osm_waterways_gen0            | 124 MB     | 76 MB           | 49 MB
 public            | osm_landusages_gen1           | 103 MB     | 77 MB           | 26 MB
 public            | osm_transport_points          | 41 MB      | 24 MB           | 17 MB
 public            | osm_barrierways               | 30 MB      | 20 MB           | 9784 kB
 public            | osm_landusages_gen0           | 27 MB      | 23 MB           | 3608 kB
 public            | osm_barrierpoints             | 12 MB      | 6496 kB         | 5552 kB
 public            | osm_amenities                 | 9736 kB    | 5856 kB         | 3880 kB
 public            | osm_housenumbers              | 8992 kB    | 5608 kB         | 3384 kB
 public            | spatial_ref_sys               | 7144 kB    | 6896 kB         | 248 kB
 public            | osm_waterareas_gen1           | 6184 kB    | 5216 kB         | 968 kB
 public            | osm_transport_areas           | 4408 kB    | 3392 kB         | 1016 kB
 public            | osm_places                    | 1944 kB    | 1128 kB         | 816 kB
 public            | osm_aeroways                  | 1816 kB    | 1344 kB         | 472 kB
 public            | osm_waterareas_gen0           | 1512 kB    | 1280 kB         | 232 kB
 public            | osm_housenumbers_interpolated | 40 kB      | 8192 bytes      | 32 kB
 cron              | job                           | 24 kB      | 0 bytes         | 24 kB
 partman           | part_config                   | 24 kB      | 0 bytes         | 24 kB
 cron              | job_run_details               | 16 kB      | 0 bytes         | 16 kB
 partman           | part_config_sub               | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | chunk                         | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | stripe                        | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | options                       | 8192 bytes | 0 bytes         | 8192 bytes
 columnar_internal | chunk_group                   | 8192 bytes | 0 bytes         | 8192 bytes
(32 rows)

シャードキーのハッシュ値が 32に分割(citus.shard_count)されていることを確認。

SELECT * FROM pg_dist_shard;

 logicalrelid  | shardid | shardstorage | shardminvalue | shardmaxvalue 
---------------+---------+--------------+---------------+---------------
 osm_buildings |  102040 | t            | -2147483648   | -2013265921
 osm_buildings |  102041 | t            | -2013265920   | -1879048193
 osm_buildings |  102042 | t            | -1879048192   | -1744830465
 osm_buildings |  102043 | t            | -1744830464   | -1610612737
 osm_buildings |  102044 | t            | -1610612736   | -1476395009
 osm_buildings |  102045 | t            | -1476395008   | -1342177281
 osm_buildings |  102046 | t            | -1342177280   | -1207959553
 osm_buildings |  102047 | t            | -1207959552   | -1073741825
 osm_buildings |  102048 | t            | -1073741824   | -939524097
 osm_buildings |  102049 | t            | -939524096    | -805306369
 osm_buildings |  102050 | t            | -805306368    | -671088641
 osm_buildings |  102051 | t            | -671088640    | -536870913
 osm_buildings |  102052 | t            | -536870912    | -402653185
 osm_buildings |  102053 | t            | -402653184    | -268435457
 osm_buildings |  102054 | t            | -268435456    | -134217729
 osm_buildings |  102055 | t            | -134217728    | -1
 osm_buildings |  102056 | t            | 0             | 134217727
 osm_buildings |  102057 | t            | 134217728     | 268435455
 osm_buildings |  102058 | t            | 268435456     | 402653183
 osm_buildings |  102059 | t            | 402653184     | 536870911
 osm_buildings |  102060 | t            | 536870912     | 671088639
 osm_buildings |  102061 | t            | 671088640     | 805306367
 osm_buildings |  102062 | t            | 805306368     | 939524095
 osm_buildings |  102063 | t            | 939524096     | 1073741823
 osm_buildings |  102064 | t            | 1073741824    | 1207959551
 osm_buildings |  102065 | t            | 1207959552    | 1342177279
 osm_buildings |  102066 | t            | 1342177280    | 1476395007
 osm_buildings |  102067 | t            | 1476395008    | 1610612735
 osm_buildings |  102068 | t            | 1610612736    | 1744830463
 osm_buildings |  102069 | t            | 1744830464    | 1879048191
 osm_buildings |  102070 | t            | 1879048192    | 2013265919
 osm_buildings |  102071 | t            | 2013265920    | 2147483647
(32 rows)

シャードが、各Workerノードに割り当てられていることを確認。

SELECT * FROM citus_shards;

  table_name   | shardid |      shard_name      | citus_table_type | colocation_id |                            nodename                            | nodeport | shard_size 
---------------+---------+----------------------+------------------+---------------+----------------------------------------------------------------+----------+------------
 osm_buildings |  102040 | osm_buildings_102040 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.cosmos.azure.com  |     5432 |   50659328
 osm_buildings |  102041 | osm_buildings_102041 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.cosmos.azure.com  |     5432 |   15835136
 osm_buildings |  102042 | osm_buildings_102042 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.cosmos.azure.com  |     5432 |      24576
 osm_buildings |  102043 | osm_buildings_102043 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.cosmos.azure.com  |     5432 |      24576
 osm_buildings |  102044 | osm_buildings_102044 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.cosmos.azure.com  |     5432 |  115384320
 osm_buildings |  102045 | osm_buildings_102045 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.cosmos.azure.com  |     5432 |      24576
 osm_buildings |  102046 | osm_buildings_102046 | distributed      |             5 | private-w0-kentapgsql.xxx.postgres.cosmos.azure.com |     5432 |  458407936
 osm_buildings |  102047 | osm_buildings_102047 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |    2572288
 osm_buildings |  102048 | osm_buildings_102048 | distributed      |             5 | private-w1-kentapgsql.xxx.postgres.
cosmos.azure.com |     5432 | 1751113728
 osm_buildings |  102049 | osm_buildings_102049 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |   14352384
 osm_buildings |  102050 | osm_buildings_102050 | distributed      |             5 | private-w1-kentapgsql.xxx.postgres.
cosmos.azure.com |     5432 |  446210048
 osm_buildings |  102051 | osm_buildings_102051 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |      24576
 osm_buildings |  102052 | osm_buildings_102052 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |  123256832
 osm_buildings |  102053 | osm_buildings_102053 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |  132177920
 osm_buildings |  102054 | osm_buildings_102054 | distributed      |             5 | private-w1-kentapgsql.xxx.postgres.
cosmos.azure.com |     5432 |  817176576
 osm_buildings |  102055 | osm_buildings_102055 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.cosmos.azure.com  |     5432 |     589824
 osm_buildings |  102056 | osm_buildings_102056 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |      24576
 osm_buildings |  102057 | osm_buildings_102057 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |  252690432
 osm_buildings |  102058 | osm_buildings_102058 | distributed      |             5 | private-w0-kentapgsql.xxx.postgres.
cosmos.azure.com |     5432 |  653393920
 osm_buildings |  102059 | osm_buildings_102059 | distributed      |             5 | private-w1-kentapgsql.xxx.postgres.
cosmos.azure.com |     5432 |  503881728
 osm_buildings |  102060 | osm_buildings_102060 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |  165601280
 osm_buildings |  102061 | osm_buildings_102061 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |     196608
 osm_buildings |  102062 | osm_buildings_102062 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |      98304
 osm_buildings |  102063 | osm_buildings_102063 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |      24576
 osm_buildings |  102064 | osm_buildings_102064 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |  170229760
 osm_buildings |  102065 | osm_buildings_102065 | distributed      |             5 | private-w0-kentapgsql.xxx.postgres.
cosmos.azure.com |     5432 | 2240716800
 osm_buildings |  102066 | osm_buildings_102066 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |   23207936
 osm_buildings |  102067 | osm_buildings_102067 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |    5464064
 osm_buildings |  102068 | osm_buildings_102068 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |  122445824
 osm_buildings |  102069 | osm_buildings_102069 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |    8380416
 osm_buildings |  102070 | osm_buildings_102070 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |      40960
 osm_buildings |  102071 | osm_buildings_102071 | distributed      |             5 | private-c-kentapgsql.xxx.postgres.c
osmos.azure.com  |     5432 |      24576
(32 rows)

1台目のワーカーのテーブルサイズを確認します。

psql "host=w0-kentapgsql.xxx.postgres.cosmos.azure.com port=5432 dbname=gis user=citus password={your password} sslmode=require"
SELECT
  schemaname,
  relname AS table_name,
  pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
  pg_size_pretty(pg_relation_size(relid)) AS table_only_size,
  pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_and_toast_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;

    schemaname     |   table_name    | total_size | table_only_size | index_and_toast_size 
-------------------+-----------------+------------+-----------------+----------------------
 public            | spatial_ref_sys | 7144 kB    | 6896 kB         | 248 kB
 public            | osm_buildings   | 24 kB      | 0 bytes         | 24 kB
 cron              | job             | 24 kB      | 0 bytes         | 24 kB
 partman           | part_config     | 24 kB      | 0 bytes         | 24 kB
 cron              | job_run_details | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | stripe          | 16 kB      | 0 bytes         | 16 kB
 partman           | part_config_sub | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | chunk           | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | options         | 8192 bytes | 0 bytes         | 8192 bytes
 columnar_internal | chunk_group     | 8192 bytes | 0 bytes         | 8192 bytes
(10 rows)

2台目のワーカーのテーブルサイズを確認。

psql "host=w1-kentapgsql.xxx.postgres.cosmos.azure.com port=5432 dbname=gis user=citus password={your password} sslmode=require"
SELECT
  schemaname,
  relname AS table_name,
  pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
  pg_size_pretty(pg_relation_size(relid)) AS table_only_size,
  pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_and_toast_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;

    schemaname     |   table_name    | total_size | table_only_size | index_and_toast_size 
-------------------+-----------------+------------+-----------------+----------------------
 public            | spatial_ref_sys | 7144 kB    | 6896 kB         | 248 kB
 public            | osm_buildings   | 24 kB      | 0 bytes         | 24 kB
 cron              | job             | 24 kB      | 0 bytes         | 24 kB
 partman           | part_config     | 24 kB      | 0 bytes         | 24 kB
 cron              | job_run_details | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | stripe          | 16 kB      | 0 bytes         | 16 kB
 partman           | part_config_sub | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | chunk           | 16 kB      | 0 bytes         | 16 kB
 columnar_internal | options         | 8192 bytes | 0 bytes         | 8192 bytes
 columnar_internal | chunk_group     | 8192 bytes | 0 bytes         | 8192 bytes
(10 rows)

まとめ

今回は、1台(コーディネータ + ワーカー)と3台(コーディネータ x 1、ワーカー x 2)構成で確認しましたが、4.011秒かかる処理が 1.932秒で処理されており、分散テーブルの威力を確認することができました。地図データを使う場合は、用途にもよりますが、行政区域単位で分散したりすると効率が良いかもしれません。

また、21台(1台当たり 32767 GiB)で1つのクラスターを作成したり、リードレプリカを他のリージョンに置くなど、PostgreSQLをハイパースケールな環境で使うことができそうです。

(以下は、設定だけしてみた画面です。料金が怖くてSaveボタンは押せませんでした。)

image.png

image.png

カラムナーストレージを使用すると、データを圧縮して効率よくストレージを使うことができるようですので、時間があるときに確認してみたいと思います。
(7/23追記、確認しましたー)

参考:Cosmos DB for PostgreSQLのパーティションとカラムナーストレージ

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?