ユーザー数は急速に増加し、アクセス数は短期間で 2 倍になりました。初期のキャパシティ プランニングは比較的良好であったため、ハードウェア リソースはそれをサポートできましたが、ソフトウェア システムには大きな問題がありました。リクエストの 40% が HTTP 500: Internal Server Error を返します
問題の説明
初期の適切な容量計画により、ユーザー数は急速に増加し、アクセス数は短期間で 2 倍になりました。 、ハードウェア リソースはサポートできますが、ソフトウェア システムに大きな問題があります:
リクエストの 40% が Return HTTP 500: Internal Server Error になります
ログを確認すると、接続処理でエラーが発生していることがわかりましたPHP の <->
デバッグ処理
初回
最初は根本原因が見つからなかったので、次のようなエラー関連のさまざまな方法を試すことができます:
PHP の数を増やす接続を増やし、タイムアウトを500ミリ秒から2.5秒に増やします
PHP設定でdefault_socket_timeoutを無効にします
ホストシステムでSYNクッキーを無効にします
RedisとWebサーバーを確認しますファイル記述子の数を確認します
ホストシステムのmbufferを増やします
TCPバックログの数を調整します
...
多くの方法を試しましたが、どれも効果がありませんでした
2回目
この問題をプレリリース環境で再現したいと考えましたが、残念ながら、おそらくトラフィックが再現できるほど大きくないため、まだ失敗しました
3 回目
コード内で Redis 接続が閉じられていない可能性がありますか?
通常、PHP は実行終了時にリソース接続を自動的に閉じますが、古いバージョンではメモリ リークが発生する可能性があるため、安全を期すためにコードを変更して接続を手動で閉じます
結果はまだ無効です
。 4回目
不審なターゲット: phpredisクライアントライブラリ
A/Bテストを実施し、predisライブラリを置き換え、データセンター内のユーザーの20%に導入
適切なコード構造のおかげで置き換え作業が完了すぐに結果が得られます まだ無効ですが、良い面もあります 5回目
Redis をアップグレードして試してみてください。アップグレード後もまだ動作しません 大丈夫、楽観視してください。これは Redis バージョンを最新にアップグレードする方法ではありません
6 回目です
$ redis-cli --latency -p 6380 -h 1.2.3.4 min: 0, max: 463, avg: 2.03 (19443 samples)
Redis ログを表示します:
... [20398] 22 May 09:20:55.351 * 10000 changes in 60 seconds. Saving... [20398] 22 May 09:20:55.759 * Background saving started by pid 41941 [41941] 22 May 09:22:48.197 * DB saved on disk [20398] 22 May 09:22:49.321 * Background saving terminated with success [20398] 22 May 09:25:23.299 * 10000 changes in 60 seconds. Saving... [20398] 22 May 09:25:23.644 * Background saving started by pid 42027 ...
問題を見つけました:
データを保存数分ごとにハードディスクにアクセスしているのに、バックグラウンド ストレージをフォークするのになぜ約 400 ミリ秒かかるのですか (上記のログで 1 番目と 2 番目のエントリの時間を確認できます) この時点で、ついにソースを見つけました。問題: Redis インスタンスには大量のデータがあるため、永続化操作ごとにバックグラウンド プロセスをフォークするのに非常に時間がかかり、業務内でキーが頻繁に変更されるため、永続化が頻繁にトリガーされます。解決策: 永続化には別のスレーブを使用します。このスレーブは実際のトラフィック リクエストを処理しません。唯一の機能は、以前の Redis インスタンスの永続化操作をこのスレーブに転送することです。明らかに、問題は基本的に解決されていますが、時々エラーが報告されます前回の調整後、トラフィックが増加し続けた場合でも、問題は解決されました。 、それは耐えることができました
しかし、彼らは新しい問題に気づきました:
現在の方法では、リクエストが来たときにRedis接続を作成し、いくつかのコマンドを実行してから、リクエストの量が多い場合、この方法では切断されます。コマンドの半分以上が接続操作の処理に使用されており、ビジネス ロジックの処理を超えて Redis の速度が低下します 解決策: プロキシを導入し、twitter の twemproxy を選択しました。プロキシをインストールするだけで済みます。各 Web サーバーでは、twemproxy が Redis インスタンスとの永続的な接続を担当し、これにより接続操作が大幅に削減されます
キーなどの非常に時間のかかる、または危険なコマンドをブロックできます。フラッシュオール
効果は当然完璧で、以前の接続エラーを心配する必要はもうありません
9回目
同じデータの一貫したハッシュシャーディングcontext
効果: 各マシンのリクエストと負荷を削減しますキャッシュの信頼性を向上させます 安全性、ノード障害を心配する必要はありません
以上がこの記事の全内容です、皆さんの学習に役立つことを願っています。
関連する推奨事項:
redis に存在しない 6 桁の乱数を取得するメソッド
redisWeiboメソッドを公開するメッセージキューのPHP実装
CIフレームワーク(CodeIgniter)の操作redisステップ分析
以上が実際のプロジェクトで php+redis を使用して HTTP 500: Internal Server Error をトラブルシューティングする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。