ホームページ システムチュートリアル Linux Webサーバーのパフォーマンス改善方法

Webサーバーのパフォーマンス改善方法

Jan 07, 2024 pm 06:10 PM
linux Linuxチュートリアル レッドハット Linuxシステム Linuxコマンド Linux 認定 レッドハットリナックス Linuxビデオ

###導入### インターネットの継続的な発展に伴い、日常生活におけるますます多くのニーズがインターネットを通じて実現されており、衣食住、交通手段から金融教育、ポケットからアイデンティティに至るまで、人々はすべてインターネットに依存しています。人々は自分のニーズを満たすためにインターネットを使用します。

顧客からのリクエストに直接対応する Web サーバーとして、同時により多くのリクエストに耐え、ユーザーにより良いエクスペリエンスを提供する必要があることは間違いありません。現時点では、Web側のパフォーマンスが事業展開のボトルネックとなることが多く、パフォーマンスの向上が急務となっています。この記事の著者は、開発プロセス中に Web サーバーのパフォーマンスを向上させたいくつかの経験を要約し、全員と共有しました。

問題分析

Web サーバーのパフォーマンスについては、まず関連する指標を分析します。ユーザーの観点から見ると、ユーザーが Web サービスを呼び出すとき、リクエストが返される時間が短いほど、ユーザー エクスペリエンスは向上します。サーバーの観点から見ると、同時に処理できるユーザー要求の数が多いほど、サーバーのパフォーマンスは向上します。 2 つの側面を組み合わせて、パフォーマンス最適化の 2 つの方向を要約します。

1. サーバーがサポートできる同時リクエストの最大数を増やします;

2. 各リクエストの処理速度を向上させます。

最適化の方向性を明確にする まず、サーバー側に共通のアーキテクチャ パターンを導入します。つまり、ブラウザまたはアプリからの Web リクエストは、サーバー側のいくつかの層の構造を介して処理され、返されます。

アーキテクチャ モード: IP ロード バランシング -> キャッシュ サーバー -> リバース プロキシ -> アプリケーション サーバー -> データベース

図 1 に示すように、説明の便宜上、LVS(Keepalived)->Squid->nginx->Go->MySQL

という実際的な例を示します。

Webサーバーのパフォーマンス改善方法

図 1: サーバー アーキテクチャ

リクエストを各レイヤーに分散することで、下位レベルの構造の複数のブランチが同時に動作して全体の最大同時実行数を増やすことができます。

アーキテクチャと組み合わせて、通常どのような問題がパフォーマンスを妨げているかを分析し、対応する解決策を見つけます。

通常の状況では、主にクラスターの安定性の問題は IP ロード バランシング、キャッシュ サーバー、および nginx プロキシです。パフォーマンスのボトルネックが発生しやすい場所は、多くの場合、アプリケーション サーバー層とデータベース層です。いくつかの例を挙げてみましょう:

1. ブロックの影響

(1) 質問:

ほとんどの Web リクエストは本質的にブロッキングです。リクエストが処理されると、リクエストが完了するまでプロセスは一時停止されます (CPU を占有します)。ほとんどの場合、Web リクエストはすぐに完了するため、この問題は問題になりません。ただし、完了までに時間がかかるリクエスト (大量のデータや外部 API を返すリクエストなど) の場合、処理が終了するまでアプリケーションがロックされ、この間、他のリクエストは処理されなくなります。待機時間が無駄になり、システム リソースが占有され、許容できる同時リクエストの数に深刻な影響を及ぼします。
(2) 解決策:

Web サーバーが前のリクエストの処理を待っている間、処理が完了するまで I/O ループを開いて他のアプリケーション リクエストを処理し、リクエストを待つ代わりにリクエストを開始してフィードバックを与えることができます。プロセスは中断されます。このようにして、不必要な待ち時間を節約し、その時間をより多くのリクエストの処理に使用できるため、リクエストのスループットを大幅に向上させることができます。これは、処理できる同時リクエストの数が巨視的に増加することを意味します。
(3) 例

ここでは、Python Web フレームワークである Tornado を使用して、同時実行パフォーマンスを向上させるためにブロック方法を変更する方法を具体的に説明します。

シナリオ: HTTP リクエストをリモート エンド (非常に安定した Web サイト) に送信する単純な Web アプリケーションを構築します。この期間中、ネットワーク伝送は安定しているため、ネットワークへの影響は考慮されていません。

この例では、Siege (ストレス テスト ソフトウェア) を使用して、サーバー上で 10 秒以内に約 10 個の同時リクエストを実行します。

図 2 に示すように、ここでの問題は、各リクエスト自体がどれほど速く返されたとしても、プロセスが待機しないため、サーバーによるリモート アクセス リクエストへのラウンドトリップで十分な遅延が発生することであることが簡単にわかります。リクエストが完了するまで、データは処理されるまで強制中断状態になります。 1 つまたは 2 つのリクエストではまだ問題はありませんが、ユーザーが 100 人 (または 10 人) になると、全体的な速度の低下を意味します。図に示すように、10 秒未満の類似ユーザー 10 人の平均応答時間は 1.99 秒に達し、合計 29 回に達しました。この例では、非常に単純なロジックのみを示しています。他のビジネス ロジックやデータベース呼び出しを追加すると、結果はさらに悪化します。さらに多くのユーザー リクエストが追加されると、同時に処理できるリクエストの数は徐々に増加し、一部のリクエストがタイムアウトになったり失敗したりする場合もあります。

Webサーバーのパフォーマンス改善方法

図 2: ブロック応答

以下では、Tornado を使用してノンブロッキング HTTP リクエストを実行します。

図 3 に示すように、トランザクション数は 1 秒あたり 3.20 から 12.59 に増加し、同じ期間に合計 118 のリクエストに対応しました。これは本当に大きな改善です!ご想像のとおり、ユーザーのリクエストが増加し、テスト時間が増加しても、上記のバージョンで発生した速度低下に悩まされることなく、より多くの接続に対応できるようになります。これにより、ロードできる同時リクエストの数が着実に増加します。
Web サーバーのパフォーマンス向上の実践

Webサーバーのパフォーマンス改善方法

図 3: ノンブロッキング応答

2. 応答時間と同時実行数に対するコンピューティング効率の影響

まず基本的な知識を紹介しましょう: アプリケーションはマシン上で実行されるプロセスであり、プロセスは独自のメモリ アドレス空間で実行される独立した実行本体です。プロセスは 1 つ以上のオペレーティング システム スレッドで構成されており、これらのスレッドは実際には連携して動作し、同じメモリ アドレス空間を共有する実行本体です。
(1) 質問

従来のコンピューティング手法はシングル スレッドで実行されるため、効率が低く、コンピューティング能力も弱くなります。
(2) 解決策

解決策の 1 つは、スレッドの使用を完全に避けることです。たとえば、複数のプロセスを使用して、オペレーティング システムへの負担を軽減できます。ただし、欠点は、すべてのプロセス間通信を処理する必要があることであり、通常、共有メモリ同時実行モデルよりもオーバーヘッドが大きくなります。

もう 1 つの方法は、マルチスレッドを使用して機能することです。ただし、マルチスレッドを使用するアプリケーションでは、異なるスレッドを同期し、データをロックして、1 つのスレッドだけが変更できるようにすることは困難であることが認識されています。同時にデータも。しかし、過去のソフトウェア開発の経験から、これによりコードがより複雑になり、エラーが発生しやすくなり、パフォーマンスが低下することがわかっています。

主な問題はメモリ内のデータの共有であり、これは複数のスレッドによって予測不可能な方法で操作され、再現不可能またはランダムな結果 (「競合状態」と呼ばれます) が発生します。したがって、この古典的なアプローチは、現代のマルチコア/マルチプロセッサ プログラミングには明らかに適していません。接続ごとのスレッド モデルは十分に効率的ではありません。多くの適切なパラダイムの中に、Communicating Sequential Processes (CSP、C. Hoare によって発明) と呼ばれるパラダイムと、メッセージ パッシング モデル (Erlang など、他の言語で既に使用されている) と呼ばれるものがあります。

ここで使用する方法は、並列アーキテクチャを使用してタスクを処理することです。同時プログラムは複数のスレッドを使用してプロセッサまたはコア上でタスクを実行できますが、複数のコアまたは特定の時点で同じプログラムのみを実行できます。実際の並列処理は複数のプロセッサ上で可能です。

並列処理は、複数のプロセッサを使用して速度を向上させる機能です。したがって、同時プログラムは並列であってもなくてもかまいません。

パラレル モードでは、マルチスレッド、マルチコア、マルチプロセッサ、さらには複数のコンピュータを同時に使用できます。これにより、間違いなくより多くのリソースが動員され、応答時間が短縮され、コンピューティング効率が向上し、パフォーマンスが大幅に向上します。サーバー。
(3) 例

ここではGo言語のGoroutineを使って具体的に説明します。

Go 言語では、アプリケーションの同時処理部分はゴルーチン (コルーチン) と呼ばれ、より効率的な同時操作を実行できます。コルーチンとオペレーティング システム スレッドの間には 1 対 1 の関係はありません。コルーチンは、可用性に基づいて 1 つ以上のスレッドにマップ (多重化、実行) されます。コルーチン スケジューラ Go ランタイムは、このジョブを非常にうまく実行します。コルーチンは軽量であり、スレッドよりも軽いです。これらは非常に目立ちません (そして少量のメモリとリソースを使用します)。4K のスタック メモリのみを使用してヒープ内に作成できます。作成コストが非常に低いため、必要に応じて多数のコルーチン (同じアドレス空間内の 100,000 個の連続コルーチン) を簡単に作成して実行できます。また、スタックを分割してメモリ使用量を動的に増加 (または削減) します。スタック管理は自動ですが、ガベージ コレクターによって管理されず、コルーチンの終了後に自動的に解放されます。コルーチンは、複数のオペレーティング システム スレッド間またはスレッド内で実行できるため、少ないメモリ フットプリントで多数のタスクを処理できます。オペレーティング システム スレッドでのコルーチン タイム スライスのおかげで、少数のオペレーティング システム スレッドを使用して、必要なだけサービスを提供するコルーチンを持つことができ、Go ランタイムはどのコルーチンがブロックされて保留されているかを賢明に把握し、他のコルーチンを処理できます。コルーチン。プログラムであっても、異なるプロセッサやコンピュータ上で異なるコード セグメントを同時に実行できます。

通常、長い計算プロセスをいくつかの部分に分割し、各 goroutine に 1 つの作業を担当させて、1 つのリクエストに対する応答時間を 2 倍にしたいと考えています。

たとえば、3 つのステージに分かれたタスクがあり、ステージ a はデータベース a に行ってデータを取得し、ステージ b はデータベース b に行ってデータを取得し、ステージ c はデータをマージして返します。ゴルーチンを開始すると、フェーズ a とフェーズ b を同時に実行できるため、応答時間が大幅に短縮されます。

端的に言えば、計算処理の一部をシリアルからパラレルに変換することで、関係のない他のタスクの実行終了を待つ必要がなくなり、実際の計算ではプログラムを並列実行した方が有利になります。

ここでは裏付けデータのこの部分についてはあまり詳しく説明しませんが、興味のある学生は自分でこの情報を確認してください。たとえば、Web サーバーを Ruby から Go に切り替えたところ、パフォーマンスが 15 倍向上したという古い話があります (Ruby はグリーン スレッドを使用します。つまり、CPU が 1 つだけ使用されます)。この話は少し誇張されているかもしれませんが、並列処理によってパフォーマンスが向上することは疑いの余地がありません。 (Ruby から Go への切り替え: http://www.vaikan.com/how-we-went-from-30-servers-to-2-go/)。

3. ディスク I/O のパフォーマンスへの影響

(1) 質問

ディスクのデータ読み取りは機械的な動作に依存します。データの読み取りにかかる時間は、シーク時間、回転遅延、転送時間の 3 つの部分に分けられます。シーク時間とは、指定されたトラックへの磁気アームの移動を指します。主流のディスクに必要な時間は、一般に 5ms 未満です。回転遅延とは、よく聞くディスクの速度です。たとえば、7200 rpm のディスクは、1 分間に 7200 回回転できることを意味します。つまり、1 秒間に 120 回回転できることになります。回転遅延は 1/120/2 = 4.17 ミリ秒です。送信時間は、ディスクからの読み取りまたはディスクへのデータの書き込みにかかる時間を指し、通常は 10 分の数ミリ秒ですが、最初の 2 回の時間と比較すると無視できます。ディスクにアクセスする時間、つまりディスク I/O の時間は約 9 ミリ秒 (5 ミリ秒 4.17 ミリ秒) で、これはかなり良いように思えますが、500 MIPS のマシンは 5 億の命令を実行できることを知っておく必要があります。命令は電気の性質に依存しているため、1 秒あたり 400,000 の命令を実行できます。言い換えると、1 つの I/O を実行するのにかかる時間で 400,000 の命令を実行できます。データベースには、多くの場合、数十万、数百万、さらには数千万のデータが含まれています。 9 ミリ秒かかるたびに、明らかに大惨事になります。
(2) 解決策

ディスクを廃棄して別のものと交換しない限り、ディスク I/O がサーバーのパフォーマンスに及ぼす影響に対する根本的な解決策はありません。さまざまな記憶媒体の応答速度や価格はネットで調べることができるので、お金があれば記憶媒体を自由に変更できます。

記憶媒体を変更せずに、キャッシュの設定など、アプリケーションによるディスク アクセスの数を減らすことができます。また、キューやスタックを使用するなど、一部のディスク I/O をリクエスト サイクルの外に置くこともできます。プロセスデータ、I/Oなど

4. データベース クエリの最適化

ビジネス開発モデルの変化に伴い、アジャイル開発が採用されるチームが増え、そのサイクルはますます短くなっています。多くのデータベース クエリ ステートメントはビジネス ロジックに従って記述されています。時間が経つにつれて、SQL クエリは無視されることが多くなります。フォーマットの問題により、データベースへの負荷が増大し、データベース クエリへの応答が遅くなります。ここでは、MySQL データベースで無視されてきたいくつかの一般的な問題と最適化方法を簡単に紹介します。

左端のプレフィックス マッチングの原則は非常に重要な原則です。MySQL は、a = 1、b = 2、c などの範囲クエリ (>、 3 および d = 4 (a、b、c、d) の順序でインデックスを作成すると、d はそのインデックスを使用しません。(a、b、d、c) でインデックスを作成すると、 a、b、dの順序は任意に調整できます。

区別性の高い列をインデックスとして選択するようにしてください。区別の式は count(distinctcol)/count(*) で、これは繰り返されないフィールドの割合を表します。比率が大きいほど、スキャンするレコードは少なくなります。一意のキーの数は 1 です。一部のステータスおよび性別フィールドは、ビッグ データに直面すると 0 の区別を持つ可能性があります。では、この比率には経験的な価値があるのか​​と尋ねる人がいるかもしれません。使用シナリオが異なると、この値を決定するのが難しくなります。通常、結合する必要があるフィールドは 0.1 より大きい必要があります。つまり、1 つあたり平均 10 レコードがスキャンされます。
数値フィールドを使用するようにしてください。フィールドに数値情報のみが含まれる場合は、文字フィールドとして設計しないようにしてください。これにより、クエリと接続のパフォーマンスが低下し、ストレージのオーバーヘッドが増加します。これは、エンジンがクエリや接続を処理するときに文字列内の各文字を 1 つずつ比較し、数値型の場合は 1 回の比較だけで十分であるためです。
インデックス列は計算に参加できません。列を「クリーン」に保ってください。たとえば、from_unixtime(create_time) = '2014-05-29' の場合、インデックスは使用できません。理由は非常に簡単です。B ツリーにはすべてのフィールドが格納されます。データテーブルの値を取得しますが、取得する場合は、比較するすべての要素に関数を適用する必要があり、明らかにコストがかかりすぎます。したがって、ステートメントは create_time = unix_timestamp(’2014-05-29’); のように記述する必要があります。where 句でフィールドの null 値を判断しないようにしてください。そうしないと、エンジンがその使用を断念します。
次のようなインデックスを使用してテーブル全体のスキャンを実行します。
select id from t (num は null)

num にデフォルト値 0 を設定し、テーブルの num 列に null 値がないことを確認してから、次のようにクエリを実行できます。

select id from t where num=0
条件をリンクするために where 句で または を使用しないようにしてください。そうしないと、エンジンはインデックスの使用を断念し、次のようなテーブル全体のスキャンを実行します。 num=10 または num=20
の t から ID を選択します 次のようにクエリできます:

select id from t where num=10 Union all select id from t where num=20

次のクエリでも、テーブル全体のスキャンが行われます (先頭にパーセント記号はありません):
'�c%'
のような名前の t から ID を選択します 効率を向上させるには、全文検索を検討してください。
in と not in も注意して使用する必要があります。そうしないと、次のようなテーブル全体のスキャンが発生します。 select id from t where num in(1,2,3)
連続値の場合、 between を使用できる場合は in を使用しないでください:
select id from t where num は 1 ~ 3

以上がWebサーバーのパフォーマンス改善方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

CentosとUbuntuの違い CentosとUbuntuの違い Apr 14, 2025 pm 09:09 PM

Centosとubuntuの重要な違いは次のとおりです。起源(CentosはRed Hat、for Enterprises、UbuntuはDebianに由来します。個人用のDebianに由来します)、パッケージ管理(CentosはYumを使用し、安定性に焦点を当てます。チュートリアルとドキュメント)、使用(Centosはサーバーに偏っています。Ubuntuはサーバーやデスクトップに適しています)、その他の違いにはインストールのシンプルさが含まれます(Centos is Thin)

Centosはメンテナンスを停止します2024 Centosはメンテナンスを停止します2024 Apr 14, 2025 pm 08:39 PM

Centosは、上流の分布であるRhel 8が閉鎖されたため、2024年に閉鎖されます。このシャットダウンはCentos 8システムに影響を与え、更新を継続し続けることができません。ユーザーは移行を計画する必要があり、提案されたオプションには、Centos Stream、Almalinux、およびRocky Linuxが含まれ、システムを安全で安定させます。

Centosをインストールする方法 Centosをインストールする方法 Apr 14, 2025 pm 09:03 PM

Centosのインストール手順:ISO画像をダウンロードし、起動可能なメディアを燃やします。起動してインストールソースを選択します。言語とキーボードのレイアウトを選択します。ネットワークを構成します。ハードディスクをパーティション化します。システムクロックを設定します。ルートユーザーを作成します。ソフトウェアパッケージを選択します。インストールを開始します。インストールが完了した後、ハードディスクから再起動して起動します。

Dockerの原則の詳細な説明 Dockerの原則の詳細な説明 Apr 14, 2025 pm 11:57 PM

DockerはLinuxカーネル機能を使用して、効率的で孤立したアプリケーションランニング環境を提供します。その作業原則は次のとおりです。1。ミラーは、アプリケーションを実行するために必要なすべてを含む読み取り専用テンプレートとして使用されます。 2。ユニオンファイルシステム(UnionFS)は、違いを保存するだけで、スペースを節約し、高速化する複数のファイルシステムをスタックします。 3.デーモンはミラーとコンテナを管理し、クライアントはそれらをインタラクションに使用します。 4。名前空間とcgroupsは、コンテナの分離とリソースの制限を実装します。 5.複数のネットワークモードは、コンテナの相互接続をサポートします。これらのコア概念を理解することによってのみ、Dockerをよりよく利用できます。

Centosのgitlabのバックアップ方法は何ですか Centosのgitlabのバックアップ方法は何ですか Apr 14, 2025 pm 05:33 PM

Centosシステムの下でのGitlabのバックアップと回復ポリシーデータセキュリティと回復可能性を確保するために、Gitlab on Centosはさまざまなバックアップ方法を提供します。この記事では、いくつかの一般的なバックアップ方法、構成パラメーター、リカバリプロセスを詳細に紹介し、完全なGitLabバックアップと回復戦略を確立するのに役立ちます。 1.手動バックアップGitlab-RakeGitlabを使用:バックアップ:コマンドを作成して、マニュアルバックアップを実行します。このコマンドは、gitlabリポジトリ、データベース、ユーザー、ユーザーグループ、キー、アクセスなどのキー情報をバックアップします。デフォルトのバックアップファイルは、/var/opt/gitlab/backupsディレクトリに保存されます。 /etc /gitlabを変更できます

Dockerデスクトップの使用方法 Dockerデスクトップの使用方法 Apr 15, 2025 am 11:45 AM

Dockerデスクトップの使用方法は? Dockerデスクトップは、ローカルマシンでDockerコンテナを実行するためのツールです。使用する手順には次のものがあります。1。Dockerデスクトップをインストールします。 2。Dockerデスクトップを開始します。 3。Docker Imageを作成します(DockerFileを使用); 4. Docker画像をビルド(Docker Buildを使用); 5。Dockerコンテナを実行します(Docker Runを使用)。

セントスにハードディスクをマウントする方法 セントスにハードディスクをマウントする方法 Apr 14, 2025 pm 08:15 PM

CentOSハードディスクマウントは、次の手順に分割されます。ハードディスクデバイス名(/dev/sdx)を決定します。マウントポイントを作成します( /mnt /newdiskを使用することをお勧めします);マウントコマンド(Mount /dev /sdx1 /mnt /newdisk)を実行します。 /etc /fstabファイルを編集して、永続的なマウント構成を追加します。 Umountコマンドを使用して、デバイスをアンインストールして、プロセスがデバイスを使用しないことを確認します。

Centosがメンテナンスを停止した後の対処方法 Centosがメンテナンスを停止した後の対処方法 Apr 14, 2025 pm 08:48 PM

CentOSが停止した後、ユーザーは次の手段を採用して対処できます。Almalinux、Rocky Linux、Centosストリームなどの互換性のある分布を選択します。商業分布に移行する:Red Hat Enterprise Linux、Oracle Linuxなど。 Centos 9ストリームへのアップグレード:ローリングディストリビューション、最新のテクノロジーを提供します。 Ubuntu、Debianなど、他のLinuxディストリビューションを選択します。コンテナ、仮想マシン、クラウドプラットフォームなどの他のオプションを評価します。

See all articles