MSAなど:銀行向けの高負荷サービスの作成方法

負荷の高いサービスを設計することは、賢明な先生だけが持つ神秘的なスキルではなくなりました。 今日、このために確立された慣行があり、会社とそのビジネスの特性に応じて結合および修正されます。 負荷の高いサービスを作成するためのベストプラクティスとツールについてお話しします。









すぐに、カスタム開発に専念することを予約してください。 常識として残されているように、私たちはビジネスタスクの定式化から設計を始めます。 特に、システムの負荷が高いかどうかを判断します。 時間が経つにつれて変化する(たとえば、負荷プロファイルが変化する)ことは明らかであるため、ビジネスロジックを説明するときは、可能性のある開発パスを定めます。 これが何らかのカスタマーサービスである場合、オーディエンスの規模の変化を予測できます。 システムが時間の経過とともにどのように変化するかがすぐに明らかになる場合があり、一部のコントロールポイントを予測することは困難です。



初期段階では、ストレージに必要なデータ量を計算し、抽象サービスの初期負荷とその成長率を計算できます。 また、データをストレージ、書き込み、読み取りなどの作業の種類別に分類し、それに応じてプロセスを最適化することもできます。



システムの運用に関するKPIがあり、それに基づいて許容される劣化の程度が決定されます。 ほとんどのシステムでは、応答時間が重要です。 場合によっては数秒に達することがありますが、他の場合にはミリ秒かかります。 また、この段階で、システムの可用性の程度が決定されます。 原則として、可用性が99.9%〜99.999%の高可用性システムまたは連続運用システムを設計しています。



ビジネスロジック、許容可能なデータ量、およびシステムの動作を決定したら、データ移動図の作成を開始します。 これは、選択するのに最適な設計パターンを理解するために必要です。 そして、図を作成した後、設計自体に進みます。



マイクロサービス-現代の流行語



最近、負荷の高いシステムを作成するとき、サービス指向のアーキテクチャを好みます。 特に、マイクロサービスは近年非常にファッショナブルになりました。システムの機能を小さな部分に分割します。サービスはそれぞれ小さなタスクを実行します。 数百または数千の多くのサービスが存在する場合があります。 このアーキテクチャにより、システムの保守が容易になり、個々のサービスに加えられた変更がシステム全体に与える影響ははるかに小さくなります。



また、マイクロサービスアーキテクチャのもう1つの重要な機能は、優れたスケーラビリティです。

しかし、重要な利点に加えて、マイクロサービスアーキテクチャには重大な欠点があります。ビジネスロジックをかなり小さな機能要素に分割できるとは限りません。



このタスクは複雑であり、原則として、設計段階で解決されます。 コインの裏側は、サービス間の相互作用です。 メッセージングのオーバーヘッドが大きすぎないことを確認する必要があります。 これは主に、データのシリアル化/逆シリアル化に効果的な方法を選択することにより(詳細は後述)、相互作用するサービスを「より近くに」移動するか、それらを1つのマイクロサービスに結合します。 しかし、ロジックを小さなタスクにうまく分割できれば、マイクロサービスアーキテクチャのすべての利点がサービスに反映されます。







マイクロサービスアーキテクチャにより、多数のノードでサービスをホストし、一部のノード(pah-pah-pah)で障害が発生した場合に必要な予約を設定できます。 バックアップスキームは、最初のタスクに大きく依存します。 一時停止を許可できない場所で、サービスを即座に復元する必要があります。この場合、バランサーが障害のあるノードを即座に切断するときにアクティブ/アクティブスキームが使用されます。 他の場合では、サービスの復旧時間に少しのダウンタイムを設定し、バックアップノードがすぐに使用可能にならず、サービスが自動的にバックアップノードに転送されるまでの短い期間の後、アクティブ/スタンバイスキームが使用されたとします。



アクティブ/アクティブスキームのオプションを使用する必要性の明らかな例は、リモートバンキングサービス-インターネットおよびモバイルバンキングです。



従来、VTB Bankはかなりの量のカスタムソフトウェア開発を行っていました。 最近まで、.NETおよびJava Enterpriseテクノロジーは主にこれらの目的に使用されていました。 現在、これらの資金はすでに当社がレガシーとみなしています。 新しいプロジェクトでは、マイクロサービスアーキテクチャ(MSA-マイクロサービスアーキテクチャ)に基づくアプローチを使用し始めました。



より具体的には、銀行内の新しいシステムは、Spring Bootプラットフォーム上の一連のマイクロサービスとして設計されています。 Spring Frameworkを選択した主な理由は、ITサービス市場での広範な使用と、サービスおよびマイクロサービスの開発での比較的使いやすさでした。



ユーザーと対話するには、原則として、ReactまたはAngularを使用して開発され、Rest APIを介してサーバーコンポーネントと対話するWebインターフェイスが使用されます。



別のトピックは、MSAコンポーネント間の相互作用、および既存のITエコシステムとの統合です。 MQキューなどの従来のアプローチに加えて、弱い結合とApache Kafkaプラットフォームに基づく新しい相互作用パターンを積極的に導入しています。







言語とフレームワーク



現在、短い応答時間で負荷の高いシステムを構築できる多くのテクノロジーがあります。 しかし、その構成は絶えず変化しています。オープンソースの世界から何かが絶えず入り、新しい内部プロジェクトが開発されており、その一部はオープンソースのキャンプにも入ります。 ただし、有名なベンダーの実績のあるソリューションをお勧めします。 私たちの仕事は、そのようなシステムを使用する能力を構築することです。



データキャッシングを使用しない負荷の高いシステムを想像するのは困難です。 市場には多くのツールがありますが、通常、実績のある「クラシック」であるMemcachedとRedisにこだわります。 しかし、最近、彼らはApache Igniteの方向に目を向け始めました。いくつかのプロジェクトでは、Apache Igniteは分散キャッシュとしての地位を確立しました。

プログラミング言語の選択に関しては、タスクに大きく依存します。 原則として、選択はJavaに依存します。必要な機能を迅速かつ効率的に実装できるフレームワークが多数あり、必要なパフォーマンスインジケーターを実現できるJVM設定が多数あります。



MSAを設計するとき、Javaテクノロジースタックにもこだわります。 統合に加えて、これにより、従来の統合メカニズム(MQキュー、Webサービス、および多数のJavaベースのAPI)を介して、銀行ですでに実行されているアプリケーションと簡単に統合できます。 また、開発したツールを使用して、このプラットフォームで利用可能なマイクロサービスを開発および管理することもできます。



また、ロシア市場では、JVMに基づくテクノロジースタックを使用したMSAアプリケーションの開発にすでにかなり多くの専門家がいることも重要です。



データ保存



データストレージに関しては、設計の最初の質問は質問です。どのデータモデルがDBMSを使用すべきか-リレーショナルか、それとも他のものか? データベースクエリの処理効率を向上させるためのその他の手法は、選択に依存します。これは、負荷の高いサービスは先験的に応答時間が短いためです。 リレーショナルDBMSについて話している場合、負荷の高いプロジェクトでそれらを使用するには、クエリの効率を上げるという問題を解決する必要があります。 すべては、クエリプランの分析から始まります。



原則として、その結果に基づいて、クエリ自体を変更し、インデックスを追加します。 パーティション化はテーブルに適用でき、サンプルを1つ以上のパーティションに制限することでサンプルのデータ量を削減できます。 また、データの非正規化を使用して、ある種の冗長性を導入することもしばしば必要です。これにより、クエリの効率が向上します。



また、非リレーショナルDBMSでは、特定の製品やビジネスシナリオに応じて、ほぼ個別のアプローチを使用する必要があります。 一般的なアプローチのうち、労働集約的な計算の遅延処理のみを選択できます。



もちろん、すべては特定のタスクに依存しますが、可能であれば、Oracleを使用します。これは、効率的なクエリとチューニングを作成するのにエンジニアの時間がかからないためです。 また最近では、Apache Igniteをよく見ています。



スケーリング



上記のように、作成されたシステムが6か月または1年でどのような負荷を経験するかを常に予測することはできません。 また、スケーリングの可能性を定めなければ、システムは急速に増加する負荷に対処しなくなります。 特定のプロジェクトに応じて、垂直方向または水平方向のスケーリングが適用されます。 垂直-単一のコンポーネント/ノード内にリソースを追加することにより、個々のコンポーネントのパフォーマンスを向上させます。 水平-コンポーネント/ノードの数を増やして、それらに負荷を分散します。



サービスまたはコンポーネントのスケールアップは、ステートレスパラダイムを使用する場合、つまりリクエスト間のコンテキストを保存しない場合、はるかに簡単です。 この場合、このコンポーネントまたはサービスの複数のコピーをシステムに簡単に展開し、それらの間の負荷を分散できます。 ステートフルパラダイムの場合、コンポーネント/サービス内の状態の存在をバランスが考慮に入れるように注意する必要があります。



物理的な世界



テスト、テスト、そして再びテスト



負荷テストなしでは、負荷の高いシステムを起動することは考えられません。 負荷テストでは、入力時に特定のKPIの達成を確認することを目的としています。 私たちの経験から、リクエストの長い処理時間は、ほとんどの場合、アルゴリズムの非効率性に関連しています。 また、パフォーマンスキャッシュは、同じタイプの多数のリクエストを使用したデータキャッシュによって促進されます。



テストにより、設計時に見落とす可能性のあるボトルネックを特定できます。 プロジェクトの一部として実装されたWebサービスは、その単純さにもかかわらず、負荷テスト中に低パフォーマンスで機能しました。 プロファイリングにより、ほとんどの場合、データのシリアル化と逆シリアル化に時間がかかりました。つまり、基本的にはデータ構造をビット表現に、またはその逆に蒸留しました。 ソリューションはすぐに見つかりました-データの性質は非常にまれにしか変化しませんでした。 (事前にシリアル化された表現を準備しておくことで)データの事前シリアル化を実装でき、応答時間を大幅に短縮できました。





外部APIのシリアル化の最適化(事前シリアル化)



システムが要件を満たしているかどうかを確認するストレステストに加えて、ストレステストも実施します。 このようなテストの目的は、システムが耐えることができる最大負荷を見つけることです。



モニタリング



メトリックはセンサーの役割を果たします。メトリックは、深刻なシステム、特に負荷の高いシステムに密集しています。 メトリックがなければ、プログラムは入力と出力を備えたブラックボックスに変わり、内部でどのように機能するかは不明です。 アーキテクチャを設計するとき、監視システムの情報を生成するメーターが配置されます。



一部のプロジェクトでは、ELK(Elastick Search Kibana)を使用してシステムアクティビティを視覚化し、監視しました。 このフレームワークには、必要なレポートフォームをすばやく簡単に設定できる柔軟なインターフェイスがあります。





キバナの監視



おわりに



フォールトトレラントな高負荷システムを構築する場合、特効薬はありません。 テクノロジーではなく、システムアーキテクチャが正しく選択されているため、負荷に対処できます。 常にいくつかの妥協点を探すことです。 場合によっては、既存のアプローチとパターンを使用でき、場合によっては、アーキテクチャソリューションを設計および実装する必要があります。



All Articles