Redis는 모든 메모리와 충돌을 차지합니다


12

Redis 서버 v2.8.4는 8GB RAM 및 16GB 스왑 공간 (SSD)이있는 Ubuntu 14.04 VPS에서 실행됩니다. 그러나 혼자서 메모리 를 차지하고 htop있음을 보여줍니다 !redis22.4 G

redis-server추억으로 인해 결국 추락했다. Mem그리고 Swp모두는 100 %에 도달 redis-server다른 서비스와 함께 살해된다.

보낸 사람 dmesg:

[165578.047682] Out of memory: Kill process 10155 (redis-server) score 834 or sacrifice child
[165578.047896] Killed process 10155 (redis-server) total-vm:31038376kB, anon-rss:5636092kB, file-rss:0kB

redis-serverOOM 충돌이 발생하거나 다시 시작 service redis-server force-reload하면 메모리 사용량이 100MB 미만으로 떨어집니다.

질문 :redis-server 충돌 할 때까지 왜 더 많은 메모리를 차지합니까? 어떻게 방지 할 수 있습니까?

maxmemoryred가 maxmemory한도에 도달하면 데이터 제거를 시작하기 때문에 설정 이 작동하지 않는 것이 사실 입니까?

여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오

redis-server를 다시 시작한 후

여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오

Redis 버전 : Redis server v=2.8.4 sha=00000000:0 malloc=jemalloc-3.4.1 bits=64 build=a44a05d76f06a5d9


최신 정보

htop보고서의 메모리 사용량이 redis-server제 4.4g RAM 및 22.6G 스왑으로, 레디 스의 키를 모두 차지하는 공간의 크기가 아니라 60.59636307 MB에 의해보고, rdbtools . 이것은 redis-server다시 시작한 직후에 차지하는 RAM의 양이기도합니다 .

INFO ALLredis-server메모리를 많이 복용

mem_fragmentation_ratio:0.19

127.0.0.1:6379> INFO all

# Server
redis_version:2.8.4
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:a44a05d76f06a5d9
redis_mode:standalone
os:Linux 3.13.0-24-generic x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.8.2
process_id:26858
run_id:4d4a507b325e567d5ada203a0c65891bcf4d02de
tcp_port:6379
uptime_in_seconds:100011
uptime_in_days:1
hz:10
lru_clock:165668
config_file:/etc/redis/redis.conf

# Clients
connected_clients:60
client_longest_output_list:768774
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:23973468008
used_memory_human:22.33G
used_memory_rss:4563857408
used_memory_peak:24083474760
used_memory_peak_human:22.43G
used_memory_lua:33792
mem_fragmentation_ratio:0.19
mem_allocator:jemalloc-3.4.1

# Persistence
loading:0
rdb_changes_since_last_save:127835154
rdb_bgsave_in_progress:0
rdb_last_save_time:1406716479
rdb_last_bgsave_status:err
rdb_last_bgsave_time_sec:1
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:110
total_commands_processed:386765263
instantaneous_ops_per_sec:3002
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:1385878
keyspace_misses:23655
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:82

# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:10547.48
used_cpu_user:8240.36
used_cpu_sys_children:201.83
used_cpu_user_children:914.86

# Commandstats
cmdstat_del:calls=136,usec=1407,usec_per_call=10.35
cmdstat_exists:calls=161428,usec=1391252,usec_per_call=8.62
cmdstat_zadd:calls=64149642,usec=936323882,usec_per_call=14.60
cmdstat_zrem:calls=137,usec=2131,usec_per_call=15.55
cmdstat_zremrangebyscore:calls=2293,usec=111905082,usec_per_call=48802.91
cmdstat_zrange:calls=7925,usec=285907448,usec_per_call=36076.65
cmdstat_zrangebyscore:calls=921434,usec=292731002,usec_per_call=317.69
cmdstat_zcount:calls=8,usec=172,usec_per_call=21.50
cmdstat_zrevrange:calls=191184,usec=965447,usec_per_call=5.05
cmdstat_zcard:calls=5180,usec=13502,usec_per_call=2.61
cmdstat_zscore:calls=29856,usec=576044,usec_per_call=19.29
cmdstat_hset:calls=64145124,usec=199407095,usec_per_call=3.11
cmdstat_hget:calls=248487,usec=501220,usec_per_call=2.02
cmdstat_hincrby:calls=128339355,usec=2071112929,usec_per_call=16.14
cmdstat_hgetall:calls=193747,usec=1608260,usec_per_call=8.30
cmdstat_select:calls=1,usec=5,usec_per_call=5.00
cmdstat_rename:calls=134,usec=1090,usec_per_call=8.13
cmdstat_keys:calls=4503,usec=4997628,usec_per_call=1109.84
cmdstat_bgsave:calls=2,usec=20012,usec_per_call=10006.00
cmdstat_type:calls=603,usec=2736,usec_per_call=4.54
cmdstat_multi:calls=64181979,usec=383633610,usec_per_call=5.98
cmdstat_exec:calls=64181979,usec=4403181204,usec_per_call=68.60
cmdstat_info:calls=126,usec=28675,usec_per_call=227.58

# Keyspace
db0:keys=2109,expires=0,avg_ttl=0

답변:


8
  1. maxmemoryRedis 데이터베이스가 얼마나 커질 수 있는지에 대한 한계를 설정하려면를 사용하십시오 . 그렇게하지 않으면 Redis는 메모리가 소진되면 (현재 경험에 따라) OS가 OS를 종료 할 때까지 커집니다.
  2. 사용법은 다음 maxmemory과 함께 maxmemory-policy사용해야합니다. 사용 사례의 요구 사항에 따라 다른 제거 정책 중에서 선택할 수 있습니다. 예를 들어, allkeys-lru퇴거 정책 을 사용하는 경우 Redis는 실제로 가장 최근에 사용 된 데이터 maxmemory에 도달 하면 퇴거를 시작 합니다. 또는 volatile-lru또는 volatile-random정책으로 만료 가능한 데이터 만 제거하도록 Redis에 지시 할 수 있습니다 . 마지막으로 정책을 설정할 수는 noeviction있지만 일단 메모리가 소진되면 Redis는 OOM 메시지를 사용한 추가 쓰기를 거부합니다.

편집하다:

먼저 스왑 비활성화-Redis와 스왑이 쉽게 혼합되지 않으므로 속도가 느려질 수 있습니다.

또한 이렇게 free -m대신 RAM의 상태 (전체 그림에 대한 상단의 http://www.linuxatemyram.com/ ).


메모리 사용이 계속 증가하는 이유에 대해 혼란스러워하지만 bgsave다시 시작 redis-server하면 메모리 사용이 더 합리적인 값인 70MB로 떨어집니다. 이것이 메모리 누수 일 수 있습니까?
Nyxynyx

가능하지만 가능성이 낮거나 다른 사람들이보고했을 것입니다 ... 조각화 문제 일 가능성이 높습니다. 다음 번에 Redis의 출력을 게시하십시오 INFO ALL. 내 추측이 맞다면, mem_fragmentation_ratio의지는 하늘 높이 올랐다.
Itamar Haber

redis-server모든 기억을 고르고 매일 충돌합니다. 이제 모든 메모리를 사용하려고하므로 출력을 캡처 INFO ALL하여 OP에 추가했습니다. mem_fragmentation_ratio:0.19
Nyxynyx

redis 데이터 세트가 250MB를 초과하지 않고 maxmemory1GB로 설정된 경우 redis의 mem 사용량이 1GB에 도달하면 퇴거가 여전히 데이터를 제거한다는 의미입니까? redis 's mem_fragmentation_ratio가 이므로 0.19조각화가 너무 많거나 너무 많이 스왑 또는 둘 다에 저장되어 있음을 의미합니까? 조각화를 줄일 수있는 방법이 있습니까?
Nyxynyx

OOM으로 인해 redis-server가 충돌하려고하면 rdbtools는 redis의 키가 60MB 만 차지한다는 것을 보여줍니다. 이것은 매우 심각한 조각화처럼 보입니까? 4.4GB의 RAM과 22.4G의 스왑을 고려합니다.
Nyxynyx

5

redis가 잘 알려져 있고 프로덕션에서 사랑 받고 메모리 누수가 발견되지 않았기 때문에 이것은 거의 확실히 메모리 조각화입니다.

풀 크기 설정에 대한 권장 사항은 조각화에 도움이되지 않습니다. Redis는 조각화를 설명 할 수 없기 때문에 Redis 크기를 실제 메모리 크기보다 낮게 지정해야합니다. 단, 짧은 대답의 경우이를 수행하고 다시 시작하는 계획을 시작해야합니다. 자주 서버.

다양한 운영 체제 및 메모리 내 데이터베이스를 사용하는 경험에 따르면, 실제 메모리의 2 배가 필요하며 메모리 크기는 약 2 주 후에 안정화됩니다.

그러나 이는 실제 할당 패턴과 사용중인 메모리 할당 자에 따라 다릅니다.

현재 서버에서 찾은 최고의 메모리 할당자는 JEMalloc입니다. Aerospike 에서이를 사용하여 장기 메모리 조각화를 줄입니다 (거의 제거). JEMalloc에는 메모리 "아레나"(풀)를 생성하고 모든 할당에서 어떤 풀을 선택하여 비슷한 크기의 할당을 제공하고 유사한 메모리 수명 할당을 관리 할 수있는 기능이 있습니다. 당신이 논의하는 종류의 경우 우리에게 큰 승리였습니다.

Zend PHP 엔진은 엔진 내부의 모든 할당이 트랜잭션 당 메모리 또는 전역 메모리에 있기 때문에 이와 관련하여 정교합니다. 트랜잭션 당 메모리는 트랜잭션 종료시 한 번의 스왑으로 해제되므로 매우 효율적일 수 있습니다.

Linux를 사용하는 경우 커널 메모리 할당 자 (Clib)는 많은 변화를 겪었으며 실제 버전에 따라 실제 응용 프로그램 패턴과 마찬가지로 조각화의 양을 결정합니다. 예를 들어, 개체를 약간자를 때 일부 할당자가 훨씬 더 좋고 일부는 훨씬 나쁩니다. 안타깝게도 다른 Redis 사용자와 논의하더라도 사용중인 OS 및 OS 버전에 대해 이야기하는 것을 의미합니다.

지속성에서 서버를 다시 시작하고 메모리를 다시 가져올 수 있다는 사실은 누수를 의미 할 수 있지만 조각화가 발생할 가능성이 높습니다.

  1. 스왑을 허용하지 않음 (레디 스의 경우 스왑보다 OOM에 더 좋습니다)
  2. redis의 메모리 크기 감소
  3. 일정에 따라 다시 시작

maxmemory? 를 조정하여 메모리 크기를 어떻게 줄이 겠습니까?
Nyxynyx
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.