2013-09-03 18 views
5

私は非常に多くのredisを使用しているレールアプリを実行しています - しかし、私は時々そこにかなり多くのRedis::TimeoutErrorが発生しているのを見ています。状況にはパターンはありません。これは、Webアプリケーションとバックグラウンドジョブ(sidekiqを使用して処理中)の両方で発生します。頻繁ではなく時々発生します。ランダムに発生するRedis :: TimeoutErrorのデバッグ/修正方法

今、私はこれの根本原因を突き止める方法を知らないので、それを修正する方法は考えられません。ここで

私のセットアップにはほとんど背景です:

Redisのインスタンスは、専用のローカルギガビットネットワークにおける私のWebサーバーとバックグラウンド・サーバーの両方に接続されている別の物理サーバ上で実行されています。すべてのサーバでubuntu 12.04が動作しています。 redisバージョンは2.6.10です。私はそうのような初期化子を使用して(3.2である)私のレールアプリから接続しています:

require 'redis' 
require 'redis/objects' 
REDIS = Redis.new(:url => APP_CONFIG['REDIS_URL']) 
Redis.current = REDIS 

これはredis-cli INFOの出力です:

私のRedisの設定で
# Server 
redis_version:2.6.10 
redis_git_sha1:00000000 
redis_git_dirty:0 
redis_mode:standalone 
os:Linux 3.2.0-38-generic x86_64 
arch_bits:64 
multiplexing_api:epoll 
gcc_version:4.6.3 
process_id:28475 
run_id:d89bbb1b81d3169c4228cf23c0988ae437d496a1 
tcp_port:6379 
uptime_in_seconds:14913365 
uptime_in_days:172 
lru_clock:1507056 

# Clients 
connected_clients:233 
client_longest_output_list:0 
client_biggest_input_buf:0 
blocked_clients:19 

# Memory 
used_memory:801637360 
used_memory_human:764.50M 
used_memory_rss:594706432 
used_memory_peak:4295394784 
used_memory_peak_human:4.00G 
used_memory_lua:31744 
mem_fragmentation_ratio:0.74 
mem_allocator:jemalloc-3.3.0 

# Persistence 
loading:0 
rdb_changes_since_last_save:23166 
rdb_bgsave_in_progress:0 
rdb_last_save_time:1378219310 
rdb_last_bgsave_status:ok 
rdb_last_bgsave_time_sec:4 
rdb_current_bgsave_time_sec:-1 
aof_enabled:0 
aof_rewrite_in_progress:0 
aof_rewrite_scheduled:0 
aof_last_rewrite_time_sec:-1 
aof_current_rewrite_time_sec:-1 
aof_last_bgrewrite_status:ok 

# Stats 
total_connections_received:932395 
total_commands_processed:3088408103 
instantaneous_ops_per_sec:837 
rejected_connections:0 
expired_keys:31428 
evicted_keys:3007 
keyspace_hits:124093049 
keyspace_misses:53060192 
pubsub_channels:0 
pubsub_patterns:0 
latest_fork_usec:17651 

# Replication 
role:master 
connected_slaves:1 
slave0:192.168.0.2,6379,online 

# CPU 
used_cpu_sys:54000.21 
used_cpu_user:73692.52 
used_cpu_sys_children:36229.79 
used_cpu_user_children:420655.84 

# Keyspace 
db0:keys=1498962,expires=1310 

私は、次のセットを持っています:

\fidaemonize yes 
pidfile /var/run/redis/redis-server.pid 
timeout 0 
loglevel notice 
databases 1 
save 900 1 
save 300 10 
save 60 10000 
stop-writes-on-bgsave-error yes 
rdbcompression yes 
rdbchecksum yes 
dbfilename dump.rdb 
dir /var/lib/redis 
slave-serve-stale-data yes 
slave-read-only yes 
slave-priority 100 
maxclients 1000 
maxmemory 4GB 
maxmemory-policy volatile-lru 
appendonly no 
appendfsync everysec 
no-appendfsync-on-rewrite no 
auto-aof-rewrite-percentage 100 
auto-aof-rewrite-min-size 64mb 
lua-time-limit 5000 
slowlog-log-slower-than 10000 
slowlog-max-len 128 
hash-max-ziplist-entries 512 
hash-max-ziplist-value 64 
list-max-ziplist-entries 512 
list-max-ziplist-value 64 
set-max-intset-entries 512 
zset-max-ziplist-entries 128 
zset-max-ziplist-value 64 
activerehashing yes 
client-output-buffer-limit normal 0 0 0 
client-output-buffer-limit slave 256mb 64mb 60 
client-output-buffer-limit pubsub 32mb 8mb 60 
+0

タイムアウトエラーはバッチで発生するか、散発的に発生します。 –

+0

redis-cli -latency yieldは、しばらくの間実行した場合のホストへの最大待ち時間とは何ですか? –

+0

@MichaelPapile私は小規模なバッチで発生している可能性があると思いますが、それほど明確ではないかと思います。カーテンポイントなどですべてが失敗しているようなものではない –

答えて

7

:Iの多くを生成しますがSAVEコマンドを使用しているため

  • (それはあなたのconfで設定があります)/Oを実行し、特にEBSボリュームをAmazonで使用している場合は、サーバーを叩きます。
  • Redisスレーブを使用しているため(以前と同じように、ミラーリングする前にSAVEを実行しています)。
  • 多くのインデックスでは非常に遅いKEY *を使用しているためです。

私はこれらの問題に関する記事を書きました。hereを参照してください。

1

サーバーが正常に実行されると、クライアント側で問題が発生する可能性があります。サーバーではなく各redisクライアントインスタンスにはタイムアウト設定もあり、デフォルト設定は非常に短く、数ミリ秒のようなものです。したがって、サーバーがその時間内に応答しない場合は、クライアントによってRedis :: TimeoutErrorが発生します。

あなたが試すことができる最初のことは、より長いタイムアウト値を設定し、状況が良くなるかどうかを確認することです。

redis_url = 'redis://user:[email protected]:port/' 
redis = Redis.connect(:url => redis_url, :timeout => 0.7) 

さらに長いタイムアウト設定で、タイムアウトが発生しないだろうが、それはあなたのシステムの設計の問題だろうという保証はありません。

0

redisに接続する独自のコードを使用しているのですか、それともsidekiqで処理できるのですか?接続が失われてしまった場合は、再接続するために接続コードを設計してください。 Redis :: BaseConnectionErrorを救済して再接続できます。

2
  1. redisサーバで「slowlog」コマンドを試して、「slow query」があるかどうかを確認してください。
  2. "TimeoutError"が発生したときにいくつかのログを書き、 "slow redisation"コマンドが "slow log"になっていないか確認してください。
  3. は、クライアント側での設定あなたのタイムアウトを調整
  4. 多くの問題から来ることができました
関連する問題