web-dev-qa-db-ja.com

Memcachedが遅い:平均10ms memcached `get`

Newrelicを使用して、Python/Djangoアプリケーションのパフォーマンスを測定しています。 Newrelicは、システム全体で「Memcached」がコマンドに応答するために平均して12msを使用していると報告しています。

上位のダース程度のWebビュー(リクエスト数)までドリルダウンすると、一部のMemcache getが最大で30msを占めることがわかります。 Memcache get未満で返る10msの単一の使用法を見つけることができません。

システムアーキテクチャの詳細:

  • 現在、4つのアプリケーションサーバーがあり、それぞれにmemcachedメンバーがあります。 4つのmemcachedメンバーすべてがmemcacheクラスターに参加します。
  • 私たちはクラウドホスティングプロバイダーで実行しており、すべてのトラフィックは(「内部」IP経由で)「内部」ネットワークを介して実行されています
  • アプリケーションサーバー間でpingを実行すると、応答は~0.5msにあります

Memcachedの10ms aslow応答時間ではありませんか?

「Memcacheが遅すぎる」と思うかどうか私が理解している限り、「間違っている」。それで私はそれを間違っていますか?

これはmemcache-topコマンドの出力です]

memcache-top v0.7   (default port: 11211, color: on, refresh: 3 seconds)

INSTANCE        USAGE   HIT %   CONN    TIME    EVICT/s GETS/s  SETS/s  READ/s  WRITE/s 
cache1:11211    37.1%   62.7%   10      5.3ms   0.0     73      9       3958    84.6K   
cache2:11211    42.4%   60.8%   11      4.4ms   0.0     46      12      3848    62.2K   
cache3:11211    37.5%   66.5%   12      4.2ms   0.0     75      17      6056    170.4K  

AVERAGE:        39.0%   63.3%   11      4.6ms   0.0     64      13      4620    105.7K  

TOTAL:      0.1GB/  0.4GB       33      13.9ms  0.0     193     38      13.5K   317.2K  
(ctrl-c to quit.)

** 1台のマシンでのtopコマンドの出力は次のとおりです。

top - 21:48:56 up 1 day,  4:56,  1 user,  load average: 0.01, 0.06, 0.05
Tasks:  70 total,   1 running,  69 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.3%st
Mem:    501392k total,   424940k used,    76452k free,    66416k buffers
Swap:   499996k total,    13064k used,   486932k free,   181168k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                               
 6519 nobody    20   0  384m  74m  880 S  1.0 15.3  18:22.97 memcached                                                                                              
    3 root      20   0     0    0    0 S  0.3  0.0   0:38.03 ksoftirqd/0                                                                                            
    1 root      20   0 24332 1552  776 S  0.0  0.3   0:00.56 init                                                                                                   
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd                                                                                               
    4 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kworker/0:0                                                                                            
    5 root      20   0     0    0    0 S  0.0  0.0   0:00.02 kworker/u:0                                                                                            
    6 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0                                                                                            
    7 root      RT   0     0    0    0 S  0.0  0.0   0:00.62 watchdog/0                                                                                             
    8 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 cpuset                                                                                                 
    9 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 khelper                                                                                                
...output truncated...
6
Chris W.

書き込みは高速で、単一の読み取りは非常に遅いですが、バッファリングされた読み取りは非常に高速であることがわかりました。取得するキーの配列を渡して、get_manyでバッファ付き読み取りを行う必要があります。これが私のテストです:

  1. 0.42605304718秒、1秒あたり234712で100000書き込み(1つずつ書き込まれますが、バックグラウンドでバッファリングされる可能性があります)

  2. バケットサイズ= 10000で100000を読み取り、0.651949167252秒、153386 /秒で読み取り(多く)

  3. 86.2907109261秒で1度に1つずつ読み取り、1秒あたり1158

私の場合、pymemcacheでpythonを使用しています。

3
rideswitch

これまでのところ、私の調査では10msは「遅い」と示されています。これは、memcacheドキュメント自体がsub -1ms回を「予期された」ものとして参照していることを意味します。したがって、私たちが見ている応答時間は桁違いに遅いです。

パフォーマンスに期待すること: https://code.google.com/p/memcached/wiki/NewPerformance

遅いmemcached応答の「可能性のある原因」は(可能性の大まかな順序)のようです。

  1. 不十分なアプリケーション設計(またはバグ)
  2. ネットワークの混雑
  3. swapping
  4. コテナントアプリケーションによる高CPU負荷
  5. なんらかの接続最大値に達しています
  6. ステートフルファイアウォール
  7. 悪いTCP構成

私はこれらのほとんどすべてを以下のように扱いました:

  1. memcached-tophttps://code.google.com/p/memcache-top/ )によると、アプリケーションからの接続時間はbrutishttps://code.google.com/p/brutis/ )同じアプリサーバーから。
  2. システムのピーク負荷時間が明確であっても、応答時間は1日を通して一定です。これが輻輳問題である場合に予想されるように、応答時間は決して「スパイキー」ではありません。 (また、ホスティングプロバイダーは、これらのインスタンスに、使用しているatopレポートよりもはるかに多くのMbpsを提供すると主張しています)
  3. システムに十分な空きメモリ(およびiowaitなし)があることが確認されました
  4. キャッシュ全体のCPU使用率が低い
  5. サーバーあたり10〜20の同時接続のみを処理
  6. (iptablesを介して)ステートフルファイアウォールを使用していましたが、すべてのステートフルエントリを削除しても、パフォーマンスに変化はありませんでした。
  7. これらの構成オプションを盲目的に設定し、それらが物事を改善することを望みました:

    /sbin/sysctl -w net.ipv4.tcp_tw_recycle=1
    /sbin/sysctl -w net.ipv4.tcp_tw_reuse=1 
    /sbin/sysctl -w net.ipv4.tcp_fin_timeout=10 
    

結果は変化しません。


この問題の診断は基本的に途方に暮れています。 「Redisのインストール」のポイントに近づいており、うまく機能することを願っています。

1
Chris W.

最初に頭に浮かぶのは、FQDN/DNSを使用してmemcacheサーバーへの接続を開始するか、IPアドレスまたはローカルソケットを使用するかです。

ホスト名を使用している場合は、名前解決に時間がかかる可能性があります。

FQDNをクライアントとサーバーの/ etc/hostsに入れて再起動し、何もキャッシュされないようにするか、参照をIPアドレスベースに変更して、改善が見られないかどうかを確認します。

1
Wing Tang Wong

上の出力で、スワップスペースを使用していることに気づきました。スワッピングを停止するには、それを取得する必要があります。スワップはmemcachedのパフォーマンスを低下させます。

0
John Reilly

2つのことに気づきました。ヒット率は非常に低く、可能な限り100%に近いはずです。 memcachedに使用できる200MBを超える空きメモリがあります。

0

Memcachedフラッシュを実行したので、動作していると思われる出力例を投稿すると思います。 New Relicはmemcachedで費やされた10.4msを報告しているので、複数の呼び出しをカウントしていると思います。ベアメタルまたは仮想マシンで実行していますか?速度を重視している場合、仮想マシンを使用する方法はありません( http://redis.io/topics/benchmarks

memcache-top v0.6   (default port: 11211, color: on, refresh: 3 seconds)

    INSTANCE        USAGE   HIT %   CONN    TIME    EVICT/s READ/s  WRITE/s 
    app01:11211     0.5%    49.8%   2994    0.7ms   0.0 75.2K   378.5K  
    app02:11211     0.5%    51.7%   2992    0.7ms   0.0 76.5K   143.9K  
    app03:11211     1.0%    69.6%   1469    0.7ms   0.0 42.0K   161.3K  
    app04:11211     2.0%    52.6%   801 0.5ms   0.0 66.0K   415.9K  
    app05:11211     2.2%    52.5%   801 0.4ms   0.0 71.9K   171.2K  
    app06:11211     2.0%    66.4%   800 0.5ms   0.0 135.9K  180.4K  
    app07:11211     1.9%    52.0%   800 0.6ms   0.0 65.5K   482.4K  
    app08:11211     1.1%    87.1%   1469    0.7ms   0.0 59.3K   365.3K  
    db01:11211      1.0%    82.4%   1469    0.5ms   0.0 64.6K   155.4K  
    elastic01:11211     1.7%    69.9%   737 0.5ms   0.0 44.2K   128.8K  
    elastic02:11211     1.7%    65.0%   737 0.5ms   0.0 48.2K   155.8K  
    elastic03:11211     1.8%    68.3%   737 0.6ms   0.0 24.5K   115.7K  
    elastic04:11211     1.8%    69.5%   737 0.7ms   0.0 95.3K   158.0K  

    AVERAGE:        1.5%    64.4%   1272    0.6ms   0.0 66.9K   231.7K  

    TOTAL:      12.1GB/ 1.0TB       16.2K   7.6ms   0.0 869.1K  2.9M    
    (ctrl-c to quit.)
0
James

Django=およびmemcachedの問題は、リクエストごとに接続を確立することです。そのため、その時間の一部は接続セットアップ時間です。

使用しているmemcacheバインディングによって異なります。しかし、あなたはあなたのwsgi.pyにこのようなものを置くことができました

# Fix Django closing connection to memcached after every request (#11331)
from Django.core.cache.backends.memcached import BaseMemcachedCache
BaseMemcachedCache.close = lambda self, **kwargs: None

基本的には、モンキーはクローズしないようにクローズハンドラーにパッチを当てます。

それが機能しない場合は、memcachedクラスに置き換えます。

0
dalore