メモリ管理の最適化に関して、この記事では主に Redis 最適化の経験の概要を共有し、皆様のお役に立てれば幸いです。
Redis ハッシュは値内の HashMap であり、Map のメンバーの数が比較的少ない場合、Map の保存には 1 次元線形に似たコンパクトな形式が使用され、ポインターのメモリ オーバーヘッドが大幅に節約されます。このパラメーター コントロールは、redis.conf 構成ファイル内の次の 2 つの項目に対応します:
hash-max-zipmap-entries 64 hash-max-zipmap-value 512
value Map に少数のメンバーしかない場合デフォルトは 64 です。つまり、値のメンバーが 64 未満の場合は、線形コンパクト ストレージが使用されます。値がこの値を超えると、自動的に実数に変換されます。ハッシュマップ。
hash-max-zipmap-value は、値 Map 内の各メンバー値の長さが特定のバイト数を超えない場合、スペースを節約するために線形コンパクト ストレージが使用されることを意味します。
上記の 2 つの条件のいずれかが設定値を超えると、実際の HashMap に変換され、メモリが節約されなくなります。では、値が大きいほど良いのでしょうか? 答えはもちろんノーです。 HashMap の検索と操作の時間計算量は O(1) ですが、Hash を放棄して 1 次元ストレージを採用すると、メンバーの数が少なければ影響は大きくありません。パフォーマンスに重大な影響を与えるため、一般に、この値の設定は時間コストとスペース コストの間の最も基本的なトレードオフです。 Xlist-Max-Ziplist-Value 64 list-max-ziplist-entries 512
リスト データ タイプ データ タイプ ノード値が、コンパクト ストレージ形式を使用するバイト数、リスト データ タイプの数、コンパクト ストレージを使用するバイト数より小さいポインタへのポインタの形式。
メモリの事前割り当て:
Redis の内部実装では、(Memcache と比較して) メモリ割り当ての最適化があまり行われていません。メモリの断片化はある程度存在しますが、ほとんどの場合、これが Redis のパフォーマンスのボトルネックになることはありません。ただし、Redis に保存されているデータのほとんどが数値である場合、Redis は内部で共有整数メソッドを使用してメモリ割り当てのオーバーヘッドを節約します。つまり、システムの起動時に、まず 1 から n までの数値オブジェクトの数を割り当て、プールでは、保存されたデータがこの値の範囲内にある場合、オブジェクトはプールから直接取得され、参照カウントによって共有されます。これにより、システムが大量のデータを保存する場合でも、一定の時間を節約できます。このパラメータ値 n を設定するには、ソース コード内のマクロ定義 REDIS_SHARED_INTEGERS の行を変更する必要があります。デフォルト値は 10000 です。変更後に再コンパイルするだけです。
永続化メカニズム:
時間指定スナップショットメソッド (スナップショット):
この永続化メソッドは、実際には Redis 内のタイマーイベントであり、一定時間ごとに、現在のデータの変更数と時間が設定された永続性を満たしているかどうかを確認します。トリガーの条件が満たされると、オペレーティング システムのフォーク呼び出しを通じて子プロセスが作成され、この子プロセスはデフォルトで親プロセスと同じアドレス空間を共有します。このとき、子プロセスを通じてメモリ全体をトラバースできます。メインプロセスは引き続きサービスを提供できます。書き込みがある場合、オペレーティングシステムは、親プロセスと子プロセスが相互に影響を及ぼさないように、メモリページ単位でコピーオンライトを実行します。この永続性の主な欠点は、スケジュールされたスナップショットが一定期間内のメモリ イメージのみを表すため、システムを再起動すると、最後のスナップショットから再起動までの間のすべてのデータが失われることです。
ステートメントベースの追加メソッド (aof):
aof メソッドは、実際には mysql のステートメントベースの binlog メソッドに似ています。つまり、Redis メモリ データを変更するすべてのコマンドがログ ファイルに追加されます。ログファイル Redis の永続データです。
aof 方式の主な欠点は、ログ ファイルを追加すると、データを復元するためにシステムを再起動するときに、データの読み込みが非常に遅くなる可能性があることです。数十ギガバイトのデータをロードするには数時間かかります。もちろん、これに時間がかかるのは、ディスク ファイルの読み取り速度が遅いためではなく、読み取られたすべてのコマンドをメモリ内で実行する必要があるためです。さらに、各コマンドはログを書き込む必要があるため、aof を使用すると Redis の読み取りおよび書き込みパフォーマンスも低下します。
各インスタンスのメモリ サイズは約 2G なので、システムへのキャッシュ障害の影響を軽減できるだけでなく、データの回復も高速化できます。速度は向上しますが、システム設計にある程度の複雑さももたらします。
Redis の永続性クラッシュの問題: Redis のオンライン運用とメンテナンスの経験がある人は、物理メモリを大量に使用しても、実際の合計物理メモリ容量を超えていない場合、Redis が不安定になったり、クラッシュしたりすることに気づくでしょう。スナップショットの永続性に基づくフォーク システム コールにより、メモリ使用量が 2 倍になると考えられています。フォーク コールのコピー オン ライト メカニズムはオペレーティング システムのページ単位、つまり、書き込まれたページのみに基づいているため、この見解は不正確です。ダーティ ページはコピーされますが、通常、システムは短期間にすべてのページを書き込むことができないため、コピーが行われます。では、Redis がクラッシュする原因は何でしょうか。
その答えは、Redis の永続性はバッファ IO を使用するということです。いわゆるバッファ IO は、Redis が永続ファイルの書き込みおよび読み取り操作に物理メモリのページ キャッシュを使用することを意味しますが、ほとんどのデータベース システムはこの問題を回避するためにダイレクト IO を使用します。 Redis 永続ファイル (特にスナップショット ファイル) が大きすぎて読み書きする場合、ディスク ファイル内のデータはオペレーティング システムの物理メモリにロードされます。このファイルにはキャッシュ層があり、このキャッシュ層のデータと Redis メモリで管理されているデータは実際には繰り返し保存されますが、物理メモリが不足している場合、カーネルはページ キャッシュを削除する可能性があります。ページ キャッシュの特定のブロックの方が重要であり、プロセスでスワップを開始すると、システムが不安定になったり、クラッシュしたりする可能性があります。私たちの経験では、Redis の物理メモリ使用量が総メモリ容量の 3/5 を超えると、危険性が高まります。
概要:
1. ビジネス ニーズに応じて適切なデータ型を選択し、さまざまなアプリケーション シナリオに対応するコンパクト ストレージ パラメーターを設定します。
2. ビジネス シナリオでデータの永続化が必要ない場合、すべての永続化メソッドをオフにすると、最高のパフォーマンスと最大のメモリ使用量を実現できます。
3. 永続性を使用する必要がある場合は、再起動中の一部のデータの損失を許容できるかどうかに基づいて、スナップショット モードとステートメント追加モードのどちらかを選択します。仮想メモリとディスクストア モードは使用しないでください。
4. Redis が配置されているマシンの物理メモリ使用量が、実際の総メモリの 3/5 を超えないようにしてください。
redis.conf の maxmemory オプション。このオプションは、物理メモリの使用量が増加した後、後続の書き込みリクエストの拒否を開始するように Redis に指示します。このパラメータにより、Redis が物理メモリの過剰な使用によってスワップが発生し、最終的にパフォーマンスやパフォーマンスに重大な影響を与えることを防ぐことができます。クラッシュさえも。
redis.conf ファイルの vm-enabled は no です
関連する推奨事項:
以上がRedis 最適化エクスペリエンスの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。