2013-09-03 8 views
5

Ich habe eine Rails-App läuft, die Redis ziemlich viel verwendet - aber - ich sehe einige Redis::TimeoutError hier und da auftreten, von Zeit zu Zeit. Es gibt kein Muster in den Umständen. Es tritt sowohl in der Web-App als auch in den Hintergrundaufträgen auf (die mit sidekiq verarbeitet werden) - nicht oft, aber von Zeit zu Zeit.Wie debuggen/korrigieren zufällige auftretende Redis :: TimeoutError?

Jetzt habe ich keine Ahnung, wie man die Ursache dafür aufspüren und daher keine Ahnung, wie man es beheben kann. Hier

ist ein wenig Hintergrund auf meinem Setup:

Die redis Instanz auf einem separaten physischen Server ausgeführt wird, die sowohl mein Web-Server und Hintergrund-Server in einem privaten lokalen 1Gbit Netzwerk verbunden ist. Auf allen Servern läuft ubuntu 12.04. Die Redis-Version ist 2.6.10. Ich verbinde aus meiner Rails-Anwendung (die 3,2 ist) einen Initialisierer wie so mit:

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

Dies ist die Ausgabe von redis-cli INFO:

# 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 

In meiner redis Config Ich habe folgenden Satz:

\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

So kommen die Timeout-Fehler in Batches oder sporadisch. –

+0

auch was ergibt rediscli - latency als die maximale Latenz zu Ihrem Host, wenn sie für eine Weile ausgeführt wird? –

+0

@MichaelPapile Ich denke, dass sie in kleinen Chargen auftreten - aber nicht sicher und nicht sehr deutlich - wenn ja - es ist überhaupt nicht wie alles an Vorhang Punkten oder irgendetwas scheitert –

Antwort

7

, die von vielen Fragen kommen könnte.

  • , weil Sie den SAVE Befehl verwenden (es ist in Ihrem conf ist Setup) eine Menge I zu erzeugen/O und hämmere den Server, vor allem, wenn Sie EBS-Volumes bei Amazon verwenden.
  • weil Sie einen Redis-Slave haben (wie zuvor, tun SAVE vor der Spiegelung).
  • , weil Sie eine KEY * verwenden, die auf vielen Indizes sehr langsam ist.

Ich schrieb einen Artikel zu diesen Themen, siehe here.

1

Es kann ein Problem auf der Clientseite sein, wenn der Server normal funktioniert. Jede Redis-Clientinstanz, nicht der Server, hat ebenfalls eine Zeitüberschreitungseinstellung, und die Standardeinstellung ist sehr kurz - etwa einige Millisekunden. Wenn der Server innerhalb dieser Zeit nicht antwortet, wird vom Client ein Redis :: TimeoutError ausgelöst.

Das erste, was Sie versuchen können, ist einen längeren Timeout-Wert einzustellen und zu sehen, ob die Dinge besser werden.

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

Auch bei längerer Timeout-Einstellung, gibt es keine Garantie, dass nicht passieren würde Timeout, aber dann würde es ein Problem der Gestaltung Ihres Systems sein.

0

Rollen Sie Ihren eigenen Code, um sich mit redis zu verbinden, oder lassen Sie sidekiq einfach damit umgehen? Ich denke, du solltest deinen Verbindungscode wirklich so gestalten, dass die Verbindung wiederhergestellt wird, wenn die Verbindung unterbrochen wurde. Sie können Redis :: BaseConnectionError retten und die Verbindung wiederherstellen.

2
  1. Versuchen Sie "Slowlog" Befehl auf dem Redis-Server, um zu sehen, ob es einige "langsame Abfrage" gibt.
  2. Schreiben Sie einige Protokolle, wenn "TimeoutError" passiert, um zu sehen, ob der "Fehler Redis Befehl" im "langsamen Protokoll".
  3. passen Sie Ihre Timeout auf der Client-Seite Einstellung
Verwandte Themen