RedisのはRedisのを使用することである、達成するために、シングルスレッドモデルに基づいています(Redisのは、ノンブロッキングIOを使用しているが、すべてのクライアント要求を処理するためのスレッドである、とコマンドの様々な最適化された操作コマンドの時間複雑さの大半度はO(1))であるが、それはより多くの我々はいくつかの手段を介しなり、この記事を最適化し、パフォーマンス要件の厳しいですので、Redisの特性ので、シングルスレッドの実行で、Redisのより効率的な動作をしましょう。
本論文では、走行速度のRedisを強化するために以下の手段を使用します。
- 格納されたキーと値のペアの長さを短くします。
- 怠け者無料(遅延削除)特性を使用します。
- 有効期限のキー値を設定します。
- 無効に長い時間のかかる問合せコマンド。
- 使用slowlog最適化は、コマンドを取ります。
- パイプラインデータのバッチ処理を使用しました。
- 同時に大量のデータを避けるために失敗。
- クライアントは、最適化を使用しています。
- Redisのメモリサイズ制限。
- 代わりに、Redisのサービスをインストールするには、物理マシンの仮想マシンを使用します。
- データの永続化戦略を確認してください。
- 無効にTHP特性;
- 読み取りおよび書き込み速度を向上させるために、分散アーキテクチャを使用しました。
1.キーと値のペアは、メモリ長を短くします
そして、鍵ペアの長さは、次のように我々は、書き込みデータが実行されないパフォーマンステストのセットとして、パフォーマンスに反比例します。
場合には、上記のデータから分かるように、ここで同じキー、値が大きい値遅い運用効率、同じデータ型のためのRedisが記憶異なる内部コードを使用するので、例えば3つの内符号列があります。 (コード整数)INTは、理由のRedisのRAW(メモリ割り当て最適化文字列コード)、embstr(動的ストリング・コード)は、異なる符号化、しかし、大きなによって使用されるデータの量を効率と空間のバランスを達成することですより複雑な内部エンコーディングは、より複雑な保存され、内部でのパフォーマンスを下げます。
これは、書き込みのスピードだけで、大規模のコンテンツ用の鍵でなく、他のいくつかの問題を持っています:
- 長いコンテンツの持続時間が時間を停止する、より大きな、より長く必要性、Redisのパフォーマンスの低下のために必要。
- ネットワーク上の大きいコンテンツ、より多くのコンテンツ送信、より長い時間が必要で、全体的な速度を下げます。
- より多くのコンテンツメモリの容量も大きく、メモリはRedisのを与えて、より頻繁除去メカニズムをトリガするには、より多くをもたらした負担を実行します。
、Javaで、例えば、私たちは直列化またはprotostuff Kryoを使用することができ、必要に応じてこのように、我々は、キーのメモリ長を短くしようとすると、データ系列を圧縮すると再保存された完全なセマンティクスを確保し、我々は圧縮することができますてきぱきを使用しています。
2.怠惰無料特性
Redisの4.0怠惰なフリー性は、それは、不活性削除または削除の遅延として理解することができる、新しい機能が使用されています。除去手段により有効であるメインスレッドを削除するのRedisを除去するための閉塞を低減するために、個々のサブスレッドを処理する非同期時間放出ファンクションキー、BIO(バックグラウンドI / O)に離鍵操作に設けられています大きなキーを削除するときに回避のパフォーマンスと可用性の問題が発生します。
4に対応する怠惰な無料のシーンは、デフォルトで閉じられています。
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
slave-lazy-flush no
复制代码
彼らは、以下の意味を表します。
- lazyfree-怠惰-立ち退きは:オープン怠惰な無料のメカニズムを削除するかどうか、Redisのメモリがよりmaxmeoryより実行するときことを示しています。
- lazyfree-レイジー期限が切れる:キーセットの有効期限が切れたときに怠惰な無料のメカニズムを削除開くかどうか、有効期限を表し、
- lazyfree-怠惰なサーバ・デル:これらの目的ならば、キーがすでに存在している取り扱いのいくつかの命令は、それは、ターゲット・キーがすでに存在する場合、このようなrenameコマンドなどの暗黙的なデルのキー、で動作する最初のRedisのターゲット・キーを削除しますキーが大きな鍵となり、それが削除された、この設定を削除怠惰無料メカニズムを開くかどうかを、このシナリオで示され、ブロッキングの問題が発生します。
- スレーブレイジーフラッシュ:スレーブ(スレーブノード)のために行ったデータ同期の全額、RDBファイルをロードする前にスレーブマスターは、削除怠惰無料メカニズムをオープンするかどうか、現時点で表して、自分のデータを、クリーンアップするflushallを実行します。
あなたが効果的にメインスレッドの効率を向上させることができるように、lazyfree-レイジー立ち退き、lazyfree-レイジー期限が切れる、lazyfree-怠惰なサーバ・デル・ターン、それらの他の構成ことをお勧めします。
3.キーの有効期限を設定します
Redisのは、あなたが自動的に頻繁にメモリをトリガー、キーの過剰な蓄積を避けるために、メモリ使用量を節約するために、古くなったキーと値のペアを削除するのに役立ちますように、我々は、キー値が妥当な有効期限を設定し、実際のビジネスケースに基づいている必要があります制圧戦略。
4.無効に長い時間がかかるクエリ
O(N)の間の読み取りおよび書き込みコマンドの複雑さはO(1)されている時間のRedisの過半数は、公式文書、アドレスに記述されている各コマンドのための時間の複雑さがあります。redis.io/commands、などを...
O(1)安全な使用を表し、O(N)は注意する必要があり、Nは、不確実性を表している、より大きなデータ・クエリの速度が遅くなることができます。Redisのデータのクエリを行うための一つのスレッドだけなので、これらのディレクティブは長い時間がかかる場合は、Redisのは、遅延の多くを引き起こして、ブロックされます。Redisの上のO(N)コマンドへの影響を回避するために以下の態様から開始することができる形質転換によって引き起こされます。
- キーコマンドの使用を禁止することを決めました。
- スキャンコマンドバッチ、バーニアトラバーサルを使用するすべてのメンバーのためのクエリを避けてください。
- 厳密な制御機構により、データサイズのハッシュ、セット、ソートセット構造等;
- ソート、和、積、およびその他の操作は、運転圧力Redisのサーバーを減らすために、クライアント上で実行しました。
- 削除(デル)ビッグデータは、それはそれはRedisののメインスレッドをブロックすることなく、目的のデータを削除するには、新しいスレッドを開始します、リンク解除非同期方式を削除することが提案されている、長い時間がかかる場合があります。
5. slowlog最適化は、コマンドを取ります
私たちは、最も時間のかかるRedisのを識別するためにslowlog機能を使用できる2つの重要な設定項目があるRedisの走行速度、スロークエリを改善するために、関連の最適化コマンド:
slowlog-log-slower-than
:構成項目のコマンドを超えると言うことであるクエリセットを遅らせるための時間の評価は、動作はそれがマイクロ秒で実行し、スロークエリーログレコードとして遅くなり(一秒マイクロ1,000,000に等しいです)。slowlog-max-len
:スロークエリログ構成へのレコードの最大数。
ログが遅いスロークエリログに格納されている私たちは、実際の交通状況に対応する構成によれば、我々は挿入の逆の順序を使用することができ slowlog get n
、関連するスロークエリログを取得するために、その後、関連するため、対応するサービススロークエリを見つけます最適化。
データを用いて前記パイプライン一括操作
パイプライン(パイプライン技術)は、これにより全体の相互作用の性能を向上させるクライアントによって提供されるバッチ処理技術、一次処理Redisのコマンドの複数です。
次のように私たちは、性能比較のパイプラインと一般的な操作、パイプラインのテストコードをテストするためのJavaコードを使用します。
public class PipelineExample {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
// 记录执行开始时间
long beginTime = System.currentTimeMillis();
// 获取 Pipeline 对象
Pipeline pipe = jedis.pipelined();
// 设置多个 Redis 命令
for (int i = 0; i < 100; i++) {
pipe.set("key" + i, "val" + i);
pipe.del("key"+i);
}
// 执行命令
pipe.sync();
// 记录执行结束时间
long endTime = System.currentTimeMillis();
System.out.println("执行耗时:" + (endTime - beginTime) + "毫秒");
}
}
复制代码
上記の手順の実行結果:
実行時間:297ミリ秒
共通のオペレーションコードは次のとおりです。
public class PipelineExample {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
// 记录执行开始时间
long beginTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
jedis.set("key" + i, "val" + i);
jedis.del("key"+i);
}
// 记录执行结束时间
long endTime = System.currentTimeMillis();
System.out.println("执行耗时:" + (endTime - beginTime) + "毫秒");
}
}
复制代码
上記の手順の実行結果:
時間のかかる:17276ミリ秒
上記の結果から分かるように、通常のコマンドの実行時間は17276秒であるが、パイプラインの実行時間は、従来のパイプライン技術は、58倍高速について行うよりも、297ミリ秒です。
同時に大量のデータを避けるために7.失敗
Redisのキーは、第2走査当たり10回の有効期限が切れます、使用されている期限切れ貪欲戦略を削除するために、この構成はredis.confに構成することができ、デフォルト値はhz 10
、Redisのは、ランダムに20鍵の有効期限が切れ削除、20の値を選択しますキー、下に示すように割合が、プロセスを繰り返すために、期限切れの鍵の25%を超える場合:
一方、同時に大きなキャッシュの有効期限が切れた場合は、サイクルタイムが満了辞書はキーは、これまで比較的まばらな削除される期限切れになるまで削除期限切れの辞書をスキャンし続けるのRedisにつながる、と全体の実行過程で、大規模システムでのRedisなります見かけカトンを読み書きするもう一つの理由は、カトンは頻繁に再利用、メモリページへのメモリマネージャのニーズなので、いくつかのCPUを消費します。
などの商品カトン現象を回避するために、我々は、キャッシュの多くを防ぐために必要があると同時に、一緒に期限切れになる、簡単な解決策は、有効期限に基づいて指定された範囲内の乱数を追加することです。
8.クライアントの最適化
クライアントの使用時には、我々は技術へのパイプライン以外を使用しようとするだけでなく、完全な使用Redisの接続プールを作るのではなく、頻繁に使用すると、ネットワーク伝送を削減し、不要な呼び出し命令の数を減らすことができるようにすることを、破壊Redisの接続を作成するために注意を払う必要があります。
9.メモリサイズ制限のRedis
64ビットオペレーティングシステムRedisのメモリサイズに制限されないで、すなわち構成要素は maxmemory <bytes>
、これが不十分な物理メモリ、スワップ領域の使用スワップ領域、およびシステム心配がRedisの使用されたときのいずれかにつながる、コメントアウトされページングは、スワップ領域に移動するとき、Redisのは、このようにRedisの全体の性能に影響を与え、遅延のRedisその結果、プロセスをブロックします。したがって、我々はRedisのメモリサイズを制限する必要がある値は、メモリのトリガー戦略、が不足してこのRedisのに達したときに、固定値である4.0 Redisの後の8種のうちのメモリ戦略:
- noevictionは:メモリ不足がある場合ではないすべてのデータのうち、新しい操作は、ポリシーの外に、Redisのデフォルトメモリを文句を言うでしょう。
- LRU-AllKeys:最低使用中の全キーのうちの鍵。
- ランダムAllKeys:任意のランダムなキーアウト。
- LRU-揮発性:アウト最低使用中のすべての主要なキーの有効期限の時間設定の。
- ランダム揮発性:キー有効期限の任意のセットのランダムアウト。
- TTL-揮発性は:キーのうち、以前の優先順位を期限切れ。
Redisのでは4.0のリリースは排除戦略の2種類を追加しました:
- LFU-揮発性:すべてのアウト有効期限がキーに設定されている、少なくともで使用されるキー。
- LFU-AllKeys:少なくとも使用中の全キーのキーアウト。
allkeys-XXXは、揮発性-XXXのすべてのキーデータから排除表すキーに期限切れでキーセットからのデータを表します。
私たちは、実際のビジネスケースに応じて設定することができる新しいエラーを追加する場合、デフォルトポリシーは、任意のデータのうち排除するものではありません。
10.仮想マシンの使用ではなく、物理マシン
Redisのは、仮想マシン・サーバーで実行されている、および物理マシンは、物理ネットワークポートを共有し、我々はできる、単一の物理マシンが実行中の複数の仮想マシンを有することができるので、メモリフットプリントとレイテンシのネットワークは非常に悪いパフォーマンスを持つことになりますので、./redis-cli --intrinsic-latency 100
Redisのパフォーマンスがより高い要件がある場合、遅延時間のコマンドを見て、それが直接、可能な限り物理マシン上のようRedisのサーバーを展開する必要があります。
11.データの永続化戦略をチェック
Redisの持続性戦略は、災害復旧やデータ移行することができますが、この永続性を維持するために、あなたはパフォーマンスのオーバーヘッドの多くを必要とするように、ハードディスクにメモリデータをコピーすることです。
Redisの4.0の後、Redisのは3つの永続的な方法があります。
- RDB(Redisのデータベーススナップショット)はバイナリの方法でディスクに書き込まれるメモリデータの特定の瞬間であろう。
- AOF(追加のみファイル、ファイルの追加モード)、すべてのコマンドの記録動作、およびテキスト形式のファイルに追加。
- 、Redisの4.0の後に通常モード、新しいモードを混在混合して、その後の、書き込み時には、データはRDBの形態の第1の現在のファイルの先頭に書き込まれ、永続的で、AOF RDBの利点を組み合わせましたAOFの操作コマンドファイル形式に保存されているので、データ損失のリスクを軽減しながら、再起動のRedisする速度を保証することができます。
AOF RDBと持続性は長所と短所があり、RDBは、一定時間内にデータの損失を引き起こす可能性がありますが、起動スピードAOFファイルによるものが大きいと、それはRedisの影響を与えるだろう、両方の長所RDBとAOFを持つことができるようにするために、4.0 Redisの後に追加します混合永続的な方法は、私たちは、混合永続的な方法を選択する必要があり、操作に永続的でなければなりません。
缶混合かオープン永続チェックconfig get aof-use-rdb-preamble
以下に示すように、コマンドの実行結果:
- コマンドラインを開き
- 設定ファイルを変更することで、オープンのRedis
①コマンドラインを開き、
コマンド使用してconfig set aof-use-rdb-preamble yes
以下のように実行結果を:
Redisの設定ファイルを変更することで開く②
設定ファイルのルートパスにRedisのファイルredis.conf見つかりaof-use-rdb-preamble no
へaof-use-rdb-preamble yes
次の図:
なお、非ビジネスは永続的でなければならないで、あなたが効果的に発生しない断続的なカトンに悩まさRedisの走行速度を向上させることができ持続性をオフにすることができます。
12.無効にTHPのプロパティ
Linuxのカーネル2.6.38カーネル増加透明な巨大ページ(THP)の大きなメモリページ2メガバイトの割り当てをサポートするために備えて、デフォルトで有効になって。
あなたはTHPをオンにすると、フォークの速度は、親プロセスのメモリ消費量の書き換え時に大幅に増加し、2メガバイトに元から各4KBのメモリページのフォーク後に遅くなります。各書き込みコマンドが512倍に拡大し、書き込み動作が遅いクエリの多数で、その結果、書き込み動作の実行時間が遅くなり起因しながらページメモリユニットをコピーします。このようなINCRシンプルなコマンドとしてのRedisは、したがって、次のように無効になって、この特徴無効にすることをお勧めします、スロークエリに表示されます。
決して> / SYS /カーネル/ MM / transparent_hugepage有効/エコー
THPの設定は有効なままにした後、マシンを再起動するには、/etc/rc.localのを追加することができますecho never > /sys/kernel/mm/transparent_hugepage/enabled
。
13.読み出し及び書き込みの速度を上げるために分散アーキテクチャの使用
Redisの分散アーキテクチャには、3つの重要なツールがあります。
- マスター・スレーブ同期
- センチネルモード
- Redisのクラスタのクラスタ
私たちは、それはRedisの全体の速度を向上するように、メインのライブラリに単位時間当たりのより多くの要求を処理できるような機能は、サービスから読み取るために、マスタースレーブ同期機能を実行に書き込むことができます。
以下からのアップグレード機能のためのメインモードの後にセンチネルが、人間の介入なしにベンの崩壊ノードマスターは、自動的にRedisの通常の使用を再開する時期。
RedisのクラスタRedisの3.0正式、起動さRedisのデータベースクラスタは、圧力バランス複数のノードの各ノードをロードするためにストアによって分散されます。
Redisのクラスタ仮想パーティションハッシュスロット、キーの全ては、0から16383までのスロットハッシュ関数の整数にマップされている計算式:スロット= CRC16(キー)&16383、各ノードは、キー溝の部分を維持する責任があり、溝がマッピングされています値のデータ。Redisのあなたは、読み取りおよび書き込み複数のサーバーに分散し、単一のサーバーからの圧力に、そのパフォーマンスが大幅に改善されることができるように。
これらの三つの機能では、我々は唯一のライン上を必要とし、間違いなくRedisのクラスタは、実装を優先しなければならない、それは読み取りと書き込みの圧力自動共有を複数のサーバーに、そして自動的に災害復旧する能力を持っていることができます。
2次元コードの下ウォッチ、よりエキサイティングなコンテンツ購読。