システム設計パターン
Azureのクラウド設計パターンに一通り目を通した。名前を与えずに使っていたものや気になったものを特に抜粋して残す。またAWS, GCP関連で公開されている資料へのリンクも末尾に残す。 リトライパターン: これはパターンと呼ぶほどなのかわからない。クラウドだろうがオンプレだろうが外部システムを呼び出す部分で一時障害は前提にするべきでリトライしましょうねという話。ただし実装を冪等にしておかないとネットワーク疎通の問題でレスポンスが得られなかったときなど問題になる。 Circuit breaker: 依存システムの障害発生時にリトライなどによる負荷増で連鎖障害を起こさないようにする安全策。バグなど長時間発生する障害に対する対策にもなる。Closed, Open, HalfOpenって3状態を保つステートマシンと状態遷移のイベントを渡せるライブラリを作ればいい。資料も公開されてるけどDragonの実装で使ってた。最近はIstioとかのサービスメッシュ内で組み込んだりするっぽい。ただ4xx系はエラーとして扱うとか扱わないとかアプリケーション依存な部分があるので、コンポーネントとして独立させつつアプリケーションの情報を渡す方法については色々な設計がありえるので単純に使うのが意外と難しい。 正常性エンドポイントモニタリング: むかしNagiosでプロセス監視したり拡張してレスポンス監視したりしてた。いまみんなどうしてるんだろ、プローブ的なリクエストを投げてStackdriverでログからフックしたりしてるのだろうか。SensuはスケールするNagiosでいい印象があるけど最近は聞かない。正常プローブの結果を集計するprometheus exporterを使った方が他メトリックスト一緒に扱えて便利で定着したのだろうか?Datadogは予測をやってくれて便利だけどPrometheusだと簡単にいかない。このへん整えたい。 キャッシュアサイド: アプリケーションがオンデマンドにマスターデータとキャッシュの一貫性を管理する。むかしY!J ニュースの開発してたときにマスターのデータストレージが死んでも配信できるようにって要件があったのでローカルキャッシュを取っていたときに行なっていた。キャッシュのTTLを短くしつつマスターが死んでいたときはキャッシュ優先するみたいなことをしてたなぁ。 Strangler: レガシーなサブシステムを隠すファサードを構築して、対象サブシステムのマイグレーションを徐々に行う。システム移行するときに2,3回やった。 具体化されたビュー: ストレージシステムにとって不利なクエリを使わざる得ないときに必要なテーブルを事前準備しておくことを指す。MaterializedView使って対応したことある。DWHで頻発する集約を事前に準備するETLを設計したことがある。CQRSのコマンドを永続化する方針を取ると必須になる。イベントソーシングはCQRSのビュー管理をアプリケーションで実装したもの。RDBMSのWALログとか考えるとテーブルはビューにすぎなくてマスターデータはログって見做すのは自然。 インデックステーブル: セカンダリインデックスがサポートされてないストレージシステムで擬似的にセカンダリインデックスを使うために具体化されたビューを使うこと。 Saga: 最近のアプリケーションではデータミドルウェアを複数利用する必要があったりマイクロサービス化されていたりするため、分散トランザクションが必要になる場面が出てくる。全ての参加者が2PC, 3PCなど合意プロトコルをサポートしていれば良いがそうでない場合に管理して対応する必要が出てくる。Sagaではトランザクションを「ローカルトランザクションのシーケンス」として管理する。一部の失敗で全体をキャンセルしたりが必要になるため参加するローカルトランザクションには補正トランザクションが実装されてる必要がある。具体的な実装方針は2種類ある。 補正トランザクション: REDO的な機能を作っておかないと複数システムにまたがるトランザクションが辛いことになりますよって話。後ろで成功してしまったトランザクションは維持したいとかアプリケーション固有の話がたくさんあるので設計がだいじ。また、トランザクションの失敗時に即時補正していいのかはアプリケーションによる。 Ref