写真の配布を加速します


すべてのシステム管理者は、遅かれ早かれ、静的コンテンツの戻りが遅いという問題に直面しています。

これは、おおよそ次のように現れます。3Mb、css、JavaScriptの重さのように3Kbの画像が読み込まれ、JavaScriptが青から「固執」(非常にゆっくりと)し始めます。 ctrl + reloadを押すと、問題はないと思われますが、数分後にはすべてが再び繰り返されます。

「ブレーキ」の真の理由は必ずしも明らかではなく、nginx、ホスティング事業者、「詰まった」チャネル、または「ブレーキ」または「バギー」ブラウザを見ます:)

実際、問題は、スピンドルの回転とヘッドの位置決めの機械的サブシステムにまだ加わっていない最新のハードドライブの欠陥です。

この記事では、nginx WebサーバーでSSDドライブを使用した実際の経験に基づいて、この問題に対する私のソリューションを提供します。


そのハードブレーキを理解する方法は?


Linuxでは、ディスクシステムの速度の問題は、 iowaitパラメーター(I / Oを待機しているCPUアイドルの割合)に直接関連してます。 このパラメータを監視するために、いくつかのコマンドがあります: mpstatiostatsar 。 私は通常iostat 5を起動します(測定は5秒ごとに行われます)。
平均iowaitが最大0.5%のサーバーについては冷静です。 「配布」のサーバーでは、このパラメーターが高くなる可能性があります。 iowait> 10%の場合、最適化を遅らせないことは理にかなっています。システムは、情報を読み取るのではなく、ハードドライブ上でヘッドを移動するのに多くの時間を費やします。

大きなiowaitをどうするか?


明らかに、ディスクI / Oの数を減らすと、ハードドライブが簡単に動き出し、iowaitが落ちます。
以下にいくつかの提案を示します。

これは少し助けになり、アップグレードまで待つ時間を与えます。 プロジェクトが成長している場合、 iowaitは間もなくそのことを思い出します。 :)

アップグレードアイアン



CPUのアップグレードは「減速」しないため、配布速度にはまったく影響しません。 :)

なぜSSD


1年半前、記事「Tuning nginx」を書いたとき、nginxを高速化するためのオプションの1つは、ハードドライブのSSDを使用することでした。 habrasocietyはこのテクノロジーへの関心を控えめに示しました。SSDの経時的なブレーキの可能性と、少数の書き換えサイクルに対する恐怖についての情報がありました。
その記事の公開後まもなく、Kingston SNE125-S2 / 64GBがIntel x25e SSDに基づいて当社に登場しましたこれは今日でも最も負荷の高い「ディストリビューション」サーバーの1つで使用されています。

1年の実験の後、いくつかの欠点が現れました。それについてお話ししたいと思います。
SSDを使用する理由:

SSDキャッシュを構成する


ファイルシステムの選択
実験の開始時に、ext4はKingston SNE125-S2 / 64GBにインストールされました。 インターネットでは、ログの「切り取り」方法、ファイルへの最後のアクセス日などに関する多くの推奨事項があります。 すべてが完璧に、そして長い間機能していました。 最も重要なことは、64G SSDに1〜5Kの多数の小さな写真があり、半分以下のサイズである-20G未満であるということです。 SSDが合理的に使用されていないのではないかと疑い始めました。

カーネルを2.6.35にアップグレードし、(まだ実験的な)btrfsを試してみることにしました。そのssdがマウントされていることを示す機会があります。 ディスクは通常のようにパーティションに分割することはできませんが、全体としてフォーマットされます。

例:
mkfs.btrfs /dev/sdb 

マウントするときに、必要のない多くの機能を無効にし、ファイルとメタデータの圧縮を有効にすることができます。 (実際、jpegは圧縮されず、btrfsはスマートであり、メタデータのみが圧縮されます)。 これはfstabの私のマウント行がどのように見えるかです(すべて1行で):

UUID = 7db90cb2-8a57-42e3-86bc-013cc0bcb30e / var / www / ssd btrfs device = / dev / sdb、device = / dev / sdc、device = / dev / sdd、noatime、ssd、nobarrier、compress、nodatacow、nodatasum 、noacl、notreelog 1 2

コマンドを使用して、フォーマットされたディスクのUUIDを見つけることができます
 blkid /dev/sdb 


その結果、41G以上がディスクに「クライミング」されました(ext4の2倍)。 同時に、配布速度は低下しませんでした(iowaitが増加しなかったため)。

SSDからRAIDを収集します
64G SSDが小さくなった瞬間、複数のSSDを1つの大きなパーティションにまとめたいと同時に、高価なSLCだけでなく、通常のMLC SSDも使用したかったのです。 ここで、少し理論を挿入する必要があります。

Btrfsはディスク上に3種類のデータを保存します。ファイルシステム自体に関するデータ、メタデータブロックのアドレス(常にディスク上にはメタデータのコピーが2つあります)、そして実際にはデータ自体(ファイルコンテンツ)です。 実験的に、ディレクトリ構造内の「圧縮された」メタデータは、セクション内のすべてのデータの約30%を占めることがわかりました。 メタデータは最も集中的に変更されたブロックです。なぜなら、 ファイルの追加、ファイル転送、アクセス権の変更は、メタデータブロックの上書きを伴います。 データが単純に保存される領域は、あまり頻繁に上書きされません。 そこで、btrfsの最も興味深い機能を紹介します。ソフトウェアRAIDアレイを作成し、どのディスクにどのメタデータにデータを保存するかを明示的に示すことです。

例:
 mkfs.btrfs -m single /dev/sdc -d raid0 /dev/sdb /dev/sdd 

その結果、メタデータは/ dev / sdcに作成され、データは/ dev / sdbおよび/ dev / sddに作成され、ストリップされたraidで収集されます。 さらに、 より多くのディスクを既存のシステムに接続したり、データバランシングを実行したりできます。

UUID btrfs RAIDを確認するには、次を実行します。
 btrfs device scan 

注意:btrfs-rideを使用する特殊性:各RAIDアレイをマウントする前、およびbtrfsモジュールをロードした後、コマンドbtrfs device scanを実行する必要があります。 fstabによる自動マウントの場合、 デバイスオプションをマウント行に追加することにより、「btrfsデバイススキャン」なしで実行できます。 例:
 /dev/sdb /mnt btrfs device=/dev/sdb,device=/dev/sdc,device=/dev/sdd,device=/dev/sde 


proxy_cacheを使用しないnginxでのキャッシュ


すべてのコンテンツが格納されているストレージサーバー、多くのスペース、および共有アクセスの大きな負荷を保持できない通常の「低速」SATAハードドライブがあると仮定します。
ストレージサーバーとサイトのユーザーの間に「配布」サーバーがあり、そのタスクは、ストレージサーバーから負荷を取り除き、任意の数のクライアントへの静的な中断のない「配布」を確保することです。

ディストリビューションサーバーのボードにbtrfsを使用して1つ以上のSSDをインストールします。 これは、proxy_cacheに基づいてnginx設定を直接要求します。 しかし、私たちのシステムにはいくつかの欠点があります。

キャッシングには別のアプローチを取ります。 hiload会議の1つでアイデアが閃きました。 キャッシュセクション2にcache0およびcache1ディレクトリを作成します。 すべてのプロキシファイルはcache0に保存されます(proxy_storeを使用)。 nginxは、最初にcache0で、次にcache1でファイルの可用性を確認し(ファイルをクライアントに提供します)、ファイルが見つからない場合はファイルのストレージサーバーに移動して、cache0に保存します。
しばらくしてから(週/月/四半期)、cache1を削除し、cache0の名前をcache1に変更し、空のcache0を作成します。 cache1セクションへのアクセスログを分析し、このセクションから要求されたファイルをcache0にリンクします。

この方法により、SSDの書き込み操作を大幅に削減できます。 ファイルの再リンクは、ファイルを完全に書き換えるよりもまだ少ないです。 さらに、複数のSSDからRAIDを収集できます。そのうちの1つは、メタデータ用のSLCと通常データ用のMLC SSDです。 (私たちのシステムでは、メタデータは総データ量の約30%を占めています) 。 リンクすると、メタデータのみが上書きされます!

Nginxの構成例
 log_format cache0 '$request'; # ... server { expires max; location / { root /var/www/ssd/cache0/ ; try_files $uri @cache1; access_log off; } location @cache1 { root /var/www/ssd/cache1; try_files $uri @storage; access_log /var/www/log_nginx/img_access.log cache0; } location @storage { proxy_pass http://10.1.1.1:8080/$request_uri; proxy_store on; proxy_store_access user:rw group:rw all:r; proxy_temp_path /var/www/img_temp/; #    SSD! root /var/www/ssd/cache0/; access_log off; } # ... 


cache0およびcache1ローテーションのスクリプト
以前に説明したローテーションスキームを実装するのに役立ついくつかのスクリプトをbash作成しました 。 キャッシュのサイズが数百ギガバイト単位で測定され、キャッシュ内のコンテンツの量が数百万単位である場合、次のコマンドで数回ローテーションした直後にria_ssd_cache_mover.shスクリプトを実行することをお勧めします。
 for i in `seq 1 10`; do ria_ssd_cache_mover.sh; done; 
このコマンドを実験的に実行する時間を設定します。 彼女は私のためにほぼ一日働いた。 次は 毎日、cronでria_ssd_cache_mover.shの起動を1時間ごとに設定します。

DOSストレージサーバーに対する保護
ストレージサーバーが弱く、システムを絞めようとする悪意のある人がいる場合、前述のソリューションと一緒にsecure_linkモジュールを使用できます

便利なリンク




UPD1:それにもかかわらず、カーネルを使用することをお勧めします> = 2.6.37以前。 最近、メタデータを含むSSDのスペースオーバーフローが原因で2.6.35で大きなキャッシュクラッシュが発生しました。 その結果、エイリアンは複数のSSDをフォーマットし、btrfs raidを再構築します。 :(

Source: https://habr.com/ru/post/J108958/


All Articles