Redisのパフォーマンスについての考え
単純なキャッシングから数テラバイトサイズのセットアップまで、さまざまなユースケースでRedisを使用している多くの人々や企業と話す特権が与えられているので、私が他の何よりも取り上げるよう求められているトピックの1つはパフォーマンスです。 Redisは、パフォーマンスへのアプローチ方法が異なります。ほとんどではないにしても、多くのデータベースサーバーでパフォーマンスを向上させようとしています。 Redisの目標は、速度を落とさないことです。これは非常に異なるアプローチであり、それを利用するには異なる考え方が必要です。
パフォーマンスメトリクス–レイテンシーは王様ですか?
Redisを使用するときに主に関係するパフォーマンスメトリックは、基本的に2つあります。1秒あたりに実行できるコマンド(またはトランザクション)の数と、実行にかかる時間です。それを分解すると、前者は後者からの二次的な結果であることがわかります。 Redisはシングルスレッドであるため、プッシュできるops /秒の数は、それらにかかる時間に完全に関係しています。したがって、最終的に重要なのは、私が「コマンドレイテンシ」と呼んでいるものです。
Redisの利点の1つは、シンプルさだと思います。クエリではなく、コマンドを発行します。コマンドはデータをプルするためのはるかに単純なルートであり、この場合、単純さはコマンドの速度に反映されます。また、開発者は、さまざまなクエリを最適化しようとするのではなく、最適化されたコマンドを提供できます。このエレガントなシンプルさは、Redisを使用するプログラマーに提供されます。これは多くの場合、サーバーソフトウェアに実行させるのではなく、クライアント側でセットのフィルタリングなどの「クエリ」タイプの操作を実行することを意味します。
このタイプのクエリはサーバー上で一貫した方法で実行するのが最適だと感じる人もいますが、現在、これはもはや優先ルートではないと考えています。その理由は、バグベアを「スケーラビリティ」と呼んでいるためです。たとえば、「水平方向にスケーラブルな」Webサービスまたはサイトの実行を開始すると、このパターンが正常に機能することに早い段階で気付くことがよくあります。ただし、「わいせつな」レベルのトラフィックの処理を開始すると、データベースが重大なボトルネックであることがすぐにわかります。その後まもなく、このデータベース(通常はMySQLなどのSQLストア)が「水平方向にスケーラブル」ではないことを学びます。単純に追加することはできません。
コマンドレイテンシ
もちろん、どちらもRedisではありません。ただし、ここでの違いは、フィルタリングロジック、並べ替えなど、単一のRedisコマンドまたは多くても数個のコマンドで実行できないものを保持することで、DBにロジックをロードしないため、「処理するもの」がなくなることです。 。 Redisは、従来の「データベースサーバー」ではなく、「データストア」として使用する必要があります。これは、「Redisの速度を落とさないでください」の最初の側面です。 Luaスクリプトのパスを開始すると、パフォーマンスが大幅に低下するリスクがあることを述べる必要はありません。トラフィックが低から中程度の場合、開発中に表示されない場合があります。ただし、大規模にヒットすると、それが表示されます。そしてその時までに、ロジックはすでに組み込まれていることが多すぎて、アプリケーションコードに移行するには技術的負債が大量になります。技術的負債の清算にどれだけの優先順位が与えられるかは誰もが知っています。
これは、Luaスクリプトに場所がないということではありません。それは単にそれが高度に精査されるべきであることを意味します。 Luaスクリプトが正味のパフォーマンスの低下であるかどうかに関係なく、そのロジックをクライアント側で処理した場合に実行する必要のある追加のラウンドトリップのコストを比較することをお勧めします。ただし、クライアントコードがそれを実行できる時間ではありません。このように考えてみてください。往復のコストを2ミリ秒削減しても、スクリプトの実行時間に3ミリ秒を追加すると、間違った方向に進みました。
ここでは、シングルスレッドサーバーの性質を鋭敏に認識する必要があります。その3msスクリプトは、実行中に数百(または数千)のコマンドをブロックする可能性があります。それらを(プル)->(ロジック)->(プル)シーケンスに分割すると、サーバーは「(ロジック)」フェーズ中に追加の要求を処理できます。クライアントコードにロジックを保持することで、マルチクライアントベースのシステムに固有の同時実行性を維持できます。トランザクションまたはLuaスクリプトが必要な場合は、もちろんそれらを使用してください。ただし、コードが「簡単」になるように見えるため、使用しないでください。同時実行パフォーマンスのヒットを常に認識し、それを測定し、意識的に選択します。
これにより、「Redisを遅くしない」という2番目のルールが導き出されます。スクリプトを介してサーバーロジックを回避することで同時実行性を維持します。副次的な利点は、複数のキーで動作するLuaスクリプトを書き直したりダンプしたりせずに、Redisクラスターセットアップに移行できることです。
Redisを遅くする他の方法
Redisサーバーの実行には、システムレベルまたは運用上の側面がいくつかあり、Redisの速度が低下する可能性があります。 I / Oリソース制限を使用する他のサーバーと同様に、Redisの速度が低下する可能性があります。たとえば、8GBのネットワーク帯域幅が必要であるが1GBがある場合、それは「遅い」でしょう。デーモンプロセスが必要な数よりも少ないオープンソケットに制限されている場合、コマンドを実行する代わりに、接続が閉じられるのを待つために時間が費やされます。
おそらく、Redisの速度を低下させる最も一般的な2つの操作上の選択肢は、1)仮想マシンに配置することです。特にXenハイパーバイザーベースの1つと、2)ヘビーディスクの永続性です。
最初のものは、標準のRedisの文献でかなりよく取り上げられています。XenハイパーバイザーVMに配置しないでください。 2つ目は永続性のようですが、私の見積もりでは十分ではありません。
もちろん、標準的な推奨事項があります。ローカルの高速ディスクを使用し、永続化するときにCoWダンスを処理するのに十分なメモリがあることを確認します。スレーブでのみ永続化を実行する場合でも同様です。これらは確かに、コマンドのレイテンシーに波及する影響を与える可能性があります。不足しているのは、それらが正しいかどうかを適切に判断する方法です。
これをテストする標準的な方法の1つは、組み込みのレイテンシテストを使用することです。その方法の技術的な詳細に入る前に、より大きな「方法」の質問に対処したいと思います。ここでの主なサブセットは、これらのテストをいつ実行するかです。まず、データセットが小さい場合、このテストは無意味になる可能性があります。どれくらい小さいですか?データをディスクにダンプするのにかかる時間を決定します。 1、2秒、場合によっては10秒の話をしていると、意味のあるデータが得られる可能性が低くなります。もちろん、これはすべて、SAVEではなくBGSAVEを実行することを前提としています。
永続性レイテンシ
これは、私が「永続性レイテンシー」と呼んでいるものの最初の原則につながります。つまり、コマンドがサーバーにヒットしてから、結果が何らかの形式の永続性にヒットするまでの時間です。永続性オプションを導入する最小のレイテンシーを見つけます。ネットワークとディスクに応じて、AoFまたはスレーブサーバーのいずれかが最も待ち時間の短いバンピング永続性オプションになり、RDBが最後になります。
RDBは、主にT秒間にN回の変更の遅延が組み込まれているために最後になります。したがって、その最小期間(最小のデフォルトウィンドウは60秒)に十分な変更があると仮定すると、永続性遅延は間隔T+RDBをディスクに書き込む時間です。デフォルトの60秒間隔でそのメモリをディスクにダンプするのに30秒かかる場合、「永続性レイテンシ」は(60 + 30)90秒になります。
ただし、これは、この永続性の待ち時間が問題であるかどうかという問題を提起します。この質問には2つの側面があります。1)ビジネス要件に対して十分ですか。および2)Redisの速度が低下しますか?
最初の質問は、私がすべての人に答える一般的な答えを提供できないというものです。ただし、永続性レイテンシの要件が上記の式よりも厳しい場合は、RDBではなく「スレーブやAoFを使用する」という答えが得られる可能性が高いと言えます。これは、Redisを実行しているプラットフォームで明らかな間違いを犯していないことを前提としています。これが2番目の側面につながります:Redisの速度が低下しますか?
「RDBファイルを保存するのにどれくらいの時間がかかるか」という質問が頭に浮かぶ人もいます。私の見解では、これは間違いです。どれくらい時間がかかるかは重要ですか?この質問に対する答えは、「保存によってRedisの速度が低下するか」です。そうでない場合は、1秒かかるか1時間かかるかは気にしないでください。たとえば、RDBを保存するのに1000秒かかるサーバーAについて考えてみます。固有のコマンド遅延範囲を保存しない場合は、30〜100マイクロ秒です。保存中、この遅延は30〜100マイクロ秒の範囲です。この場合、Redisのパフォーマンスが低いという考えの下で、このRDBの節約時間を短縮することに取り組むのは時期尚早の最適化です。
ただし、サーバーBの所要時間はわずか10秒ですが、コマンドの待機時間は30-100usから130-250usに跳ね上がります。これで、保存によってRedisの速度が低下し、それを最小限に抑えたいため、RDBファイルの生成にかかる時間を考慮する必要があります。それがより高速なディスクを意味する場合、少なくとも今はそれらを正当化する理由があります–約100〜150マイクロ秒の増加がアプリケーションのパフォーマンスの不安を引き起こすと仮定します。そうでない場合は、時期尚早の最適化に戻ります。
さて、そのレイテンシーを測定する方法については、この投稿のパート2で詳しく説明します。これは、すでにかなり長くなっているためです。
-
Redisでのハッシュの使用
Redisのハッシュは、フィールドと値の両方が文字列である単一のキーの下に、関連付けられたフィールドと値のペアを格納する方法です。 Redisでは、データ構造全体と、構造内の各フィールドの両方を変更できます。これにより、アプリケーション内のオブジェクトの優れた(そして非常に高速な)バッキングストアになります。 CLIの例 2つのフィールドでハッシュを作成します: 127.0.0.1:6379> HMSET my_hash key1 foo key2 bar OK ハッシュに関連付けられているフィールドと値を一覧表示します: 127.0.0.1:6379> HGETALL my_
-
Redisの10の簡単なヒント
Redisは現在、技術コミュニティで注目を集めています。 Antirezの小さな個人的なプロジェクトから、メモリ内データストレージの業界標準になるまでには長い道のりがあります。これに伴い、Redisを適切に使用するためにほとんどの人が同意できる一連のベストプラクティスが提供されます。以下では、Redisを正しく使用するための10の簡単なヒントを紹介します。 1。キーの使用をやめる* さて、多分あなたに向かって叫ぶことはこの記事を始めるための素晴らしい方法ではありません。しかし、それはおそらく最も重要なポイントです。あまりにも頻繁に、redisインスタンスを見て、簡単なcommandstats