お使いのシステムは、高い同時実行をサポートする方法:人々は何をすべきか知っている特定の問題について尋ねられたとき、多くの人がインタビュー?
学生のほとんどは、単に何も答えることを考えていませんでした質問をどこから始めれば分からない、実際には、本質的には、ベール気性いくつかの本当に高い並行システムを経験していません。
ノーオーバー関連のプロジェクトの経験があるので、私たちは本当の経験と、その後の回答のセットの経験、彼らは高い同時実行をサポートするにはあまりにも複雑なシステムから出てくるかの体系的な博覧会から自分自身を抽出することができません。
だから、簡単にこの問題にカットし、この記事でこのような観点から、私たちはどのように対処する最も簡単なアイデアを使用する方法を教えます。
もちろん、ここでの最初の明確な前提:非常に並行システムが異なります。第二同時ミドルウェア・システム、ゲートウェイシステム要求の何千もの第二の瞬間スパイク大きなプロモーションシステムの何百ものあたり毎日百億リクエストあたりの例メガビットのため。
それらがので、各システムの特性の異なる、高い並行性を扱うので、アーキテクチャに対処するとき、それは同じではありません。
ビジネスシナリオの背後に異なるため、また注文システムにおいて、そのような電子ビジネスプラットフォーム、商品系、高い並行性のシナリオの在庫システムアーキテクチャ設計は、異なっています。
そのため、この資料では、インタビュアー大眼瞪小眼で、インタビューの中でこの質問をされることはありませんので、それは、任意の複雑なアーキテクチャ設計を必要としない、あなたの考えている、このような質問に対する答えを提供することが主な理由です。
具体的にインタビューの中で、本当に良い答え、この問題に、我々はあなたがこの記事の思考を参照することをお勧めします、そして、あなたの手を考えることが、システムのより多くの責任がある、それは建築の練習に関連する何かをするのが最善です。
1、最初のシンプルなシステムアーキテクチャを検討
お使いのシステムは、単にデータベースに接続し、その背後にあるマシン上に展開され始めていると仮定すると、データベースは、単一のサーバーにデプロイされます。
あなたも、このようなシステムの導入機は4コア8Gであるように、現実的になりたいことがあり、データベース・サーバは、16コア32Gです。
この時点で10万の合計量、稀にユーザーの量は、日活のユーザーが、異なるシステムの状況に応じて差別化システムのユーザーは、我々はより客観割合、それの10%、毎日のアクティブユーザー10000を取ることが想定されます。
パレートのルールによると、その日のピークは4時間をカウントし、80%を占めアクティブユーザーのピークは、その4時間でアクティブ8,000人です。
その後、システム上の誰もが、我々はそれを数える20回日に応じて、要求を開始します。その後も4時間以内(14400秒)を平均化する毎秒もわずか16万回、毎秒10個の要求8000-開始した要求のピーク。
すべての権利!同時実行性の高い完全な権利、シェアを取りますか?
次に、システム・レベルは、第2の要求あたり10回であるすべてのこのようなCRUD等を行うなど、いくつかのデータベース操作を要求するデータベースへの呼び出し。
だから我々は、これはデータベース層は右、また、1秒間に30のリクエストの場合であることを、最初の要求は、データベースがそれを要求した3回に対応取りますか?
この構成データベースサーバーのサポートによると、全く問題ありません。
ビュー示すと、上述したシステムは、これは以下の通りです。
2、システムのクラスタの展開
ユーザーの数は、このような登録ユーザーの量として、急速に成長し始めたと仮定すると5億に上昇し、50倍に増加しました。
この時点日活50万ユーザー、秒あたりの要求のピーク時には、システムは、500 / sです。そして、第二の数あたりのデータベース要求は何が起こるか、この時間、1500 / sのでしょうか?
プロセスは、いくつかのビジネスロジック、より複雑なシステムである場合は、上記のマシン構成によると、ビジネスロジックが重いシステムの一種である、そして、比較的時間のかかるCPUです。
この時点で、毎秒4コア8G要求は、マシンが、それはあなたのマシンをロードCPUに高い可能性があり、500 / sに達したとき。
次に、データベース・レベルは、上記構成の点で、実際には、実質的にその後まだ許容1500 / S要求圧力ピーク。
これは、データベースのディスク負荷、ネットワーク負荷、CPU負荷、メモリ負荷マシンを観察するために主に、当社のオンライン経験に基づいて、構成データベースには、1500 / sの要求に圧力下に問題はありません。
したがって、この場合には最初は、お使いのシステムのクラスタの展開をサポートすることで、事を行う必要があります。
ロードバランシング層の前でハングアップすることができ、要求は、システムが複数のクラスタ化されたマシンが高い同時実行性の圧力をサポートする使用することができ、均一なシステムレベルを打ちます。
例えば、システムは、機械の配置、各マシンのみ250リクエスト/秒のものとします。
その結果、2台のマシンが大幅にCPUの負荷を軽減します、この最初の「高い同時実行」は、第1のカバーにそれを生きる上ではないのですか?
でも、これが行われていない場合は、極端な場合には、その単一のマシンの負荷が高いと高いが、要求に対応するための十分なリソースを持つことができないマシン上でシステムを展開することが可能である、との要求も、システムのダウンタイムの、こだわって表示されたとき問題のクラス。
だから、簡単な要約、最初のステップ:
負荷分散層を追加し、層系の要求が均等にヒット。
複数のマシンのクラスタの展開、カン朱予備同時圧力を使用してシステム層。
このアーキテクチャ図では、次のように次のようになります。
3、データベースサブライブラリ別個読み取りおよび書き込みサブテーブル+
、利用者の数は増加し続けていることを仮定すると、千万の登録ユーザーに達し、その後、毎日一万人のユーザーの日常生活です。
那么此时对系统层面的请求量会达到每秒1000/s,系统层面,你可以继续通过集群化的方式来扩容,反正前面的负载均衡层会均匀分散流量过去的。
但是,这时数据库层面接受的请求量会达到3000/s,这个就有点问题了。
此时数据库层面的并发请求翻了一倍,你一定会发现线上的数据库负载越来越高。
每次到了高峰期,磁盘IO、网络IO、内存消耗、CPU负载的压力都会很高,大家很担心数据库服务器能否抗住。
没错,一般来说,对那种普通配置的线上数据库,建议就是读写并发加起来,按照上述我们举例的那个配置,不要超过3000/s。
因为数据库压力过大,首先一个问题就是高峰期系统性能可能会降低,因为数据库负载过高对性能会有影响。
另外一个,压力过大把你的数据库给搞挂了怎么办?
所以此时你必须得对系统做分库分表 + 读写分离,也就是把一个库拆分为多个库,部署在多个数据库服务上,这是作为主库承载写入请求的。
然后每个主库都挂载至少一个从库,由从库来承载读请求。
此时假设对数据库层面的读写并发是3000/s,其中写并发占到了1000/s,读并发占到了2000/s。
那么一旦分库分表之后,采用两台数据库服务器上部署主库来支撑写请求,每台服务器承载的写并发就是500/s。每台主库挂载一个服务器部署从库,那么2个从库每个从库支撑的读并发就是1000/s。
简单总结,并发量继续增长时,我们就需要focus在数据库层面:分库分表、读写分离。
此时的架构图如下所示:
4、缓存集群引入
接着就好办了,如果注册用户量越来越大,此时你可以不停地加机器,比如说系统层面不停加机器,就可以承载更高的并发请求。
然后数据库层面如果写入并发越来越高,就扩容加数据库服务器,通过分库分表是可以支持扩容机器的,如果数据库层面的读并发越来越高,就扩容加更多的从库。
但是这里有一个很大的问题:数据库其实本身不是用来承载高并发请求的。所以通常来说,数据库单机每秒承载的并发就在几千的数量级,而且数据库使用的机器都是比较高配置,比较昂贵的机器,成本很高。
如果不停地加机器,这是不对的。
在高并发架构里通常都有缓存这个环节,缓存系统的设计就是为了承载高并发而生。
单机承载的并发量都在每秒几万,甚至每秒数十万,对高并发的承载能力比数据库系统要高出一到两个数量级。
可以根据系统的业务特性,对那种写少读多的请求,引入缓存集群。
具体来说,就是在写数据库的时候同时写一份数据到缓存集群里,然后用缓存集群来承载大部分的读请求。
这样的话,通过缓存集群,就可以用更少的机器资源承载更高的并发。
比如说上面那个图里,读请求目前是每秒2000/s,两个从库各自抗了1000/s读请求,但是其中可能每秒1800次的读请求都是可以直接读缓存里的不怎么变化的数据的。
那么此时你一旦引入缓存集群,就可以抗下来这1800/s读请求,落到数据库层面的读请求就200/s。
同样,给大家来一张架构图,一起来感受一下:
按照上述架构,好处是什么呢?
可能未来你的系统读请求每秒都几万次了,但是可能80%~90%都是通过缓存集群来读的,而缓存集群里的机器可能单机每秒都可以支撑几万读请求,所以耗费机器资源很少,可能就两三台机器就够了。
要是换成数据库来试一下,可能就要不停地加从库到10台、20台机器才能抗住每秒几万的读并发,那个成本是极高的。
好了,我们再来简单小结,承载高并发需要考虑的第三个点:
不要盲目进行数据库扩容,数据库服务器成本昂贵,且本身就不是用来承载高并发的
针对写少读多的请求,引入缓存集群,用缓存集群抗住大量的读请求
5、引入消息中间件集群
接着再来看看数据库写这块的压力,其实是跟读类似的。
假如说所有写请求全部都落地数据库的主库层,当然是没问题的,但是写压力要是越来越大了呢?
比如每秒要写几万条数据,此时难道也是不停的给主库加机器吗?
可以当然也可以,但是同理,耗费的机器资源是很大的,这个就是数据库系统的特点所决定的。
相同的资源下,数据库系统太重太复杂,所以并发承载能力就在几千/s的量级,所以此时你需要引入别的一些技术。
比如说消息中间件技术,也就是MQ集群,是非常好的做写请求异步化处理,实现削峰填谷的效果。
假如说,现在每秒是1000/s次写请求,其中比如500次请求是必须请求过来立马写入数据库中的,但是另外500次写请求是可以允许异步化等待个几十秒,甚至几分钟后才落入数据库内的。
那么此时完全可以引入消息中间件集群,把允许异步化的每秒500次请求写入MQ,然后基于MQ做一个削峰填谷。比如就以平稳的100/s的速度消费出来然后落入数据库中即可,此时就会大幅度降低数据库的写入压力。
此时,架构图变成了下面这样:
大家看上面的架构图,首先消息中间件系统本身也是为高并发而生,所以通常单机都是支撑几万甚至十万级的并发请求的。
所以,这本身也跟缓存系统一样,可以用很少的资源支撑很高的并发请求,用来支撑部分允许异步化的高并发写入是没问题的,比使用数据库直接支撑那部分高并发请求要减少很多的机器使用量。
而且经过消息中间件的削峰填谷之后,比如就用稳定的100/s的速度写数据库,那么数据库层面接收的写请求压力,不就成了500/s + 100/s = 600/s了么?
大家看看,是不是发现减轻了数据库的压力?
到目前为止,通过下面的手段,我们已经可以让系统架构尽可能用最小的机器资源抗住了最大的请求压力,减轻了数据库的负担。
系统集群化
数据库层面的分库分表+读写分离
针对读多写少的请求,引入缓存集群
针对高写入的压力,引入消息中间件集群
初步来说,简单的一个高并发系统的阐述是说完了。
但是,其实故事到这里还远远没有结束。
6、现在能Hold住高并发面试题了吗?
看完了这篇文章,你觉得自己能回答好面试里的高并发问题了吗?
很遗憾,答案是不能。而且我觉得单单凭借几篇文章是绝对不可能真的让你完全回答好这个问题的,这里有很多原因在里面。
まず、高並行性のトピック自体は記事のいくつかははっきり言うことができるから非常に複雑な、そう遠くない、本質は非常に並行システム・アーキテクチャにおける本当の支援複雑なビジネス・シナリオは実際には非常に複雑であることです。
第二同時ミドルウェア・システムごとに例のメガビット、ゲートウェイシステム百億毎日の要求、秒あたりの要求の数十万人のための大きな推進体制スパイク、瞬時に、大規模かつハイパワーなビジネスプラットフォーム・アーキテクチャなどの数百万人のユーザーのサポート数百。
高い同時リクエストをサポートするために、システムアーキテクチャ設計は、特定のビジネス・シナリオや特性に特異的に結合する基本的な技術サポートの多くを必要とする複雑なアーキテクチャの様々な設計、洗練された構造物を設計する能力とメカニズムが必要になります。
最後に、これまでの学生のほとんどを超えた複雑なシステムアーキテクチャの複雑さのプレゼンテーションは、想像力を連絡しませんでした。
しかし、その後、複雑なシステムアーキテクチャ、記事のいくつかを明確にさまざまな詳細の内側と床の製造工程を言うのは難しいです。
サブライブラリーのサブテーブル、キャッシュ、ニュース:第二に、高い同時実行このコンテンツトピック自体は紙よりもはるかに多くが含まれているので、いくつかのトピックと述べました。
完全かつ複雑な高い並行処理システムアーキテクチャは、問い合わせので、複雑なインフラシステムの様々な、完全なリンクが含まれ、ホット・キャッシュ・アーキテクチャ、マルチ優先ハイスループットMQアーキテクチャ設計、システムとしての絶妙な建築設計(種々の同時パフォーマンスの最適化設計など)だけでなく、システムの並行性の高いアーキテクチャ全体の技術的なプログラムの複雑な組み合わせ、ならびにNoSQLの(elasticsearchなど)/負荷分散/ Webサーバやその他の関連技術。
だから我々は、技術の畏敬の念を保つために覚えて、これらのものは、いくつかの記事で明確に表現するのは困難です。
最後に、実際の着陸時に並行性の高いシナリオの下での生産システムは技術的な問題の多くになります。
例えば、メッセージングミドルウェアのスループットを最適化する必要が増加しない、ディスクがあまりにも簡単に爆発しすぎ圧力パフォーマンスの低下、メモリ消費量を書き込み、サブサブテーブルのデータベースミドルウェアは知らないなぜそれで失われたデータとそう。
これらの記事はすべてにそれを明確にすることにより、非常に多くのような質問には、それは不可能です。