大規模およびマイクロサービスユニットの設計の高可用性

それは、大規模なマイクロサービスシステム、オンラインシステムの多くの場合、いくつかの7 * 24中断のない操作になると、このようなシステムは、次の要件を持っている傾向があります。

 

まず、高可用性。このようなシステムは、多くの場合、SLAの一部を維持する必要があり、7 * 24中断のない操作が完全に連動意味するものではありませんが、一定の割合があります。たとえば、私たちは多くの場合、サービスのダウンタイムが53分未満である、フォーナイン(99.99%)を達成するために必要な可用性は、年間総ダウンタイムは一時間以上、約53分、それはあることができないと言う、それは高可用性設計の資格を示しています。

 

第二に、ユーザーは、国全体に分散されています。、各地域の人々は、近く訪問することを望んでいること、一般的に全国にサービスを提供するためのシステムではありませんので、大規模なマイクロサービス・システムのユーザーは、一般的に、国でサポートされているが、各領域は、対応するビジネスユニットを持っている必要がありますこれにより、ユーザーは近くアクセスすることができます。

 

第三に、大規模複雑な、存在するピークと谷。マイクロサービスは、実際には、比較的大きい、比較的大きな負荷圧力、および要求に応じて弾性的に伸縮性の山と谷である必要があります。

 

第四に、故障診断のパフォーマンスと迅速な回復のためのメカニズム。大規模マイクロサービスシナリオ、操作および保守担当者は、宣言的に使用しなければならないアプリケーション、操作およびメンテナンス方法のライフサイクルを制御するための操作とメンテナンスマニュアルコマンドを実行することは困難です。あなたは、パフォーマンスのボトルネックや障害点を持っていたらまた、自動検出メカニズムの位置決めポイントはすぐにSLAを保証するために、失敗、タイムリーな修理のボトルネックやポイントを見つけることがあるはずです。

 

戦略的デザイン

 

上記の要件を満たすために、このシステムの運用・保守は、決してグループの努力、またはグループの努力の開発である、解決することができ、エンドツーエンドで、様々な部門は目標を完了するために、私たちは、多くの場合、設計戦略と呼ばれます。

 

まず、R&D

 

高い同時実行、システムの高可用性をサポートすることができ、リンクのR&Dの努力から開始するために必要なする必要があります。

 

まず、各サービスが良いマイクロステートレス処理、電源やその他のサービス・インターフェース・デザインを実現しました。

 

状態は、それ以外の場合は、ユーザを処理することは不可能である、ユーザーのすべての情報がプロセスに格納されている場合、いくつかのプロセスは、分布相から、それはこのプロセスをユーザに配布する必要があり、格納、配布、処理に分割されていますしかし、プロセス、できませんでし拡大は、新しいプロセスが圧力を共有することはできません、ユーザーの元のプロセスデータに保存されているものを扱うことができないだけで始め多くの圧力。

 

だから、キャッシュ、データベース、オブジェクトストアとして、二つの部分、ステートレスとステートフル部分の部分に分割され、しばしばステートレスビジネスロジック部分の一部として使用され、そして状態が中間状態で保持されている全体の構造を有している話このようなメッセージキューのような大きなデータプラットフォーム、。

 

この状態のいかなる部分も簡単にユーザーの配布を簡単に処理するための新しいプロセスに配布することができたときに、拡大縮小せず、バックエンドに状態を保存することができます。バックエンドミドルウェアは、ビジネス層を気にしない、拡張、移行ステータス、複製、同期メカニズムを検討する時間だ、最初から設計されたこれらのミドルウェアステートフルです。

 

データ、データ記載の主なタイプを格納します。

  • メインメモリに保存されたセッションデータなど、。そのようなセッションとしてメモリに格納されたデータについては、それは統合キャッシュの外側に配置することができます。
  • 構造化データは、主にビジネスロジックに関連します。ビジネス関連のデータのためには、統一されたデータベースに格納する必要があります
  • 多くの場合、CDNによって発行された比較的大きなファイルの画像データを、。ファイルの場合、写真などのデータは、内部に保存された統一のオブジェクトに格納する必要があります
  • などのテキスト、コメント、などの非構造化データ、非構造化データのために、それは、例えばElasticSearchために、統一された検索エンジンの内部に存在することができます。

しかし、残された問題は、配布された、処理されているが、データが格納されていない、確かにデータのこの部分にそれを行う方法、データがまだいくつかを失うことになる際に、再起動の過程でいくつかのメモリがあるでしょう?、つまり、そこにありますか

 

このセクションでは、再試行によって解決される必要があり、このコールのコースが失敗した場合の例ダボがあるメカニズムを再試行するために、プロセスのプリアンブルは、再試行されます。再試行するので、それはインタフェースが冪等ある必要があり、二度$ 1転送と呼ばれる、同じトランザクションは、最終的に離れて$ 2オンにすることはできません。

 

インターフェイスは、クエリ、挿入、更新に分け、または操作を削除しています。

 

インタフェース自体の面でのクエリのための特別審査員をしない、冪等です。

 

それぞれが固有の主キーデータを有するだけでなく、挿入の一意性を保証するためにいる場合、プラグインインタフェースが懸念されるため、一度だけ、エラーが報告されていません。

 

更新操作が関係しているため、それはいくつかの場合に分け、より複雑です。

状況は何度も前に、コール冪等の後に、同じインターフェイスです。別のケースでは、繰り返し同じインターフェース、同時環境の正しさを呼び出されます。

 

多くの場合、テーブルを持っているべき等冪等性を維持するために、入力電力と、電力マッチングIDなどの他のパラメータを介してテーブルには、各操作を一度だけ実行されることを保証するために、最終的な時間の実装の一貫性、続行することができ最終的インターフェース呼び出しの成功を確実にするために再試行してください。

 

等の分散ロックのRedis、飼育係によって必要に応じて、呼び出した後に同じ時間を達成するために、同時条件、呼び出すことが最初の場合は、実行される唯一の要求は、結果はまだそれと一致していることを確認するために何回、ありますか?それは多くの場合、それぞれの状態だけ循環一度、ステートマシンによって必要とされます。CASの操作に分散されて楽観的ロックは、あります、それは原子状態の循環を保証することができ、単一のステートメントに統合ステータスの更新を決定します。オプティミスティック・ロックは、必ずしも更新の成功を保証するものではありません、あなたはアップデート失敗に対処するための対応するメカニズムを持っている必要があります。

 

第二に、重要ヒューズ度を達成するためのサービスをダウングレードするためによると、電流制限保護ポリシー

 

サービスには、次のような問題が発生しますアプリケーションレベルで、より多くの分割しました:

 

雪崩サービス:ハングアップされているサービスは、すべてのサービスが影響を受けている全体のリンクを呼び出します。

リクエストの数が多いの蓄積、回復が遅い:ロングスローのサービスを待つ遅いサービス、立ち往生、全体のリンク多数のコールタイムアウトが正常に戻りました。

 

これらの問題を解決するために、我々は次のシナリオのアプリケーションレベルの実装では、次のとおりです。

 

メカニズムを融合することで、サービスは、サービスが時間ヒューズに影響を受けることができたときにハングアップし、フォールバック保証を使用する非クリティカルなサービスの場合、データが入手できない、あなたはまだ続けていくことができます処理します。

非同期技術は、迅速なサービスの失敗を許す、遅すぎる、影響を受けるサービスがすぐにタイムアウトの後に失敗することができますので、サービスがブロックされたときに、スレッドプールとメッセージキューイングを呼び出すことによって、リンク全体には影響しません。

 

彼らは、システム全体の負荷が高すぎるん見つけたら、養子縁組、だけでなく、すべてのコアプロセスを確実にするために使用される最も重要なトランザクション処理の最も重要な資源を確保するための機能や、特定のコールの一部をダウングレードすることを選択できます。

 

ヒューズセットの方針、および両方が全体のリンクをテストするストレスによる戦略のダウングレードを設定するとき、制限する手段、システム全体をサポートする能力は、このようにテストでそのシステムを確保するための戦略を開発する必要性を制限することを知っていることができるはずがありますごみサービスの範囲をサポートする能力を超えて、サポート能力の範囲内で提供すること。ダイアログボックスが「システムがビジー状態である、もう一度試してください」と言ってポップアップ表示時にご注文の場合は、システムがハングアップしていることではなく、システムが正常に動作していることが、制限政策が役割を果たしたという意味ではありません。

 

第三に、各サービスは、知覚されるヘルスチェックサービスのステータスのための効果的なプローブライブインタフェースを設計する必要があります

 

私たちは、関係の操作やメンテナンス部門のために、あなたは、ステートマシンの状態、またはコンテナを監視することができ、サービスを展開する場合、それが実行されている、あなたはまた、プロセスを監視することができます開始され、ポート等、聞いているが、そのプロセスのために開始されました、通常のサービス、運用、保守部門かどうかは、システムの運用・保守の監視が通常のサービスを決定するために、プロセスをこのインタフェースを呼び出すことによって取得することができることができます効果的なプローブライブインタフェースを設計するために、サービスのそれぞれを開発する必要性を認識することはできません。このインタフェースを直接返しませんが、正常な状態からのスレッドは、その後、対応するステータスコードを返すかどうかのサービスを提供するために、内部プロセスを調べる必要があります。だけにして運用・保守サービスを開発し、協働するように、コピーの数にサービスを維持する場合、または開始ものの、サービスの一部が、仮死状態で、他の通常のサービスを行います圧力に耐えることができません。

 

第四に、良いコード検査の規範と静的スキャンツールの開発を通じて、問題を制限するためのシステムを最大限にコードが使用できないために生じました

 

コードの高可用性ラインを維持するために、コードの品質は、オンラインの問題のほとんどは、それがあるかどうか、パフォーマンスの問題や安定性の問題は、インフラストラクチャが原因ではなく、コードによって引き起こされる、鍵となります。また、利用できるインフラが99.95%だったが、この値よりも利用できる高いのサービスレベル要件は、可能なビジネス階建てを補うために必要です。以下の高可用性アーキテクチャセクションに加えて、各サービスのための良好なコード検査規範と静的スキャンツールを開発することが、懸念される、テストケースの多数を通して、制限コードが、利用できない必須であり、高いので、システムの問題が生じ最大利用できる根拠。

 

第二に、高可用性アーキテクチャの設計

 

システムのすべての部分では、我々は、単一のポイントを回避しなければなりません。多くの場合、システムの冗長性制御およびデータプレーン、サブレベルの複数の担当し、各レベルは、通常、高可用性設計する必要があります。

 

 

 

高可用性のためのエンジンルーム内レベルは、複数の領域のそれぞれは、展開のために利用可能な領域を分割し、複数の領域、又は雲の複数の展開されなければなりません。

 

コントロールはまだ、少なくとも二つの部屋に分散制御コンポーネントを必要とする、使用できるように、クラウドの場合、クラウド管理と制御は、失敗するすべての部屋を作り、マルチルームの高可用性の展開に関係しているエンジンルーム全体でデータベースとメッセージキューの管理データの同期。

 

クラウドデータプレーンが懸念されるため、エンジンルームの入口と部屋へのゲートウェイは、高可用性とネットワークを横断行い、そのような入口および公衆IPネットワーク・ロード・バランサすなわち、エンジンルームの障害が発生した場合に、別の部屋に切り替えることができます。

 

 

在云之上要部署Kubernetes平台,管控层面Kubernetes要实现高可用部署,etcd要跨机房高可用部署,Kubernetes的管控组件也要跨机房部署。当然还有一种情况是机房之间距离比较远,需要在每一个机房各部署一套Kubernetes,这种情况下,Kubernetes的管控依然要实现高可用,只不过跨机房的高可用就需要应用层来实现了。

 

在应用层,微服务的治理平台,例如注册发现,zookeeper或者Euraka,APM,配置中心等都需要实现跨机房的高可用。另外就是服务要跨机房部署,实现城市级机房故障迁移能力

 

第三,运维

 

运维一个大规模微服务系统也有不一样的挑战。首先建议使用的是Kubernetes编排的声明式的运维方式,而非ansible之类命令式的运维方式。

 

另外对于系统的发布,要进行灰度、蓝绿发布,降低系统上线发布风险。要有这样的理念,任何一个新上线的系统,都是不可靠的。

 

 

所以可以通过流量分发的模式,逐渐切换到新的服务,从而保障系统的稳定。

 

其三,完善监控及应对机制,对系统各节点、应用、组件全面地监控,能够第一时间快速发现并解决问题。

 

 

监控绝非只有基础设施的CPU,网络,磁盘的监控,应用的,业务的,调用链的监控都应该有。而且对于紧急事件,应该有应急预案,应急预案是在高可用已经考虑过之后,仍然出现异常情况下,应该采取的预案,例如三个etcd全挂了的情况。

 

其四,持续关注线上系统网络使用、服务器性能、硬件存储、中间件、数据库灯指标,重点关注临界状态,也即当前还健康,但是马上可能出问题的状态。例如网关pps达到临界值,下一步就要开始丢包了,数据库快满了,消息出现大量堆积等等。

 

第四,DBA

 

对于一个在线业务系统来讲,数据库是重中之重,很多的性能瓶颈定位到最后,都可能是数据库的问题。所以DBA团队要对数据库的使用,进行把关。

 

造成数据库性能问题,一方面是SQL语句的问题,一方面是容量的问题。

 

例如查询没有被索引覆盖,或者在区分度不大的字段上建立的索引,是否持锁时间过长,是否存在锁冲突等等,都会导致数据库慢的问题。

 

因而所有上线的SQL语句,都需要DBA提前审核,并且要对于数据库的性能做持续的监控,例如慢SQL语句等。

 

另外对于数据库中的数据量也要持续的监控,到一定的量就需要改分布式数据库DDB,进行分库分表,到一定的阶段需要对分布式数据库进行扩容。

 

第五,故障演练和性能压测

 

再好的规划也比不上演练,再好的性能评估也比不上在线的性能压测。

 

性能问题往往通过线上性能压测发现的。线上压力测试需要有一个性能测试的平台,做多种形式的压力测试。例如容量测试,通过梯度的加压,看到什么时候实在不行。摸高测试,测试在最大的限度之上还能承受多大的量,有一定的余量会保险一些,心里相对比较有底。再就是稳定性测试,测试峰值的稳定性,看这个峰值能够撑一分钟,两分钟还是30分钟。还有秒杀场景测试,限流降级演练测试等。

 

只有经过性能压测,才能发现线上系统的瓶颈点,通过不断的修复和扩容瓶颈点,最终才能知道服务之间应该以各种副本数的比例部署,才能承载期望的QPS。

 

对于可能遇到的故障,可以进行故障演练,故意模拟一些故障,来看系统如何反应,是否会因为自修复,多副本,容错等机制,使得这些故障对于客户端来讲没有影响。

 

战术设计

 

下面,我们就从架构的每个层次,进行战术设计。我们先来看一下高可用部署架构选型以及他们的优劣。

架构类型

可用性

优势

问题

单体应用

-

网络开销小

扩展性差,维护困难

单机房服务化

应用级高可用

网络开销小,解耦可扩展

容量受限,机房级单点

同城多活阶段一

机房级高可用

突破单机房容量瓶颈

非必要的跨机房开销大

同城多活阶段二

机房级高可用

非必要的跨机房网络开销小,提供机房级容灾

城市级单点,仍存在非必要的跨机房开销

异地多活单元化

城市级高可用

异地容灾,可用性高

成本较高,要求各应用组件实现单元化

 

高可用性要求和系统的负载度和成本是强相关的。越简单的架构,部署成本越低的架构,高可用性越小,例如上面的单体应用。而微服务化,单元化,异地多活,必然导致架构复杂难以维护,机房成本比较高,所以要使用多少成本实现什么程度的高可用,是一个权衡。

 

高可用的实现需要多个层次一起考虑:

 

 

首先是应用层,可以通过异地多活单元保证城市级高可用,这样使得一个城市因为灾难宕机的时候,另外一个城市可以提供服务。另外每个多活单元采用双机房保证机房级高可用,也即同城双机房,使得一个城市中一个机房宕机,另一个机房可以提供服务。再者每个机房中采用多副本保证实例级高可用,使得一个副本宕机的时候,其他的副本可以提供服务。

 

其次是数据库层,在数据中心之间,通过主从复制或MGR实现数据异步复制,在每个集群单元中采用DDB分库分表,分库分表中的每个实例都是有数据库同步复制。

 

其三是缓存层,在数据中心之间,缓存采用多集群单元化复制,在每个集群单元中采用多副本主从复制。

 

其四微服务治理平台层,平台组件异地多活单元保证了城市级高可用,平台组件每个多活单元采用双机房保证机房级高可用,平台组件每个机房中采用多副本保证实例级高可用。

 

当有了以上高可用方案之后,则以下的故障等级以及影响时间如下表格。

故障层级

预计影响范围

预计SLA影响

恢复手段

应用单实例故障

(进程异常退出,FGC等)

单个或部分用户请求失败。应用有多副本自动重试即可正常

无影响

K8S通过健康检测到异常,自动重启容器

应用单节点故障

(主机硬件异常,掉电等)

部分用户请求失败。应用有多副本自动重试即可正常

<1分钟

K8S检测到节点异常会自动迁移该节点上的容器

中间件单节点故障

(Zookeeper、Eureka)

ZK故障为从节点无影响;

ZK故障为主节点,在重选举时无法注册发现;

Eureka单节点故障无影响;

无影响

自动剔除故障节点,故障节点需手工恢复

缓存单节点故障

(Redis)

Redis集群模式单节点故障无影响;

无影响

自动剔除故障节点,故障节点需手工恢复

数据库单节点故障

(DDB、RDS)

DDN从节点故障无影响;

DDN主节点故障会影响部分用户请求超时;

<1分钟

DDB自动主备切换,故障节点需手工恢复

机房故障

(机房断电,网络分区等)

部分用户请求失败

<15分钟

通过监控检查,切换流量入口至同城机房;

接下来,我们每个层次详细论述。

 

第一,应用层

 

下图以最复杂的场景,假设有三个城市,每个城市都有两个完全对等的数据中心。三个城市的数据中心也是完全对等的。

 

我们将整个业务数据按照某个维度分成A,B,C三部分。这样任何一部分全部宕机,其他部分照样可以提供服务。对于有的业务,如果省级别的服务中断完全不能忍受,市级别的服务中断要求恢复时间相当短,而区县级别的服务中断恢复时间可以相对延长。在这种场景下,可以根据地区来区分维度,使得一个区县和另外一个区县的数据属于不同的单元。

 

为了节约成本,模型可能会更加简化。中心节点和单元化节点不是对称的。中心节点可以实现同城双活,而异地单元化的部分只部署一个机房即可。这样是能满足大部分高可用性需求的。

 

这种架构要求实现中间件层和数据库层单元化,这个我们后面会仔细讲。

 

第二,接入层

 

单元化要求APP层或者在机房入口区域的接入层,实现中心单元和其他单元节点的流量分发。

 

对于初始请求没有任何路由标记的,可以随机分发给任何一个单元,也可以根据地区或者运营商在GSLB中分发给某个就近的单元。

 

应用层接收到请求以后,根据自己所在的单元生成路由信息,将路由信息返回给接入层或者APP。

 

接下来APP或者接入层的请求,都会带着路由信息,选择相应的单元进行发送,从而实现了请求的处理集中在本单元。

 

 

第三,中间件层

 

在中间件层,我们以zookeeper为例,分为以下两个场景。

 

场景一、ZooKeeper 单元化主从多活

 

在这种场景下,主机房和单元化机房距离相隔较近,时延很小,可以当做一个机房来对待。可以采用ZooKeeper高可用保障通过多ZooKeeper实例部署来达成。

 

如图所示,主机房zookeeper有leader和follower,单元化机房的zookeeper仅为observer。

 

 

 

场景二、 ZooKeeper 单元化多集群复制

 

两个机房相距较远,每个机房部署一套ZooKeeper集群,集群之间进行数据同步。各机房应用连接机房内的ZooKeeper集群,注册的信息通过数据同步,能够被其他机房应用获取到。

 

单一机房ZooKeeper集群不可用,其余机房不受影响。当前不考虑做不同机房之间的集群切换。

 

 

第四,数据库层

 

在数据库层,首先要解决的问题是,分布式数据库DDB集群多机房同步复制。

 

在单元内采用同城主从复制模式,跨单元采用DTS/NDC实现应用层数据双向同步能力。

 

 

对于数据的ID分配,应该采取全局唯一ID分配,有两种实现方式,如果主机房和单元化机房距离较近,可采用ID分配依然采用中心式, 所有机房的单元全部向同一中心服务申请ID的方式。如果主机房和单元化机房相隔较远,可采用每个单元各自分配, 通过特定规则保证每个机房得到的最终ID不冲突的方式。

 

 

第五,缓存层

 

在缓存层,有两种方式,方式一是集群热备,新增Redis集群作为热备份集群。

 

 

主集群与备份集群之间在服务端进行数据同步,通过Redis Replication协议进行同步处理。

 

离线监听主集群状态,探测到故障则进行主备之间切换,信息通过配置中心下达客户端,类哨兵方式进行监听探活

 

在这种场景下,集群之间数据在服务端进行同步,正常情况下,集群之间数据会一致。但会存在一定的复制时延。

 

在故障切换时,可能存在极短时间内的数据丢失。如果将缓存仅仅当缓存使用,不要做内存数据库使用,则没有问题。

 

第二种方式,集群多活。新增集群作为多活集群,正常情况下客户端根据Key哈希策略选择分发到不同集群。

 

 

客户端通过Proxy连接集群中每一个节点,Proxy的用处是区分客户端写入与集群复制写入。

集群之间在服务端进行数据双向复制,数据变更通过Redis Replication协议获取。

离线监听主集群状态,探测到故障则进行切换,信息通过配置中心下达客户端,类哨兵方式进行监听探活。

 

此方案应用于单纯的集群间高可用时,同一个Key在同一段时间内只会路由到同一个集群,数据一致性可以保证。

在故障切换情况下,可能存在极端时间内的数据丢失。

 

第六,微服务治理平台

 

作为大规模微服务的微服务治理平台,一方面自己要实现单元化,另外一方面要实现流量在不同单元之间的染色与穿梭。

 

从API网关,NSF服务治理和管理中心,APM性能管理,GXTS分布式事务管理,容器平台的管控都需要进行跨机房单元化部署。

 

当请求到达一个单元之后,API网关上就带有此单元的路由信息,NSF服务治理与管理平台在服务之间相互调用的时候,同样会插入此单元的路由信息,当一个单元某实例全挂的时候,可以穿梭到另一个单元进行调用,并在下一跳调用回本单元,这种方式称为流量染色。

 

 

欢迎关注个人公众号

おすすめ

転載: www.cnblogs.com/popsuper1982/p/11577040.html