Redis server v2.8.4 berjalan pada Ubuntu 14.04 VPS dengan 8 GB RAM dan 16 GB ruang swap (pada SSD). Namun htop
menunjukkan bahwa itu redis
saja yang menghabiskan 22.4 G
memori!
redis-server
akhirnya jatuh karena kehabisan memeory. Mem
dan Swp
keduanya hit 100% kemudian redis-server
terbunuh bersama dengan layanan lain.
Dari 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
Memulai kembali redis-server
dari kecelakaan OOM atau service redis-server force-reload
menyebabkan penggunaan memori turun menjadi <100MB.
Pertanyaan: Mengapa redis-server
memori lebih banyak dan lebih banyak sampai crash? Bagaimana kita bisa mencegah ini?
Apakah benar pengaturan maxmemory
tidak akan berfungsi karena setelah redis mencapai maxmemory
batas, itu akan mulai menghapus data?
Setelah memulai ulang redis-server
Versi redis: Redis server v=2.8.4 sha=00000000:0 malloc=jemalloc-3.4.1 bits=64 build=a44a05d76f06a5d9
Memperbarui
Ketika htop
melaporkan penggunaan memori redis-server
menjadi 4.4G RAM dan 22.6G Swap, jumlah ruang yang diambil oleh semua tombol dalam redis hanya 60.59636307 MB
, seperti yang dilaporkan oleh rdbtools . Ini juga jumlah RAM yang diambil redis-server
tepat setelah restart.
INFO ALL
saat redis-server
mengambil banyak memori
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
bgsave
dan memulai kembaliredis-server
menyebabkan penggunaan memori turun ke nilai yang lebih masuk akal yaitu 70 MB. Mungkinkah ini kebocoran memori?INFO ALL
. Jika tebakan saya benar,mem_fragmentation_ratio
kemauan akan setinggi langit.redis-server
babi semua memori dan crash setiap hari. Ini akan menggunakan semua memori sekarang, jadi saya sudah menangkap outputINFO ALL
dan ditambahkan ke OP.mem_fragmentation_ratio:0.19
maxmemory
diatur ke 1 GB, apakah ini berarti bahwa ketika penggunaan redis mencapai 1GB, penggusuran masih akan menghapus data? Karena redismem_fragmentation_ratio
adalah0.19
, apakah itu berarti ada terlalu banyak fragmentasi, atau terlalu banyak disimpan dalam swap, atau keduanya? Adakah cara untuk mengurangi fragmentasi?Ini hampir pasti fragmentasi memori, karena redis terkenal dan dicintai dalam produksi dan Anda mungkin belum menemukan kebocoran memori.
Rekomendasi tentang pengaturan ukuran kolam tidak akan membantu fragmentasi. Anda harus secara khusus menurunkan ukuran Redis - lebih rendah dari ukuran memori Anda yang sebenarnya - karena Redis tidak dapat menjelaskan fragmentasi - tetapi, dalam hal jawaban singkat, Anda harus melakukan itu, dan mulai merencanakan memulai kembali Anda server sering.
Aturan praktis saya yang bekerja dengan berbagai sistem operasi dan database dalam memori adalah Anda membutuhkan 2x memori Anda yang sebenarnya, dan ukuran memori akan stabil dalam sekitar 2 minggu.
Namun, itu tergantung pada pola alokasi aktual Anda, dan pengalokasi memori yang Anda gunakan.
Saat ini, pengalokasi memori terbaik yang saya temukan untuk server adalah JEMalloc. Kami menggunakannya di Aerospike sekarang untuk mengurangi (hampir menghilangkan) fragmentasi memori jangka panjang. JEMalloc memiliki fitur yang memungkinkan Anda untuk membuat "arena" memori (kumpulan), dan pada alokasi apa pun, pilih kumpulan mana, sehingga memberi Anda alokasi ukuran-suka dan untuk mengelola alokasi memori seumur hidup yang serupa. Ini merupakan kemenangan besar bagi kami dalam kasus-kasus yang Anda diskusikan.
Mesin Zend PHP canggih dalam hal ini, karena semua alokasi di dalam mesin baik dalam memori per transaksi, atau memori global. Memori per transaksi dibebaskan pada satu tegukan di akhir transaksi, dan dengan demikian bisa sangat efisien.
Jika Anda menggunakan Linux, pengalokasi memori kernel (Clib) telah melakukan beberapa putaran, dan versi yang Anda gunakan akan secara dramatis menentukan jumlah fragmentasi, seperti pola aplikasi yang sebenarnya. Sebagai contoh, beberapa pengalokasi jauh lebih baik ketika Anda objek yang sedikit tumbuh, beberapa jauh lebih buruk. Sayangnya, bahkan berdiskusi dengan pengguna Redis lain berarti membicarakan OS mana, dan versi OS mana yang Anda gunakan.
Fakta bahwa Anda dapat me-restart server (dari kegigihan) dan mendapatkan kembali memori Anda bisa berarti kebocoran, tetapi lebih cenderung mengarah ke fragmentasi.
sumber
maxmemory
?