Статья для понимания мониторинга памяти Redis и потребления памяти

Redis
Статья для понимания мониторинга памяти Redis и потребления памяти

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

Статистика использования памяти

Метрики Redis, связанные с памятью, можно получить с помощью команды info memory. Наиболее важными индикаторами и пояснениями являются следующие:

Имя свойства Описание недвижимости
used_memory Общий объем памяти, выделенный распределителем Redis, то есть объем памяти, занимаемый всеми данными, хранящимися внутри.
used_memory_human Вернуть used_memory в удобочитаемом формате
used_memory_rss Отображает общий объем физической памяти, занимаемой процессом Redis, с точки зрения операционной системы.
used_memory_rss_human Отображать в удобном для пользователя формате used_memory_rss
used_memory_peak Максимальное значение использования памяти, указывающее пиковое значение used_memory
used_memory_peak_human Возвращает значение used_memory_peak в удобочитаемом формате.
used_memory_lua Объем памяти, потребляемый движком Lua.
mem_fragmentation_ratio Отношение used_memory_rss/used_memory, которое может представлять скорость фрагментации памяти
maxmemory Максимальный предел памяти, который может использовать Redis, 0 означает отсутствие ограничений в байтах.
maxmemory_policy Стратегия высвобождения памяти, используемая Redis, может быть noeviction, allkeys-lru, volatile-lru, allkeys-random, volatile-random или volatile-ttl. По умолчанию используется noeviction, что означает, что он не будет переработан.

image.png

Когда mem_fragmentation_ratio > 1, это означает, что часть памяти не используется для хранения данных, а потребляется фрагментацией памяти.Если значение большое, уровень фрагментации серьезный. Когда mem_fragmentation_ratio

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

В статье Администрирование Redis (ссылка в конце статьи) рекомендуется ставить область подкачки такого же размера, как и память.Если области подкачки нет, то однажды Redis вдруг понадобится больше памяти, чем текущая рабочая доступная системная память, Redis будет не хватать памяти OOM Killer убивает напрямую. Хотя производительность Redis ухудшится, когда данные Redis будут выгружены (swap out), это лучше, чем быть убитым напрямую.

Redis использует параметр maxmemory для ограничения максимального объема доступной памяти. Основные цели ограничения памяти:

  • Используется в сценариях кэширования, когда превышен предел памяти maxmemory, используйте стратегии удаления, такие как LRU, для освобождения места.
  • Предотвращает превышение используемой памяти над физической памятью сервера, что приводит к завершению процесса системой после OOM.

maxmemory ограничивает объем памяти, фактически используемый Redis, то есть память, соответствующую статистике used_memory. Фактическое потребление памяти может быть больше, чем параметр maxmemory, будьте осторожны, так как эта память вызывает OOM. Итак, если у вас 10 ГБ ОЗУ, лучше установить maxmemory на 8 или 9 ГБ.

Отдел потребления памяти

Внутрипроцессное потребление Redis в основном включает в себя: собственную память + объектную память + буферную память + фрагментацию памяти.Потребление памяти самим пустым процессом Redis очень мало.Обычно, когда used_memory_rss составляет около 3 МБ, used_memory обычно составляет около 800 КБ. процесс может потреблять память, его можно игнорировать.

объектная память

Объектная память — это самая большая часть памяти Redis, в которой хранятся все пользовательские данные. Все данные в Redis принимают тип данных ключ-значение.Каждый раз, когда создается пара ключ-значение, создаются как минимум два типа объектов: ключевой объект и объект-значение. Потребление памяти объектом может быть просто понято как сумма потребления памяти этими двумя объектами (и такой информации, как истечение срока действия). Ключевыми объектами являются все строки.При использовании Redis легко игнорировать влияние ключей на потребление памяти.Вам следует избегать использования слишком длинных ключей. Дополнительные сведения об объектной системе Redis см. в моей предыдущей статье.Двенадцать изображений помогут вам понять структуру данных и объектную систему Redis..

буферная память

Буферная память в основном включает в себя: клиентский буфер, буфер невыполненных копий и буфер AOF.

Буферизация на стороне клиента относится ко всей входящей и исходящей буферизации TCP-подключений к серверу Redis.

Входной буфер не может контролироваться, максимальное пространство 1G, при превышении оно будет отключено. Кроме того, входной буфер не контролируется maxmemory.Предположим, что экземпляр Redis устанавливает maxmemory на 4G и хранит данные 2G, но если входной буфер в это время использует 3G, предел maxmemory превышен, что может привести к потере данных. значение ключа Knockout или OOM.

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

Буферизация вывода управляется параметром client-output-buffer-limit, формат которого показан ниже.

client-output-buffer-limit [hard limit] [soft limit] [duration]

Жесткое ограничение означает, что как только размер буфера достигнет этого порога, Redis немедленно закроет соединение. Мягкое ограничение и продолжительность времени действуют вместе.Например, если мягкое время равно 64 МБ, а продолжительность — 60 МБ, то Redis закроет соединение, только если буфер длится 60 с и превышает 64 МБ.

Обычные клиенты — это все подключения, за исключением клиентов репликации и подписки. Конфигурация Reids по умолчанию client-output-buffer-limit normal 0 0 0. Redis не ограничивает выходной буфер обычных клиентов.Как правило, потреблением памяти обычными клиентами можно пренебречь, но при наличии большого количества медленных клиенты соединений Эту часть потребления памяти нельзя игнорировать во время доступа, и maxclients можно установить в качестве ограничения. Особенно, когда используется команда с большим объемом вывода данных, и данные не могут быть переданы клиенту вовремя, например, команда монитора, легко вызвать внезапный выброс памяти сервера Redis. Похожие кейсы можно посмотреть в этой статьеНекоторые ямы, на которые Meituan наступила в Redis 3. Использование памяти Redis резко возросло.

Подчиненный клиент используется для репликации ведущий-подчиненный.Главный узел устанавливает отдельное соединение для каждого подчиненного узла для репликации команд.Конфигурация по умолчанию: client-output-buffer-limit slave 256mb 64mb 60. Когда сетевая задержка между ведущим и подчиненным узлами высока или главный узел подключен к большому количеству подчиненных узлов, эта часть потребления памяти будет занимать большую часть потребления памяти.В другой сетевой среде, такой как удаленную среду с несколькими машинными комнатами, чтобы предотвратить переполнение из-за медленного подключения клиента репликации. Существует два типа буферов, связанных с репликацией ведущий-подчиненный: один — буфер вывода от клиента, а другой — буфер невыполненной репликации, описанный ниже.

Клиент подписки используется для функции публикации-подписки.Клиент соединения использует отдельный выходной буфер.Конфигурация по умолчанию: client-output-buffer-limit pubsub 32mb 8mb 60. Когда создание сообщений службой подписки быстрее, чем потребление скорость, выходной буфер будет Генерируется отставание, и пространство памяти переполняется.

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

Имя свойства Описание недвижимости
qbuf Длина буфера запроса (в байтах, 0 означает, что буфер запроса не выделен)
qbuf-free Длина оставшегося места в буфере запроса (в байтах, 0 означает, что свободного места нет)
obl Длина выходного буфера (в байтах, 0 означает, что выходной буфер не выделен)
oll Количество объектов, содержащихся в выходном списке (когда в выходном буфере не осталось места, ответы команд ставятся в очередь как строковые объекты в этой очереди)
127.0.0.1:6379> client list
id=3 addr=127.0.0.1:58161 fd=8 name= \
age=1408 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 \
qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 \
events=r cmd=client

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

127.0.0.1:6379> info clients
# Clients
connected_clients:1
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0

Буфер невыполненной репликации — это многократно используемый буфер фиксированного размера, предоставляемый Redis после версии 2.8 для реализации частичной репликации. Управляется параметром repl-backlog-size, значение по умолчанию — 1 МБ. Существует только один буфер невыполненной репликации для всего главного узла, и все подчиненные узлы совместно используют этот буфер. Следовательно, можно установить большее буферное пространство, например 100 МБ, что может эффективно избежать полного копирования. Подробности о копировании буферов невыполненных работ можно найти в моей старой статье.Подробное объяснение процесса репликации Redis.

Буфер перезаписи AOF: это пространство используется для хранения последних команд записи во время перезаписи Redis AOF. Размер буфера перезаписи AOF не может контролироваться пользователем, он зависит от времени перезаписи AOF и количества команд записи, но обычно он невелик. Подробнее о сохранении AOF см. в моей старой статье.Подробное объяснение Redis AOF Persistence.

Фрагментация памяти Redis

Распределитель памяти Redis по умолчанию использует jemalloc, а дополнительные распределители: glibc, tcmalloc. Чтобы лучше управлять и повторно использовать память, распределитель памяти обычно использует для выделения фиксированный диапазон блоков памяти. Конкретная стратегия распределения будет подробно объяснена позже, но нормальная скорость фрагментации Redis обычно составляет около 1,03 (почему именно это значение). Однако, когда длина хранимых данных сильно различается, следующие сценарии подвержены высокой фрагментации памяти:

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

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

Потребление памяти дочерним процессом

Потребление памяти дочерним процессом в основном относится к потреблению памяти дочерним процессом, созданным Redis, при выполнении перезаписи AOF или сохранении RDB. Объем памяти дочернего процесса, сгенерированного Redis при выполнении операции ветвления, такой же, как и у родительского процесса.Теоретически для выполнения соответствующей операции требуется удвоение физической памяти. Однако в Linux есть технология копирования при записи.Родительский и дочерний процессы будут совместно использовать одну и ту же страницу физической памяти.Когда родительский процесс обрабатывает запрос на запись, он создает копию страницы, которую необходимо изменить для завершения записи. операция, в то время как дочерний процесс завершит операцию записи. Тем не менее, чтение моментального снимка памяти всего родительского процесса во время fork.

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

Но ядро ​​Linux добавило механизм Transparent Huge Pages (THP) в память 2.6.38.Проще говоря, он увеличивает размер страницы.Первоначально страница составляет 4 КБ.После включения механизма THP размер страницы составляет 2 МБ. Хотя это может увеличить скорость ветвления (количество копируемых страниц уменьшается), это приведет к увеличению единицы страниц памяти копирования при записи с 4 КБ до 2 МБ. команды записи, это увеличит объем копии памяти.Оба изменяют содержимое страницы, но единица страницы становится больше, что приводит к чрезмерному потреблению памяти. Например, следующие два журнала потребления памяти при выполнении перезаписей AOF:

// 开启 THP
C * AOF rewrite: 1039 MB of memory used by copy-on-write
// 关闭 THP
C * AOF rewrite: 9MB of memory used by copy-on-write

Эти два журнала относятся к одному и тому же процессу Redis, общий объем используемой_памяти составляет 1,5 ГБ, а количество команд записи в секунду при выполнении дочернего процесса составляет около 200. Когда THP включается и выключается отдельно, потребление памяти дочерним процессом имеет огромное значение. Поэтому, когда THP включен в сценарии с высокой параллельной записью, потребление памяти дочерним процессом может быть в несколько раз больше, чем у родительского процесса, что приводит к переполнению физической памяти машины.

Таким образом, дочерний процесс, созданный Redis, не должен потреблять в 1 раз больше памяти, чем родительский процесс.Фактическое потребление определяется количеством записанных команд в течение периода, поэтому необходимо зарезервировать часть памяти для предотвращения переполнения. И рекомендуется отключить THP системы, чтобы предотвратить чрезмерное потребление памяти во время копирования при записи. Не только Redis, но и машина, на которой развернут MySQL, обычно также отключает THP.

Мой блог, добро пожаловать в игру

Оригинальный текст официального аккаунта WeChat

Справочная статья