SaaS.tech #2 で LT させていただいたお話

こんにちは!矢ヶ崎です!

2022/04/20 に、「SaaSにおけるマルチテナント設計の悩みと勘所 | SaaS.tech #2 」というイベントにてLTをさせていただきました!このイベントは、SaaSのTech領域に特化したイベントになっていて、いままでありそうでなかったイベントだと思います。ここ数年はSaaSとクラウドのことばっかりをやってきたので、個人的に激アツです!日本でもSaaSビジネス系のお話は、書籍もイベントもそこそこある感じがしますが、Techのものはほぼ皆無だと思いますので、とっても貴重なイベントだと思っています!

ここに登壇させていただいてとても嬉しかったのでブログにしてみました。

このときのテーマは「マルチテナント」ということでしたので、「マルチテナントにおけるデータ分離(仮)」のお話をさせていただきました。もちろん、ぼくじゃない登壇者のみなさまのお話も、全てとても参考になるものだったのでぜひ見ていただくことをオススメします!

ぼくの登壇資料はこちらです!https://speakerdeck.com/yaggy/marutitenantoniokerutenantozeng-jia-shi-falsedetabesufen-li-falseti-yan-tan-li-jia

内容はざっくり言うと、SaaSを作って運用していて、マルチテナントでDBのスキーマ単位にデータを分離していて、パフォーマンスの問題が出てきたのでその解決として、スキーマによるテナント分離ではなく、行によるテナント分離へ変更したお話です。

動画を公開していただいておりますので、細かい内容はこちらをご覧ください!

https://www.youtube.com/watch?v=L9Ek9g_oU9c

今回はLTで登壇させていただいたので、時間の都合で割愛させていただた部分があります。せっかくなのでここでもうちょっと細かく書いておきます。

このパーティションプルーニングの部分になります。

「パーティションプルーニング」は、”一致する可能性のないパーティションにはそもそも無駄にアクセスしないようにする”というイメージの機能です。大規模にパーティショニングされているときに特に有効になります。

当たり前といえば当たり前なのですが、このパーティションをプルーニング(刈り込み・絞り込み)するためには、SQL文のWHERE句でパーティションを特定できるような条件(partition_id = get_partition_id()など)が必要になってきます。基本的にこれはパーティションプルーニングを使いたい全てのSQLに必要となってきます。大変です・・・

今回はすでに行レベルセキュリティ(RLS)を使っているというお話をしました。ということは、USINGやWITH CHECKで指定しているRLSのポリシーを、ユーザから実行されたクエリに対して自動的に追加条件として付けているということになります。これをうまく利用して、今回はパーティションプルーニングに必要なパーティションの特定条件を、RLSのポリシーに記述して、パーティションプルーニングを自動的に有効にしました。

具体的には、例えば tenant_id(テナントを特定するID)でRLSをかけている場合でそのIDことにパーティショニングしている場合には、tenant_idからパーティションを特定する関数とパーティションIDを一致させる条件をRLSのポリシーに追記します。

例:

CREATE POLICY public_t1_users ON t1
FOR ALL
USING (tenant_id = current_tenant_id() AND partition_id = get_partition_id(current_tenant_id()))
WITH CHECK (tenant_id = current_tenant_id() AND partition_id = get_partition_id(current_tenant_id()));
ALTER TABLE t1 ENABLE ROW LEVEL SECURITY;

こうすることにより、SQLを発行するユーザはRLSやパーティションを意識することなく、いつもどおりのイメージで実装することができます。

(インデックスの問題などがありますが、またそれは別の機会に)

ということで、今後はSaaSのテクニカルな内容に特化してポストしていきたいと思います!ひとつよろしくお願いいたします!

こちらからは以上です。