Игра с Redis-удалились 2 миллиона ключей, почему до сих пор не освобождается память?

Redis
Игра с Redis-удалились 2 миллиона ключей, почему до сих пор не освобождается память?

   Серия статей «Игра с Redis» в основном описывает базовые, промежуточные и расширенные приложения Redis. Эта статья является [12-й] статьей в серии «Игры с Redis». Последние серии статей можно найти на страницеПубличный аккаунт "zxiaofan" (нажми на меня, нажми на меня)просмотр, илиПоиск Baidu «играть в Redis zxiaofan»Вот и все.

Прошлые выборы:«Поиграйте с использованием и принципом фильтра Блума в Redis-Redis»

Ключевые слова в этой статье: игра с Redis, фрагментация памяти Redis, освобождение памяти Redis;

контур

  • задний план
  • Как просмотреть данные памяти Redis
  • Почему не освобождается память
    • Что такое фрагментация памяти
    • Как формируется фрагментация памяти Redis?
  • как освободить память
  • Меры предосторожности при дефрагментации памяти в рабочей среде

1. Предпосылки

   Кластер Redis, используемый бизнесом компании, построен самостоятельно.Некоторое время назад планировалось перенести самостоятельно построенный кластер Redis на приобретенный кластер Alibaba Cloud.
Старый кластер имеет в общей сложности 350 Вт ключей, занимающих 8,8 ГБ памяти.Анализ DTS перед миграцией показал, что почти два миллиона ключей не нужно было мигрировать, поэтому два миллиона ключей были удалены заранее.
После удаления ключа я обнаружил, что память redis почти не изменилась, ключ 350W удалил два миллиона, поэтому я должен освободить несколько гигабайт памяти. Удаление не удалось? Путем сравнения данных обнаруживается, что данные, которые планировалось удалить, действительно были удалены.
Почему память не освобождается после удаления 2 миллионов ключей? Эта проблема беспокоила меня в течение долгого времени, и я, наконец, понял это, ознакомившись с информацией.

2. Как просмотреть данные памяти Redis

2.1, информационная память

   После входа в интерфейс командной строки Redis используйте команду info memory (кластер использует команду cluster info), чтобы просмотреть текущую информацию о памяти, связанную с Redis.Некоторая информация отображается следующим образом:

127.0.0.1:6379> info memory
# Memory

# Redis 保存数据申请的内存空间
used_memory:9469412118
used_memory_human:8.82G

# 操作系统分配给 Redis 进程的内存空间
used_memory_rss:11351138316
used_memory_rss_human:10.57G

# Redis 进程在运行过程中占用的内存峰值
used_memory_peak:12618222522
used_memory_peak_human:11.75G

# 内存碎片率,used_memory_rss / used_memory
mem_fragmentation_ratio:1.20

# Redis 最大可用内存,0表示不限制
maxmemory:0
maxmemory_human:0B

# 内存分配器
mem_allocator:jemalloc-5.1.0

Давайте объясним, что означает каждый атрибут:

used_memory: Redis сохраняет пространство памяти, запрошенное данными, включая память, занимаемую процессом Redis и данными, в байтах;

used_memory_rss: Пространство памяти, выделенное операционной системой процессу Redis (включая пространство, занимаемое фрагментами памяти), представляет собой данные с точки зрения операционной системы; результат данных примерно равен результату данных, видимому командами top и ps .

used_memory_peak: пиковый объем памяти, занимаемый процессом Redis во время работы, used_memory_peak >= used_memory;

maxmemory: максимальная доступная память Redis, 0 означает отсутствие ограничений. Он может легко реализовать управление памятью при развертывании нескольких процессов Redis на одном сервере, предотвратить превышение объема используемой памяти над физической памятью сервера и упростить реализацию стратегий удаления, таких как LRU, когда данные превышают лимит памяти.

XXX_human: Указывает, что XXX возвращается в удобочитаемом виде.

mem_fragmentation_ratio: скорость фрагментации памяти, used_memory_rss/used_memory. Часть больше 1 — это размер, занимаемый фрагментами redis.Рекомендуемое значение больше 1, но меньше 1,5.Если больше 1,5, значит фрагментов слишком много и их нужно очистить.

  Следует отметить, что в общем случае used_memory_rss больше, чем used_memory, но бывают исключения, когдаКогда used_memory_rss меньше, чем used_memory, что указывает на то, что данных, выделенных операционной системой процессу Redis, недостаточно для удовлетворения фактических требований к хранению данных.Часть данных памяти Redis будет преобразована в Swap, в результате проблема заключается в том, что когда Redis обращается к данным в Swap,производительность ухудшится.

2.2, команда памяти xxx

2.2.1, доктор памяти

  Перечисляет различные типы проблем, связанных с памятью, с которыми сталкиваются серверы Redis, и предоставляет соответствующие решения.

127.0.0.1:6379> memory doctor
Hi Sam, I can't find any memory issue in your instance. I can only account for what occurs on this base.

2.2.2, malloc-статистика памяти

   Предоставляет внутренние статистические отчеты о распределении памяти (в настоящее время поддерживает только распределитель памяти jemalloc). С помощью этой команды вы можете увидеть подробное состояние памяти каждого конкретного раздела, когда jemalloc выделяет все объекты.
Команда memory malloc-stats возвращает много информации, подробный анализ здесь не проводится, заинтересованные студенты могут выполнить анализ команды самостоятельно.

2.2.3, очистка памяти

   Ручная дефрагментация памяти заблокирует основной процесс.

127.0.0.1:6379> memory purge
OK

2.2.4, статистика памяти

   возвращает использование памяти сервером в виде массива;

127.0.0.1:6379> memory stats
 1) "peak.allocated"
 2) (integer) 905331384
 3) "total.allocated"
 4) (integer) 905330152
 5) "startup.allocated"
 6) (integer) 791160
 7) "replication.backlog"
 8) (integer) 0
 9) "clients.slaves"
10) (integer) 0
11) "clients.normal"
12) (integer) 49694
13) "aof.buffer"
14) (integer) 0
15) "lua.caches"
16) (integer) 0
17) "db.0"
18) 1) "overhead.hashtable.main"
    2) (integer) 7888
    3) "overhead.hashtable.expires"
    4) (integer) 32
19) "db.1"
20) 1) "overhead.hashtable.main"
    2) (integer) 304
    3) "overhead.hashtable.expires"
    4) (integer) 32
21) "overhead.total"
22) (integer) 849110
23) "keys.count"
24) (integer) 152
25) "keys.bytes-per-key"
26) (integer) 5950914
27) "dataset.bytes"
28) (integer) 904481042
29) "dataset.percentage"
30) "99.99359130859375"
31) "peak.percentage"
32) "99.999870300292969"
33) "allocator.allocated"
34) (integer) 905598528
35) "allocator.active"
36) (integer) 905961472
37) "allocator.resident"
38) (integer) 910348288
39) "allocator-fragmentation.ratio"
40) "1.0004007816314697"
41) "allocator-fragmentation.bytes"
42) (integer) 362944
43) "allocator-rss.ratio"
44) "1.0048421621322632"
45) "allocator-rss.bytes"
46) (integer) 4386816
47) "rss-overhead.ratio"
48) "0.0086568007245659828"
49) "rss-overhead.bytes"
50) (integer) -902467584
51) "fragmentation"
52) "0.0087051792070269585"
53) "fragmentation.bytes"
54) (integer) -897408432

2.2.5, использование памяти

   возвращает количество байтов, занимаемых ключом, и его значение в памяти (включая память, занятую redis для управления ключом);

127.0.0.1:6379> memory usage key1
(integer) 46

2.2.6, помощь с памятью

Справочная информация для   команд, связанных с памятью;

127.0.0.1:6379> memory  help
1) MEMORY <subcommand> arg arg ... arg. Subcommands are:
2) DOCTOR - Return memory problems reports.
3) MALLOC-STATS -- Return internal statistics report from the memory allocator.
4) PURGE -- Attempt to purge dirty pages for reclamation by the allocator.
5) STATS -- Return information about the memory usage of the server.
6) USAGE <key> [SAMPLES <count>] -- Return memory in bytes used by <key> and its value. Nested values are sampled up to <count> times (default: 5).

3. Почему не освобождается память?

Redis имеет свой собственный распределитель памяти, когда данные удаляются, освобожденное пространство памяти управляется собственным распределителем памяти Redis, и память не возвращается операционной системе немедленно, поэтому для операционной системы Redis по-прежнему считается занятым. по памяти.

Преимущество    заключается в том, что он уменьшает количество применений Redis для выделения памяти в системе и повышает производительность самого Redis.

3.1 Что такое фрагментация памяти

Многие учащиеся должны были слышать о фрагментации диска и использовать такие программы, как Smart Defrag, для устранения фрагментации диска.Очистка фрагментации диска может оптимизировать файловую систему, перемещать и объединять разрозненное пространство на диске, а также размещать на диске часто используемые файлы и каталоги. , Скорость самая быстрая.Быстрая область, так что компьютер может стабильно работать на самой высокой скорости.

   Фрагментация памяти связана с тем, что планируемое пространство приложения меньше, чем свободное непрерывное пространство, поэтому эта часть небольшого пространства памяти не может быть использована, а пространство памяти, которое нельзя использовать, можно назвать фрагментацией памяти.

内存碎片示意图

Как показано на рисунке, на схематической диаграмме 9-байтового пространства памяти использовалось пространство памяти с порядковыми номерами 1, 2, 3, 5, 6 и 9. Если вы планируете применить 3-байтовое непрерывное пространство памяти , в соответствии с существующим использованием памяти. Если вы не можете применить, порядковые номера 4, 7 и 8 являются «фрагментами памяти».

3.2 Как формируется фрагментация памяти Redis?

Фрагментация памяти Redis в основном вызвана следующими двумя причинами:

  • механизм распределения памяти;
  • Изменение и удаление данных Redis приводит к расширению и освобождению места;

3.2.1, механизм распределения памяти

  Redis имеет несколько распределителей памяти jemalloc, libc, tcmalloc, и по умолчанию используется jemalloc.
Метод выделения памяти jemalloc заключается в выделении пространства памяти в соответствии с рядом фиксированных размеров, а jemalloc выделяет ближайшее пространство памяти в соответствии с запрошенным размером памяти;
Например, если вы подаете заявку на 220 байт, jemalloc выделит 256 байт.Если вы продолжите записывать 20 байт, Redis не будет продолжать запрашивать пространство памяти в системе, потому что из ранее примененных 256 байт все еще остается 36 байт, но Если в это время необходимо продолжить запись 60 байт, выделенного места недостаточно, и необходимо снова обратиться в систему для выделения места в памяти.

64-битная система jemalloc по умолчанию разделена следующим образом:
Small: [8], [16, 32, 48, ..., 128], [192, 256, 320, ..., 512], [768, 1024, 1280, ..., 3840]
Large: [4 KiB, 8 KiB, 12 KiB, ..., 4072 KiB]
Huge: [4 MiB, 8 MiB, 12 MiB, ...]

3.2.2. Изменение и удаление данных Redis приводит к расширению и освобождению места

Как показано на рисунке ниже, при расширении ключа 1 необходимо добавить 2 байта.Чтобы обеспечить непрерывность пространства памяти, переносится ключ 2, когда ключ 3 освобождает место, пробелы с порядковыми номерами 7, 8, 14 и 15 не используются.
Если есть ключ, который хочет подать заявку на 3 байта пространства в это время, хотя всего осталось 4 байта, непрерывных 3 байта пространства нет, поэтому его нельзя использовать напрямую.

   После понимания принципа, если мы хотим протестировать очистку фрагментации памяти, мы можем вставить большое количество ключей, а затем удалить большое количество ключей (или установить время истечения срока действия при вставке ключей), чтобы смоделировать сценарий с высокой степенью фрагментации памяти.

内存空间的扩容和释放

4. Как освободить память

4.1. Перезапустите Redis, чтобы освободить память

   Это должен быть самый прямой и эффективный метод. Но производственная среда — это не то, что вы можете перезапустить, если хотите. Поскольку перезапуск Redis требует рассмотрения многих вопросов, таких как:

  • Загрузка данных восстановления при перезагрузке занимает время, в течение которого Redis будет недоступен;
  • Убедитесь, что все изменения элементов конфигурации обновлены до redis.conf, иначе конфигурация, измененная онлайн, будет восстановлена ​​​​после перезапуска;

4.2. Используйте резервный экземпляр Redis для синхронной миграции

Генерация фрагментации памяти во многом связана с модификацией и удалением данных, поэтому при планировании очистки фрагментации памяти экземпляра A мы можем ввести экземпляр B, синхронизировать все данные экземпляра A с экземпляром B, а затем использовать экземпляр B для замены исходного фрагмента памяти.Некоторый экземпляр A предоставляет внешние услуги.

   Хотя идея этого метода является общей, процесс работы сложен, риск высок, и он редко используется в производственной среде. Но если вы планируете перенести свои инстансы, это как раз то, что вам нужно.

4.3, очистка памяти, ручная дефрагментация

   Ручная дефрагментация памяти заблокирует основной процесс, поэтому используйте ее с осторожностью в производственной среде.

  memory purge и activedefrag не освобождают память в одной и той же области.Он просто и грубо пытается очистить грязные страницы для освобождения памяти распределителем. Его можно использовать в сочетании с активным дефрагментом в соответствии с реальной ситуацией.Очистка памяти работает лучше в крайних случаях, в то время как активный дефраг более тщательный.

4.4, откройте автоматическую дефрагментацию activedefrag

   Новый элемент конфигурации activedefrag (активный: активный, дефрагментация: дефрагментация) добавлен после версии Redis 4.0, активный дефрагмент по умолчанию отключен, и его необходимо включить вручную при планировании очистки мусора, команда выглядит следующим образом:

127.0.0.1:6379> config set activedefrag yes

   Давайте посмотрим на соответствующие файлы конфигурации:

# 以下内容节选至 redis.conf

########################### ACTIVE DEFRAGMENTATION #######################

# 3. Once you experience fragmentation, you can enable this feature when
#    needed with the command "CONFIG SET activedefrag yes".
#

# Enabled active defragmentation
# activedefrag yes

# Minimum amount of fragmentation waste to start active defrag
# active-defrag-ignore-bytes 100mb

# Minimum percentage of fragmentation to start active defrag
# active-defrag-threshold-lower 10

# Maximum percentage of fragmentation at which we use maximum effort
# active-defrag-threshold-upper 100

# Minimal effort for defrag in CPU percentage
# active-defrag-cycle-min 5

# Maximal effort for defrag in CPU percentage
# active-defrag-cycle-max 75

# Maximum number of set/hash/zset/list fields that will be processed from
# the main dictionary scan
# active-defrag-max-scan-fields 1000

Переключатель дефрагментации памяти (выполнять только при соблюдении обоих условий):

  • activedefrag: Основной переключатель дефрагментации памяти, выполнить дефрагментацию можно только после его включения;
  • active-defrag-ignore-bytes: когда количество байтов фрагментов памяти достигает этого порога (по умолчанию 100 МБ), дефрагментация разрешается;
  • active-defrag-threshold-lower: Когда доля пространства фрагментации памяти в общем пространстве, выделенном Redis операционной системой, достигает этого порога (по умолчанию 10%), дефрагментация разрешается;

Кроме того, существует несколько параметров дляКонтролируйте силу дефрагментации памяти:

  • active-defrag-cycle-min: Доля процессорного времени, занимаемая очисткой фрагментов памяти, не ниже этого порога (по умолчанию 5%), чтобы обеспечить нормальную очистку;
  • active-defrag-cycle-max: доля процессорного времени, занимаемая очисткой фрагментов памяти, не превышает этого порога (по умолчанию 75%), и после его превышения очистка будет остановлена, чтобы избежать блокировки Redis большим количеством копий памяти во время очистки и задержки. другие запросы.

Другие параметры для дефрагментации памяти:

  • active-defrag-threshold-upper: когда доля пространства фрагментации памяти в общем пространстве, выделенном Redis операционной системой, достигает этого порога (по умолчанию 100%), она сделает все возможное для организации;
  • active-defrag-max-scan-fields: Дефрагментация При сканировании набора/хэша/zset/списка этот ключ будет добавлен к дефрагментации только тогда, когда длина набора/хэша/zset/списка меньше этого порога;

5. Меры предосторожности в отношении фрагментации памяти в производственной среде

5.1 Время убрать фрагментацию памяти

   Проверить mem_fragmentation_ratio (коэффициент фрагментации памяти) через команду "info memory", при значении mem_fragmentation_ratio > 1,5 рекомендуется начать очистку фрагментов памяти. Конечно, эффект автоматической очистки также может быть достигнут путем анализа и настройки конфигурации параметров activedefrag.

5.2 Что нужно знать перед очисткой фрагментов памяти

memory purge: Ручная дефрагментация памяти блокирует основной процесс.Используйте ее с осторожностью в производственной среде.Эффект очистки отличается от activedefrag.

activedefrag: автоматическая дефрагментация фрагментов памяти. Принцип заключается в повторении всех данных Redis посредством сканирования и полной дефрагментации памяти посредством серии операций копирования и передачи памяти. Поскольку эта операция использует основной поток, она повлияет на реакцию Redis на другие запросы.

В журнале Redis вы можете просмотреть записи активной дефрагментации, занимающей много времени и ресурсов: Активная дефрагментация, выполненная за 79214 мс, означает трудоемкость, но эта трудоемкость — это не время, которое блокирует основной поток, а время от первого проверка дефрагментации памяти до конца Разница во времени между проверками, в течение которой основной поток может обрабатывать другие запросы.

12:M 21 May 12:31:11.210 - Starting active defrag, frag=12%, frag_bytes=381401201, cpu=75%
12:M 21 May 12:32:30.424 - Active defrag done in 79214ms, reallocated=50, frag=12%, frag_bytes=380061210

[Статьи из серии Fun with Redis, недавно опубликованные @zxiaofan]

«Поиграйте с использованием и принципом фильтра Блума в Redis-Redis»

«Изучение принципа игры с Redis-HyperLogLog»

«Развлечение с Redis-HyperLogLog для подсчета ежедневной и ежемесячной активности Weibo»

«Как играть с Redis-JD.com, чтобы войти и получить Jingdou»

«Игра с Redis — Boss поможет вам понять распределенные блокировки»


Удачи тебе!

Вся жизнь состоит из выбора!
В будущем вы обязательно будете благодарны себе за то, что усердно трудитесь сейчас!
CSDN】【GitHub】【OSCHINA】【Наггетс】【язык птица】【Публичный аккаунт WeChat