はじめに
こんにちは、技術本部SRE部ZOZOSREチームの堀口/柳田です。普段はZOZOTOWNのオンプレミスとクラウドの構築・運用に携わっています。
ZOZOTOWNではSQL Serverを中心とした各種DBMSが稼働しています。
その中で検索処理における参照に特化された役割を持つデータベース群をReadOnlyデータベース(以下、RODB)と呼んでいます。これらは日々増加するZOZOTOWNのトラフィックに耐えられるよう定期的にオンプレミスサーバを増台することでスケールしています。
これらのRODBは日々トラフィックの増減が激しいZOZOTOWNのサービスにおいて、オンデマンドでスケール可能なクラウド基盤上に構築した方が望ましいと判断し、クラウド化を実現しました。
本記事では、オンプレRODBをAWS RDS for SQL Server(以下、RDS)へクラウドリフトする中で解決すべき課題とそれをどのように解決したのかを紹介させて頂きます。
目次
- はじめに
- 目次
- クラウド化する上での課題
- アクセス元のアプリケーションロジックを変更せずに実現する必要がある
- オンプレ⇔クラウド間の通信量を削減する必要がある
- クラウド側障害でもサービス影響を最小限に抑える必要がある
- コストを最小化する必要がある
- まとめ
- おわりに
クラウド化する上での課題
RODBをクラウド化するにあたって以下の課題がありました。
アクセス元のアプリケーションロジックを変更せずに実現する必要がある
オンプレ⇔クラウド間の通信量を削減する必要がある
クラウド側の障害でもサービス影響を最小限に抑える必要がある
コストを最小化する必要がある
これらの課題を1つずつ説明していきます。
アクセス元のアプリケーションロジックを変更せずに実現する必要がある
RODBのアクセス種類は2種類あります。
- Webサーバ上で動作するアプリケーションからの参照処理(select)
- データ更新のためのデータレプリケーション(update/insert/delete)
アプリケーションからの参照処理におけるRODBへ接続する際のDBログイン方式は、ユーザ名+パスワード指定による一般的なSQL Server認証方式ではなく、Windows認証方式となっています。
今回のクラウド化で置き換えるサービスはAWSのマネージド型データベースであるRDS for SQL Serverと決定していました。しかし、RDSはPaaSであるゆえに既存のRODBが所属するWindowsドメインに所属させることができません。
これではWindowsログオンユーザでDB接続するWindows認証方式が使用できないことになります。
RODBへのログイン方式を変更することは、Webサーバ上で動作するアプリケーションソースを書き換えることになります。これではオンプレRODB向けなのかクラウドRODB向けなのかをアプリケーション側に意識させる必要性が生まれてしまいます。
これはインフラとアプリケーションが密結合してしまい、本来目指すべき方向から外れてしまいます。ましてやアプリケーションソースをオンプレRODB向け/クラウドRODB向けと二重管理することは絶対に避けたいものです。
RDSへのログイン方法をWindows認証でログインさせる方法がないか模索したところ、AWS側に用意されていました。
「AWS Managed Microsoft AD」というマネージド型のディレクトリサービスにRDSを所属させ、それと既存のドメイン間で信頼関係を作成するというものです。
これによりRDSへのログイン時に既存ドメイン上のユーザがWindows認証によりSQL Serverにログインが可能となりました。
より詳細な情報は下記に記載されていますので興味のある方はこちらを参照してください。 docs.aws.amazon.com
この仕組みによりアプリケーション側のログインロジックを変更することなく、オンプレDBとRDSへのログインを実現できました。
AWS Managed Microsoft ADの落とし穴
AWS Managed Microsoft ADについては当初知見がなく、構築時にハマった箇所を少し紹介します。
AD自身のアクセス制御を行うSecurityGroupについてです。AWS Managed Microsoft AD上にディレクトリを作成すると、AWSの命名規約に則ってSecurityGroupが自動的に生成されます。このSecurityGroupはAWSマネジメントコンソールから該当ディレクトリを参照しても変更できません。その存在すら見当たりません。SecurityGroupを変更したい場合は、自分で該当SecurityGroupをEC2サービス側から探し出し、変更する必要があります。
また、上記SecurityGroupを発見できたとしても、信頼関係を結ぶ他のドメインコントローラーとの通信で必要なポートが不明瞭です。AWSのマニュアルで指定されたポートだけでは不十分で、実際には他のポートも開ける必要があります。不足分はトライ&エラーで調査しました。
オンプレ⇔クラウド間の通信量を削減する必要がある
ZOZOTOWNではオンプレミスサーバ群が配置されているデータセンターからAWSサービスまでの通信はAWS Direct Connect(以下、DX)を利用しております。
今回も既設のDX回線を利用するのですが、RODBへのアクセスによりネットワーク帯域を枯渇させることがないように、また枯渇させないまでも通信量の増加を最小限にするよう配慮する必要がありました。
繰り返しになりますが、RODBのアクセス種類は2種類あります。
- Webサーバ上で動作するアプリケーションからの参照処理(select)
- データ更新のためのデータレプリケーション(update/insert/delete)
Webサーバ上で動作するアプリケーションからの参照処理(select)における通信量削減
ZOZOTOWNのWebサーバ群はオンプレミス、AWSの両方で稼働しています。
Webサーバ群はオンプレミス上で稼働しておりそこからRDSへアクセスすると、発行されたクエリ自身とその結果セットの通り道はDXとなります。
これを削減するためRDSへアクセスするWebサーバ群はEC2で稼働するWebサーバのみに限定しました。
オンプレミスのWebサーバからのアクセスはオンプレRODBにするといった棲み分けを行うことでオンプレ⇔RDS間の通信をゼロにしました。
データ更新のためのデータレプリケーション(update/insert/delete)における通信量削減
RODBのデータはSQL Serverのトランザクションレプリケーション機能により他のデータベース群より取得し最新化しています。
RODBにデータを供給するデータベースはオンプレミスで稼働しているため、RDSへ同期するデータはDXを通ってくることになります。
そして、RODBはRDSの台数の増減によりスケールさせる運用を考えているため、RDSが増えていくごとにDXの通信が増えてしまうことになります。
この対策として、オンプレミスのデータベースとRDSとの間に中継用のSQL Serverを立てることによりRDS台数の増減に影響されず、通信量を一定に担保するような構成としました。なお、中継用のSQL ServerはEC2上でSQL Serverを稼働させるIaaS型としました。
クラウド側障害でもサービス影響を最小限に抑える必要がある
今回のRDSはAZ障害時に被害を最小化するためいくつかの対策をしています。
- マルチAZ
- データ連携経路のAZ分散
マルチAZ
RDSの機能であるマルチAZ方式を採用しています。マルチAZ方式を採用した理由は以下のとおりです。
- 人間(運用担当者)よりも迅速に切り替えるため
- クライアント側から見た場合に透過的に切り替えるため
マルチAZの特徴
RDS for SQL ServerにおけるマルチAZの挙動は以下のとおりです。
- Active/Standby構成でのフェイルオーバー型
- フェイルオーバーが発動してもRDSのエンドポイント名は変わらない
- IPアドレスは変更されるため一時的に接続断が発生する
- フェイルオーバー発動のトリガーはRDS側で判断する
Active/Standby構成でのフェイルオーバー型について説明します。通常時はActive側のみでサービスしStandby側へのアクセスはできないが、障害時にはStandbyがActiveに切り替わりサービスを継続するというものです。Standby側はデータベースとしてのサービスは行えません。それにも関わらずActiveと同額のランニングコストが発生することは大きなネックとなります。
Active側の障害によりフェイルオーバーが発生してもクライアントが接続時に指定するエンドポイント名(DNS名)は変らずにアクセスできるので、切り替わり時にクライアント側の操作は不要となります。
ただしエンドポイント名で解決されるIPアドレスは変更されるため、クライアント側でIPアドレスを指定したDB接続をすると、接続先の切り替え作業が必要となります。また切り替えの際に発行中のクエリはロールバックされRDS内でのリトライは行われないため、必要な場合はクライアント側でエラーとなったクエリを再実行する必要があります。
フェイルオーバー発動条件は、Active側のホスト異常やネットワーク異常などRDS側のルールによって定められています。 詳しくはこちらを参照して下さい。
マルチAZに関する時間測定
弊社環境で計測したマルチAZに関わる作業/処理時間について以下にまとめます。
処理 | 時間 |
---|---|
手動フェイルオーバー | 1分以内 |
オンライン中のSingleAZのRDSをMultiAZに変更 | 30分 |
オンライン中のMultiAZのRDSをSingleAZに変更 | 10分 |
ただしSingleAZ⇔MultiAZに変更する作業については、同時に実施するRDSの数、タイミングによっては上記の3倍程度の時間がかかったこともありました。
データ連携経路のAZ分散
過去に発生したアベイラビリティゾーン(以下、AZ)障害対策として、特定のAZで何かしらの障害が発生してもサービス継続可能にするため、データ連携経路を複数のAZに分散しています。
上図の通り、AZ#1で障害が発生してAWSサービスがダウンしても、AZ#2でサービスを継続可能な仕組みとしています。
コストを最小化する必要がある
RDSに関するAWSのコストを考えるために必要な要素は次のとおりです。
要素 | 内容 |
---|---|
インスタンスタイプ | キャパシティが大きい程コスト増 |
ストレージ | キャパシティとIOPSが大きいほどコスト増 |
マルチAZ | シングルAZと比較してマルチAZはほぼ倍額 |
バックアップ | バックアップ対象サイズが大きいほどコスト増 ※マルチAZの場合は最低1世代のバックアップが必要 |
弊社の環境では、セール時などRODBへのアクセス増が見込まれる時に、インスタンスタイプのキャパシティを事前に増加させマルチAZ化を行います。また、アクセス減となる際には、インスタンスタイプのキャパシティを最小化しマルチAZをシングルAZ化する等の作業をすることでコストの最小化を行っております。
なお上記変更は、IaCによりコード化されたyamlを変更することで管理しており、人的な作業コストの削減も実現しております。
まとめ
本記事では、ZOZOTOWNで本番稼働するReadonlyデータベースをクラウドリフトした際の課題と対策を中心に事例を紹介しました。
弊社のReadonlyデータベースはその性質上、柔軟なスケールが可能なクラウドに適しているためクラウド化を行いました。しかし、全てをクラウド化するということを推奨するものではなく、それをクラウド化する価値があるかどうかはしっかりと判断するべきだと考えています。
おわりに
ZOZOでは、一緒にサービスを作り上げてくれる仲間を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください!