ネクストエンジンでのデータベース・シャーディング
はじめに
ネクストエンジンは数千社の企業をユーザーとしていて、その企業で扱う大量の商品情報と膨大な受注情報を取り扱っています。
増え続けるデータ量に起因するデータベースへの負荷をシャーディングにより軽減しています。
この記事ではそこに至った経緯と現状を紹介します。
マルチテナントと過去の課題
ネクストエンジンはマルチテナント方式で提供されています。企業単位でユーザーアカウントを作成し、各ユーザーアカウントの中で個人のメンバーアカウントが管理できるようになっています。
データベース内部ではユーザーアカウントごとにスキーマを作成しています。
アプリケーションはログイン情報から割り当てられた対象スキーマを特定しクエリを実行します。
2020年にクラウド移行がはじまるまで、アプリケーションとデータベースをセットという概念でまとめて管理していました。
各サーバをひとまとまりで管理してセット内の収容テナント数を制限することで、データをハードウェアレベルで分割できてパフォーマンスの悪化を防ぐことができます。
各セットはユニークなドメインを持ち、ユーザーはポータルログイン時に割り当てられたセットにのみアクセスする仕組みになっていました。
このセットの概念はスケーラビリティの面でネックになっていました。
サービス成長に伴うユーザー数増加の折にはセットの単位で調達、構築する必要があります。また負荷をセット単位で確認せねばならず、Webのスケール幅もセット数に依存してしまいます。
現在のシャーディング
クラウド移行にあたってこの構成を大きく見直しセットの撤廃を実現しました。
これまでアプリケーションはセット内の決められたDBに接続すれば良い状態でしたが、都度どのデータベースに接続すべきかを判別する必要が出てきました。
そこで、水平分割されたうちのどのデータベース(シャード)にアクセスすべきか判別する仕組み、シャードリゾルバーを新たに作成しました。
アプリケーションはデータベースアクセスが必要なタイミングでシャードリゾルバーに問い合わせを行い、レスポンスとして得られたエンドポイントに接続します。
これまでもログインユーザーがどのセットに所属しているかは判別する必要があり、実質的にユーザーとアクセス先データベースの紐付けが保存された外部データベースのテーブルが存在しました。シャードリゾルバーはこの既存テーブルを利用しシャード問い合わせに特化したサービスとして構築されています。
セットの撤廃、シャードリゾルバーの構築により、アプリケーションは全体の負荷に応じて自由にスケールさせることができ、データベースのスケールも新規にシャードのみを追加して紐付けテーブルのレコードとして新規データベースを登録するだけで済むようになりました。
またユーザーのアクセスするドメインを統一できた影響で、新規ユーザーの発行先シャードの切り替えやシャード間のユーザスキーマの移設で変更作業が減ったり、監視もしやすくなったり手間が省けています。
今後の課題
改善も進めていて、直近では、当初のシャードリゾルバーはデリバリー速度を重視し既存のRubyアプリケーションにエンドポイントを追加したものでしたが、有志によりGo製の専用アプリケーションとして切り出されたことでパフォーマンス、リソース効率の向上にも成功しています。
課題はまだまだ山積みです。
例えば、取り回しやすくなったユーザーデータを柔軟に移設しながらデータベースの負荷を平準化したいと考えています。データ量の大きいユーザーが固まって存在したり、データ量の小さなユーザーを集めて収容数が増えすぎたりすると、特定のシャードに負荷が偏ってしまいます。ユーザーごとのデータ傾向を捉え、バランスよく配置することが理想です。
そのためには負荷とデータの傾向を分析できること、さらに、安全に作業するためにオンラインでDDLを実行できることなど新たな課題も見えています。
サービスの成長を見据えて、よりスケーラブルでコストパフォーマンスの高い仕組みにしていきます。
NE株式会社のエンジニアを中心に更新していくPublicationです。 NEでは、「コマースに熱狂を。」をパーパスに掲げ、ECやその周辺領域の事業に取り組んでいます。 Homepage: ne-inc.jp/
Discussion