次の方法で共有


チュートリアル: エラスティック クラスターを使用したマイクロサービスの設計

このチュートリアルでは、複数のマイクロサービスのストレージ バックエンドとして Azure Database for PostgreSQL を使用します。 このチュートリアルでは、このようなクラスターのセットアップと基本的な操作のサンプルを示します。 具体的には、次の方法を学習します。

  • [前提条件]
  • マイクロサービスのロールを作成する
  • psql ユーティリティを使用してロールと分散スキーマを作成する
  • サンプル データ用のテーブルを作成する
  • サービスを構成する
  • サービスを実行する
  • データベースを調べる

[前提条件]

次のいずれかの方法でエラスティック クラスターを作成します。

マイクロサービスのロールを作成する

エラスティック クラスター内に分散スキーマを動的に配置できます。 システムは、使用可能なノード全体にわたってそれらをユニット全体として再調整できるため、手動で割り当てなくてもクラスター リソース全体の効率が向上します。

マイクロサービス設計パターンにスキーマ シャーディングを適用する場合は、対応するマイクロサービスごとにデータベース スキーマを作成します。 また、データベースに接続するときは、マイクロサービスごとに個別の ROLE を使用します。 各ユーザーが接続すると、ロール名はsearch_pathの先頭に表示されます。 ロール名がスキーマ名と一致する場合、適切なsearch_pathを設定するためにアプリケーションを追加で変更する必要はありません。

この例では、次の 3 つのマイクロサービスを使用します。

  • ユーザー
  • time
  • ping

各サービスのデータベース ロールを作成します。

CREATE USER user_service;
CREATE USER time_service;
CREATE USER ping_service;

psql ユーティリティを使用して分散スキーマを作成する

psql を使用してエラスティック クラスターに接続した後、いくつかの基本的なタスクを完了できます。

スキーマは、次の 2 つの方法で配布できます。

  • citus_schema_distribute(schema_name)関数を呼び出して手動で次の操作を行います。
CREATE SCHEMA AUTHORIZATION user_service;
CREATE SCHEMA AUTHORIZATION time_service;
CREATE SCHEMA AUTHORIZATION ping_service;

SELECT citus_schema_distribute('user_service');
SELECT citus_schema_distribute('time_service');
SELECT citus_schema_distribute('ping_service');

このメソッドを使用すると、既存の標準スキーマを分散スキーマに変換することもできます。

分散テーブルと参照テーブルを含まないスキーマのみを配布できます。

  • citus.enable_schema_based_sharding構成変数を有効にします。 現在のセッションの変数を変更することも、コーディネーター ノードのパラメーターから永続的に変更することもできます。 パラメーターを ON に設定すると、作成されたすべてのスキーマが既定で配布されます。
SET citus.enable_schema_based_sharding TO ON;

CREATE SCHEMA AUTHORIZATION user_service;
CREATE SCHEMA AUTHORIZATION time_service;
CREATE SCHEMA AUTHORIZATION ping_service;

次のコマンドを実行して、現在分散されているスキーマを一覧表示します。

SELECT * FROM citus_schemas;
 schema_name | colocation_id | schema_size | schema_owner
-------------+---------------+-------------+--------------
 user_service |             5 | 0 bytes     | user_service
 time_service |             6 | 0 bytes     | time_service
 ping_service |             7 | 0 bytes     | ping_service
(3 rows)

サンプル データ用のテーブルを作成する

これで、すべてのマイクロサービスのエラスティック クラスターに接続できるようになりました。 次の例では、エラスティック クラスター データベースの名前は Citus です。 psql セッションから、\c コマンドを使用して別のユーザーにスワップできます。

\c citus user_service
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);
\c citus time_service
CREATE TABLE query_details (
    id SERIAL PRIMARY KEY,
    ip_address INET NOT NULL,
    query_time TIMESTAMP NOT NULL
);
\c citus ping_service
CREATE TABLE ping_results (
    id SERIAL PRIMARY KEY,
    host VARCHAR(255) NOT NULL,
    result TEXT NOT NULL
);

サービスを構成する

このチュートリアルでは、一連の単純なサービスを使用します。 これらは、次のパブリック リポジトリを複製することで取得できます。

git clone https://github.com/citusdata/citus-example-microservices.git
$ tree
.
├── LICENSE
├── README.md
├── ping
│   ├── app.py
│   ├── ping.sql
│   └── requirements.txt
├── time
│   ├── app.py
│   ├── requirements.txt
│   └── time.sql
└── user
    ├── app.py
    ├── requirements.txt
    └── user.sql

ただし、サービスを実行する前に、エラスティック クラスターのuser/app.pyを提供するping/app.pytime/app.py、およびファイルを編集します。

# Database configuration
db_config = {
    'host': 'EXAMPLE.postgres.database.azure.com',
    'database': 'postgres',
    'password': 'SECRET',
    'user': 'ping_service',
    'port': 5432
}

変更を行った後、変更したすべてのファイルを保存し、サービスを実行する次の手順に進みます。

サービスを実行する

すべてのアプリ ディレクトリに移動し、独自の Python 環境で実行します。

cd user
pipenv install
pipenv shell
python app.py

時刻サービスと ping サービスに対してコマンドを繰り返します。その後、API を使用できます。

一部のユーザーを作成します。

curl -X POST -H "Content-Type: application/json" -d '[
  {"name": "John Doe", "email": "john@example.com"},
  {"name": "Jane Smith", "email": "jane@example.com"},
  {"name": "Mike Johnson", "email": "mike@example.com"},
  {"name": "Emily Davis", "email": "emily@example.com"},
  {"name": "David Wilson", "email": "david@example.com"},
  {"name": "Sarah Thompson", "email": "sarah@example.com"},
  {"name": "Alex Miller", "email": "alex@example.com"},
  {"name": "Olivia Anderson", "email": "olivia@example.com"},
  {"name": "Daniel Martin", "email": "daniel@example.com"},
  {"name": "Sophia White", "email": "sophia@example.com"}
]' http://localhost:5000/users

作成されたユーザーを一覧表示します。

curl http://localhost:5000/users

現在の時刻を取得します。

Get current time:

example.com に対して ping を実行します。

curl -X POST -H "Content-Type: application/json" -d '{"host": "example.com"}' http://localhost:5002/ping

データベースを調べる

いくつかの API 関数を呼び出したので、データは保存され、citus_schemas に期待される内容が反映されているかどうかを確認できます。

SELECT * FROM citus_schemas;
 schema_name | colocation_id | schema_size | schema_owner
-------------+---------------+-------------+--------------
 user_service |             1 | 112 kB      | user_service
 time_service |             2 | 32 kB       | time_service
 ping_service |             3 | 32 kB       | ping_service
(3 rows)

スキーマを作成したとき、スキーマを作成するマシンを指定しませんでした。 これは自動的に行われました。 次のクエリを使用すると、各スキーマが存在する場所を確認できます。

  SELECT nodename,nodeport, table_name, pg_size_pretty(sum(shard_size))
  FROM citus_shards
  GROUP BY nodename,nodeport, table_name;
nodename  | nodeport |         table_name         | pg_size_pretty
-----------+----------+---------------------------+----------------
 localhost |     7001 | time_service.query_details | 32 kB
 localhost |     7002 | user_service.users         | 112 kB
 localhost |     7002 | ping_service.ping_results  | 32 kB

このページの出力例を簡潔にするため、nodename を IP アドレスとして使用する代わりに、localhost に置き換えています。 localhost:7001 がノード 1 で、localhost:7002 がノード 2 であるとします。

ユーザーと ping サービスが 2 番目の ノード localhost:7001 上のスペースを共有している間に、時刻サービスがノード localhost:7002 に配置されたことが確認できます。 サンプル アプリは単純で、ここでのデータ サイズは重要ではありませんが、ノード間の不均等なストレージ領域の使用率の影響を受けるものとします。 2つの小規模な時間サービスとpingサービスを1つのノードに配置し、対して大規模なユーザーサービスは専用のノードに配置する方が理にかなっています。

クラスターはディスク サイズによって簡単に再調整できます。

SELECT citus_rebalance_start();
NOTICE:  Scheduled 1 moves as job 1
DETAIL:  Rebalance scheduled as background job
HINT:  To monitor progress, run: SELECT * FROM citus_rebalance_status();
 citus_rebalance_start
-----------------------
                     1
(1 row)

完了したら、新しいレイアウトの外観を確認できます。

  SELECT nodename,nodeport, table_name, pg_size_pretty(sum(shard_size))
  FROM citus_shards
  GROUP BY nodename,nodeport, table_name;
 nodename  | nodeport |         table_name        | pg_size_pretty
-----------+----------+---------------------------+----------------
 localhost |     7001 | time_service.query_details | 32 kB
 localhost |     7001 | ping_service.ping_results  | 32 kB
 localhost |     7002 | user_service.users         | 112 kB
(3 rows)

期待通り、スキーマは移動され、よりバランスの取れたクラスターになっています。 この操作は、アプリケーションにとって透過的です。 再起動する必要さえなく、クエリの提供を続けます。

次のステップ