株式パフォーマンスの問題をRedisの

システム内の一部のネットワークサービスでは、Redisの性能は、MySQLデータベースや他のハードの問題のパフォーマンスよりも重要であろう。マイクロボー、ホットマイクロブログ[1]は、ユーザとの間の最近の関係はRedisの中に保存されているような、クエリの大多数ではなく、外出先のMySQLよりも、Redisのを打ちます。

だから、Redisのサービスのために、私たちはそれのパフォーマンスを最適化するために行うことができますか?または、どのようなパフォーマンスの廃棄物は、それを避ける必要がありますか?

Redisのパフォーマンスの基礎

最適化を議論する前に、私たちが知っている必要があり、Redisのサービス自体は、シングルスレッドの実行など、いくつかの機能を持っています。そうでない場合は、これらの特性は、我々はパフォーマンスの最適化の基本を考えることをしない限り、Redisのは、ソースコードを変更します。

だから、何が我々はそれを考慮する必要がある基本的な特性をRedisの?Redisのプロジェクトのプレゼンテーションは、その機能の概要を示します。

Redisのは、インメモリデータベースであるディスク上持続すること。データモデルは、キーと値ですが、値の多くの異なる種類がサポートされています。

1.Redisは、オペレーティングシステムによって提供されるデータを格納するために仮想メモリを使用します。また、オペレーティングシステムは、一般的にUnixのことをいいます。Windowsは、Redisの上で実行されますが、特別な処理を必要とすることができます。お使いのオペレーティングシステムのスワップ領域場合、Redisのデータは、実際にハードディスク上に保存することができます。

2.Redisサポートの永続性は、データをハードディスク上に保存することができます。

3.Redisキー値を読み書きする方法であって、ターン内の値は、トランザクションの多くの異なる種類であってもよい。さらに、異なる基礎構造が格納されているデータのタイプ。異なるデータ・ストレージ構造のCRUDの複雑さとパフォーマンスのオーバーヘッドを決定します。

ほとんどの時間、単一スレッド4.Redis [2](シングルスレッド)、即ち同じ時間だけCPUを占有している、唯一の操作指示、同時読み出しが存在しません。

最後に、この機能を、(アムダールの法則によると、時間のかかるプロセスの大部分を最適化し、それがより理にかなっている)のRedisはシングルスレッドであるが、それは良好な性能を持つことができる理由は、二つの言葉に要約される複数のRedisの使用を従ってRedisの単純命令実行(ほとんどの命令)が1マイクロ秒未満である、[4]、1秒のシングルコアCPUができ、I /機構[3]多重O、クライアント要求はメインスレッドをブロックしません(おおよそ数百要求その数千のに対応する)命令処理100万は、マルチスレッド必要がありません(ネットワークがボトルネックになっている[5])。

最適化ネットワーク遅延

Redisのの公式ブログには、パフォーマンスのボトルネックは、より可能性の高いいくつかの場所でネットワーク[6]されることになるので、どのように我々はネットワーク上の待ち時間が行う最適化するか、言いましたか?

まず、あなたは、スタンドアロンの展開(同じマシン上とRedisのアプリケーションサービス)を使用する場合、

1. Unixのプロセス間通信を高速化localhostのローカル・エリア・ネットワーク(学名ループバック)よりも、Redisのサービスを要求します。公式文書[7]それについて考える、そう言うが、理論的には、それはこのようにする必要があります。

しかし、同社の事業規模の多くは、スタンドアロン展開をサポートすることができないが、彼らはまだTCPを使用する必要があります。

Redisのサーバーとクライアントの通信は、一般的にTCP長いリンクを使用しています。クライアントは、再送信Redisの次の命令を待つために、結果のニーズを返すように要求を送信し、複数のクライアントは、以下の関係にRedisのを要求した場合:

uploading.4e448015.gifダンプは失敗した再アップロードをキャンセル

(注:あなたが送信する場合は、キーは特に長い、RedisのコマンドをTCPパケットを置くことが完全にはできない、これだけプッシュパッケージを描きました)

これら2つの要求ので、クライアントは、ネットワークの伝送時間の期間を通過する必要があります。

ただし、可能な場合、そのようなGETキーとして、要求クラスをマージするマルチキーコマンドを使用することができるは、二つのMGET KEY1 KEY2と組み合わせることができます。実際の通信は、だけでなく、要求の数を減らすので、遅延が自然に良くなります。

あなたは、このようなSETなどのマルチキーコマンドと合併することができない場合は、合併をしませGET。方法は?

Redisの少なくとも二つのそのような方法は、要求コマンドを複数に組み込むことができ、一方はMULTI / EXECは、スクリプトです。前者の方法は、もともとRedisのトランザクションを構築し、それは要求として複数の命令をマージすることができ、それは通信プロセスに従います。スクリプトについては、スクリプトを起動する最良の使用キャッシュスクリプトSHA1ハッシュキーなので、トラフィックが小さくなります。

uploading.4e448015.gifダンプは失敗した再アップロードをキャンセル

だから、ネットワーク伝送時間を短縮するために複数の操作を行い、そうではありませんか?しかし、あなたが適切なようなので、検討して、同じノードに関わるこのキートランザクション/スクリプトを尋ねなければならないからです。

我々は、複数の要求をマージする方法はありません、上記の方法と考えている場合は、我々はまた、複数の応答をマージ検討することができます。例えば、二つのマージの返信:

uploading.4e448015.gifダンプは失敗した再アップロードをキャンセル

したがって、理論的には、プライマリーからの応答のためのネットワーク伝送時間を省略すること。これは、実行するパイプラインです。クライアントの場合はパイプラインのルビーの例を使用します。

「Redisの」必要

@redis = Redis.new()

@ redis.pipelined DO

@ redis.get 'キー1'

redis.set @ 'KEY2' 'いくつかの価値'

終わり

#=> [1、2]

パイプラインの使用上の顧客の言語、さらには黙認のいくつかは、このようなnode_redisなど、待ち時間の問題を、最適化すると言われています。

また、より多くの任意の応答情報は、TCPパケットに入れることができるよりも、あまりにも多くの要求ならば、まだ、TCPまだ副変速機が、パイプラインの使用、(たとえば、長い文字列を取得する)データが非常に長い返信送信の数を減らします。

パイプラインと上記他の方法が同じではない、それはアトミックではありません。クラスタの状態のクラスタ上ので、それ以上の可能な原子よりもパイプラインを実現しています。

概要:

  1. スタンドアロン展開場合は、UNIXを使用して、プロセス間通信
  2. 可能な場合、リクエストの数を減らすためにマルチキーコマンドは、複数の命令の併用、
  3. 使用トランザクション、スクリプトマージ要求と応答
  4. パイプライン応答の併用

長時間操作の実行を警戒

大量のデータの場合には、いくつかの操作の実行時間が比較的長くてもよく、そのようなキーはLRANGEのマイリスト0 -1 *、および他のアルゴリズムの複雑さはO(N)命令です。Redisのデータのクエリを行うための一つのスレッドだけなので、これらのディレクティブは長い時間がかかる場合は、Redisのは、遅延の多くを引き起こして、ブロックされます。

しかし、数十ミリ秒の公式文書は、KEYSは、(通常のラップトップ上で)、非常に迅速にクエリ*言うものの、わずか40ミリ秒を100万個のキーをスキャンする(//redis.io/commands/keysを::httpsを参照)システムの高いパフォーマンス要件のために、それはないキーの数百万がある場合はもちろんのこと、短いではありません(完全なマシンは、100バイトのキーとして数百万、数百の存在する可能性がある、唯一のキー10ギガバイト100,000,000)そして長いです。

だから、本番環境で命令のコードの遅い実装を使用しないようにしよう、ブログ[8]でこのRedisのの著者も述べています。また、運用・保守のクエリRedisの学生は、また、使用しないようにしてください。でも、Redisのに欠かせないが、この時間のかかる命令の使用を禁止するために、本書の使用のリネーム・コマンドキー「」をお勧めします。

複数のコマンドはRedisのを有する原子のプロセスを実行するために組み合わせることができるので、これらの命令の時間がかかることに加えて、Redisのトランザクションで、スクリプト、それはまた、留意すべきで、長い時間がかかる場合があります。

あなたが「遅い命令」生産環境を知りたい場合は、最新のカウントの実行時間を表示するSLOWLOGのGET数を使用することができ、非常に長い命令です。長いカウント長としてslowlog-ログ遅いよりredis.confに設定することによって定義することができます。

また、可能なスロー指示していない多くの場所は、DELを言及しているが、コメントredis.confファイル[9]は言うin'd。UNLINK:長い物語の短いDELは、対応するメモリ回復は長い時間(あるいは秒)を取ることがラージオブジェクトである、DELの非同期バージョンを使用することをお勧めします。後者は元のスレッドをブロックすることなく、目的のキーを削除するために、新しいスレッドを開始します。

さらに、キーの有効期限が切れたとき、Redisのは、一般的には、同期、削除する必要があります。一つの方法は>毎秒10回は一回のキーの有効期限を設定して、これらのキーは、グローバル構造体に格納されているチェックし、あなたがserver.db-を使用することができ、削除キーにある訪問を満了します。方法ですチェック:

  1. 20個のキーからランダム撮影
  2. 削除された有効期限が切れています。
  3. わずか20キー、(5個以下である、)25%以上の有効期限が切れている場合は、Redisのは、かなり多くの古い鍵を考えると、終了条件が満たされるまで、繰り返し手順1に進みます。特定のキーを削除します鍵の過去にはあまりありません。

あなたが本当に同時に有効期限が切れたキーの多くを持っている場合、ここでのパフォーマンス上の影響は、ある、それは本当にRedisの削除を循環されている、メインスレッドを占めていました。

キーが遅れる現象です生成することが容易であるため、この点では、提案のRedisの著者[10]は、このディレクティブ警戒EXPIREATです。私はまた、勧告のいくつかはランダムな変動量の有効期限キーを設定することで見てきました。最後に、この方法与えられたredis.confは、削除操作は、すなわち、提供redis.confにはいlazyfree-レイジー期限が切れる、期限切れのキーは非同期になります。

正しいアルゴリズムを使用して最適化されたデータ構造、

CRUDのための(例えば、文字列、リストのような)データ型は、その効率は、基礎となるストレージ構造によって決定されます。

我々はデータ型を使用する場合、それは方法の複雑さのあまりを使用して、それを基礎となるストレージ構造とアルゴリズム、回避を見て適切なものとすることができます。ここでは2つの例を示します。

  1. ZADD時間複雑さは、操作の新たな要素がデータ増加の他のタイプよりも複雑であるので、慎重に使用すべきであるO(ログ(N))です。
  2. 必要なときに型のフィールドの限られた数の場合、ハッシュ値は、それはおそらく、この構造を採用するziplistストレージ、およびクエリの効率ziplistはRedisののストレージ構造を調整し、フィールドハッシュテーブル高効率の同じ数を持っていない可能性がありますされています。

時間のパフォーマンスを考慮することに加えて、時には私たちは、ストレージスペースを節約する必要があります。Ziplist例えば、構造ハッシュテーブルよりも、記憶空間を節約する(Redisのエッセンシャル500はハッシュテーブルとハッシュziplist構造のフィールドに挿入され、そして各フィールドの値は15ビットのビット列についてである上記構成のように、結果空間構造は、4回にはハッシュテーブルをziplist使用されています。)。しかし、データ・スペースを節約する、アルゴリズムの複雑さは高いかもしれません。だから、ここでは具体的な問題に直面してトレードオフを行う必要があります。朱の僕のブログ、RE::社会的関心の番号へようこそ1024、Redisのは、排他的な情報を受け取ることができます。

どのようにより良いトレードオフを作るには?私はRedisのは、心の自身の平和を作ることです深いストレージ構造を掘ることがあると思います。このフィールドの内容、我々は話を次回。

これらの3点が配慮上のレベルにプログラムされている、ああ手続きを書かれたことに留意すべきです。これらの点の下には、それはまた、Redisの性能に影響を与えるだろう、それだけではないコード・レベルを調整することで、それらを解決するために、だけでなく、構造や運転・保守を考慮する必要があります。

考えてみましょうか、オペレーティング・システムおよびハードウェアのパフォーマンスへの影響

Redisのは、オペレーティングシステムとハードウェアが明らかにまた、Redisの性能に影響を与える外部環境を、実行しています。公式文書では、それはいくつかの例を示します:

  1. CPU:CPU AMD Opteronプロセッサシリーズよりもインテルは、より良いです
  2. 仮想化:低速なソフトウェア命令を監視フォークにつながる優れた仮想マシンよりも、主に仮想マシンではなく、ローカルのハード・ディスク・ドライブの一部の物理マシンは、特にXenの仮想化DOを使用した場合、(フォークをする際の永続使用されます) 。
  3. メモリ管理は:Linuxオペレーティングシステムでは、変換索引バッファを可能にするために、すなわちTLB、より多くのメモリ空間を管理する機能(TLBキャッシュページののみ有限数)、オペレーティングシステム、いくつかのメモリページは、2メガバイトまたは1ギガバイトとして、大きくなり、代わりに、通常の4096バイトで、これらの大容量メモリページは、膨大なページと呼ばれます。同時に、これらの大容量メモリページを使用するプログラマを容易にするために、オペレーティングシステムは彼らのために大きなメモリページを可能にするメカニズムが透明である透明の巨大なページ(THP)に実装されている、あなたは、通常のメモリ・ページを使用してのように、彼らとして使用することができます。しかし、このメカニズムは、おそらくTHPの、データベースに必要とされていないMongoDBのドキュメント[11]は、明示的に述べたように、データベースに必要なメモリ空間がまばらである、そうしてください、コンパクトかつ連続したメモリスペースバーになりますTHP機能を禁止。Redisのも例外ではありませんが、公式ブログのRedisに与えられた理由は次のとおりです。bgsaveます大きなメモリページを使用するときに、スローダウンをフォーク、フォークした後、これらのメモリページは、元の過程で変更されている場合、彼らはコピーする必要があります(すなわち、コピーオンライト)、このコピーは(、すべての後、彼らは巨大なページである大規模なコストの消費のコピーを)大量のメモリを消費します。だから、オフ禁止透明の巨大なページは、オペレーティング・システムに備わって下さい。
  4. スワップ領域:いくつかのメモリページは、スワップファイル空間であるが、これらの要求はRedisのデータストアに持っている場合は、オペレーティングシステムがメモリにスワップ領域から、その後、目的のページをRedisのプロセスをブロックし、かつます。これは全体のプロセスを遮断する必要、それは遅延の問題を引き起こす可能性があり、解決策は、(メモリ空間が不足している場合、他の治療法を使用してくださいことが示唆された場合はRedisのエッセンシャル)スワップ領域の使用を禁止することです。

永続によって引き起こされるオーバーヘッドを考えてみましょう

あるRedisのは永続的で重要な機能は、ハードディスクにデータをコピーします。持続性に基づいて、唯一のRedisのデータリカバリ機能。

しかし、この永続的な機能を維持するためにも、パフォーマンスのオーバーヘッドです。

すべてのことを第一に、持続性のRDB全額。

この方法では、永続データのRedisのRDBの総量は、ハードディスク上のファイルにパッケージ化されています。しかし、子プロセスアウト元のプロセスフォークの実装プロセスのRDBの永続性、forkシステムコールを行うには6年前に実験的Redisのラボに基づいて、時間がかかりながら、[12]、新しいAWS EC2のm1.smallで^ 13で、700の+ MSを必要とする、1ギガバイトのメモリフットプリントRedisのプロセスをフォークが、この時間は、Redisの要求を処理することができません。

マシンはその時よりも良くなりますが、フォークもそれのコストを考慮する必要がありますが。これを行うには、あまりにも頻繁ではない、合理的なRDB永続的な間隔を使用しています。

AOF増分持続性:次に、我々は別の永続的な方法を見てください。

このRedisのサーバーへの持続的な方法は、あなたに、プロセスを(フォーマットはRedisのプロトコルに従う)、システムは、2つのコールを呼び出します、1が書き込みである(2)の下のテキストの形式で格納された命令を送信する、同期が完了すると、1がありますFSYNC(2)、非同期完了。

これら2つの問題が遅延の原因である可能性が高いです。

  1. 出力バッファがいっぱいである、またはカーネルがハードディスクに同期され、バッファのデータは、それがブロックされたであるため、書き込みであってもよいです。
  2. FSYNCの役割は約20ミリ秒、または大きな消費の遅れもあり7200 / minのハードディスクに、書き込みに書き込まれたデータは、ハードディスク上のファイルAOF落ちたことを確認することです。FSYNCが行われたときにさらに重要なのは、書き込みがブロックされることがあります。

これは、書き込みは一見内のファイルへの書き込みデータには良い方法がないためにのみ、受け入れ可能なブロッキング。しかし、fsyncをするために、Redisのは、あなたが適時やパフォーマンスの選択のバランスをとるバックアップの種類に応じて、3つの構成を可能にします:

  1. 常に:ときappendfsyncセット常に、fsyncを実行し、クライアントの指示なので、最も可能性の高い原因遅延の問題が、最高のバックアップ適時性を同期します。
  2. everysec:第二の非同期実行のfsyncごとに一度、この時間はRedisのパフォーマンスは良くなりますが、それでもfsyncを妥協の選択とみなすことが、書き込みをブロックすることがあります。
  3. いいえ:Redisのは、カーネルのfsyncで決定、(常にfsyncをせずに、それはそうではありません)fsyncを開始するためのイニシアチブを取ることはありません

別々の読み取りおよび書き込みデータ分割 - 分散アーキテクチャを使用して

上記の、我々は、単一の、または単一のRedisサービスの最適化に基づいています。今、私たちは、サイトのサイズが大きくなる、セキュリティ問題Redisの性能への分散アーキテクチャを使用することを考えると。

まずその、下の状況は(またはそれ以上)分散アーキテクチャを使用して持っているもの:

  1. 大量のデータは、単一のサーバーは、メモリの下にインストールようにすることができない1 Tの順序
  2. 高可用性サービスを必要とします
  3. 単一過大な圧力をリクエスト

これらのデータは、問題を解決するために使用することができ、または断片をマスターから分離され、またはその両方が使用される(すなわち、クラスタノード上のフラグメントは、マスタ構造物から提供される使用します)。

このようなフレームワークは、性能向上のための新しいエントリポイントを追加することができます。

  1. 特定のライブラリーから送られた遅い実行指示
  2. ライブラリ上から、使用少し上の永続化機能
  3. いくつかの大きなフラグメントのリスト

そのうち最初の二つは、シングルスレッドのRedisので、他のプロセスと相補的なアプローチの性能(偶数機)の特性に基づいています。

もちろん、分散型アーキテクチャを使用して、連続的に分布するように、要求ニーズが転送されるような、コピーされたデータの必要性能に影響を与えることができます。(原因不明の)

言葉の後

実際には、多くのものがあるも、(パフォーマンスを向上させることができ、少しそれをオフにし、メインテーブルの再ハッシュキー毎秒10回)など、アクティブ蒸し返しとして、パフォーマンスのRedisに影響を与えるが、このブログは非常に長く書かれています。しかし、Redisのマスターの基本原則、新興やってのけるために現状のやり方を維持するための質問;また、問題が他の人によって提案されており、コレクション、およびメモリ・ソリューションよりも重要です。

出典:ZHUシーブシャオオフ

公開された277元の記事 ウォン称賛65 ビュー380 000 +

おすすめ

転載: blog.csdn.net/ailiandeziwei/article/details/104776084