勇者だって最初はひのきの棒とナベのふた

技術を中心に発信。時々SFの読書感想も。

CosmosDBのドキュメント読む その3

はじめに

masamoriです。初めての連投です。GW最高。

この記事は前回の続きです。

masamori0083.hatenablog.com

今回は、CosmoosDB のPostgresql APIを使用してみたいと思います。 分散リレーショナルとは一体・・・。

Citus

基本的には水平方向のスケールが難しいとされるRDB。これを可能にしているのはCitusというPostgreSQLオープンソース拡張機能です。

github.com

現在はMicrosoftに買収されたみたいです。このCitusの使い方は「日本PostgreSQLユーザーの会」がドキュメントを出してくださっています。

https://www.postgresql.jp/sites/default/files/2021-11/PostgreSQL_Conference%202021_B2_pub_20211112-1.pdf

リソースの作成

それではリソースを作成します。
portalのCosmosDB作成より、PostgresqlAPIを選択します。そして、適当にパラメータを埋めて、デプロイ直前のパラメータはこのようになります。なお、ネットワークやセキュリティに関しては一切考慮していないので、実運用するときはしっかりとネットワーク設計をしましょう。今回は、IPアドレスによる制限しかかけません。

デプロイします。
デプロイが終了すると、概要欄のページに飛べますが、サイドバーが普通のpostgresqlフレキシサーバーのものとは違います。

クラスターマネジメントなるものがありまして、ここでスケールの設定ができます。

.

構成

さて、実際のところどのような構成でDBが作成されているのでしょうか?
こちらが構成図です。

kubernetesをいじったことがある人には馴染みの構成かもしれません。コーディネータnodeがクライアントからの要求を集約し、各ワーカーノードにクエリを発行します。この時、実際にデータが入っているのはワーカーノードになります。うん、コンテナのオーケストレーションだなこれ。
ちなみにportalから作成すると、デフォルトではコーディネータとワーカーは一つずつです。ノードを増やしたい場合は、サイドバーの「設定>Scale」と選べばノードの数を増やせます。
検証ということで、ノードを一つ増やしました。価格はこちら。

え、高くない?なんか、スペックも自動で上がってるし。というわけで、ノードを増やす時はしっかりコストを考えましょう。

テーブル作成とクエリの発行

さて、ドキュメントに沿って作成したDBにデータを入れていきます。詳しい手順はドキュメントを見てください。

learn.microsoft.com

操作としては普通です。ただ、

SELECT create_distributed_table('github_users', 'user_id');

このcreate_distributed_table()メソッドが独特です。第一引数はテーブル名。第二引数は分散テーブルを作成する基準とするカラム名です。これで分散テーブルが作られます。分散テーブルとは、文字通り分散されたテーブルで、このメソッドを使用することでシャーディングができるようになります。他のノードにデータを移すときはこのシャーディングの単位でデータを移すことになります。パーティションのことかな?

今回のケースでは32のシャーディングを作成しています。

さて、次にクエリを発行します。これも普通です。ドキュメントはこちら

learn.microsoft.com

データのノード間移行

デフォルトでは、一つのノードにシャーディングされたデータが全て入っています。これだと分散の意味がないので、検証の意味を込めて別のノードにデータを移したいと思います。
今回の検証データにはprimary_keyがありません。基本的にこのような状況は実務だとあまり考えられないですが、primary_keyが無いとシャーディングを別のノードに移せません。そこで、非推奨ですが強制的にシャーディングを他のノードに移します。これは非推奨です!!

SELECT rebalance_table_shards(
  'github_users',
  shard_transfer_mode => 'force_logical'
);

このコマンドを打つと、指定したテーブルのシャーディングを各ノードに上手い具合に分散してくれます。

ノードに分散させるというのが醍醐味ですね。ちなみに、複製されたわけでは無いのでご注意を。また、リージョンで分散されたわけではありません。地理的冗長性を保ちたい場合、「Cluster Management > Replica data globally」で設定できます。

終わりに

基本的な操作は普通のPostgreSQLと変わらないなという印象です。ただ、僕が普段DB操作をするときは生のSQLは書かずORMで操作しています。ですので、ORMで操作したときにどんな挙動になるのかは興味があります。しかし、クエリの発行自体は変わらない印象なので、恐らくORMにも対応していると思います。
クライアントからの操作感は普段と変わらず、DBサイドで分散をよしなにやってくれそうです。
次のプロジェクトで使ってみようかなぁ。
あ、ちなみに一度ノードを増やしたらポータル上からはノードをスケールダウンすることは出来ないっぽいです。
検証でノードを複数作るときは気をつけましょう。僕もソッコーでリソース消します。