[Open source, NoSQL, Администрирование баз данных] Как ухаживать за грядкой Redis'а и как сохранить урожай?
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Чуть более года назад мне посчастливилось погрузиться в углублённое изучение Redis. Всё, что я знал про него на тот момент, это две команды — get и set. Примерно в это же время у нас начался плавный переход со Standalone Redis на Redis Cluster.Почитать про переход на кластер можно тут, а сегодня я хочу рассказать о том, что я узнал, о проблемах, которые могут возникнуть, как их отлавливать и что со всем этим делать.Большую часть времени ваша грядка будет работать и ничего плохого не произойдёт, но если не начать за ней ухаживать, то могут возникнуть серьёзные проблемы:
- Невозможность подключиться из-за скопившихся клиентов.
- Неоправданно большое количество соединений по причине некорректной настройки таймаутов или непредвиденной конфигурации клиентов.
- Потеря данных до истечения их реального срока жизни в связи с вытеснением.
- Ненормированное распределение соединений, команд или сетевой нагрузки между нодами кластера.
- Слишком большой коэффициент кеш-промахов.
Проблемы, возможности и искусственные ограниченияКонтроль за использованием командНеосторожные действия клиентов могут серьёзно навредить работе приложения. Мы можем попытаться уменьшить вероятность вреда, и в этом нам поможет встроенный механизм ACL, который разделяет пользователей и их возможности.ACL поставляется с 6 версией Redis. Если у вас нет возможности обновить приложение, то создатели рекомендуют использовать rename-commandЕсли у вас есть необходимость и возможность создавать инструменты для разработчиков, то следует закладывать ограничения на уровне библиотеки, не реализуя опасные команды: flushdb, flushall, keys и т.д.ACLACL (Access Command List) поддерживает не только выборочную блокировку команд, но и заготовленные группы. Если вы уверены что нет никого, кто бы использовал нежелательные команды, то стоит прибегнуть к разделению прав на уровне пользователей.Рассмотрим пример, в нём показано, как может выглядеть файл с заготовленным пользователем cache. У него не будет доступа к ключам, которые не сопоставляются с образцом cache:*, а также отсутствует возможность пользоваться командами, которые могут помешать другим пользователям:
# Пользователь **cache** не должен выполнять долгие запросы и может работать только
# с ключами в пространстве имён **cache:** такая схема поможет избежать чтения
# данных непредназначенных для данного пользователя
user cache -@dangerous -@admin -@slow -@blocking ~cache:* on >password_1
Пользователь admin должен обладать всеми возможностями
Не следует задавать пароль в открытом виде: >password_1
Пользуйтесь sha256 хешем #<hash>
user admin +@all on #cbd908627c922e9c4589ba7ae04d332861462c8300868c3e9f6f5da628cedcb
Как минимум, стоит отобрать выполнение admin-команд у обычных пользователей. Если у вас много различных групп пользователей, которые обращаются к общей базе, и вы не можете разделить данные между разными экземплярами, то стоит задуматься о выдаче личных пользователей под каждую группу.Главная боль — сканирование и поиск по паттернуВо время переезда на Redis Cluster одной из основных проблем стал отказ от поиска по шаблону (KEYS) и не заканчивающегося сканирования (SCAN).Поиск по паттерну выполняется при помощи команды KEYS, которая является блокирующей операцией и выполняется за О(n), где n — количество ключей в базе. Использовать эту команду в production-окружении крайне не рекомендуется, но если воспользовались, то следует отказаться в пользу сканирования.Сканирование (команда SCAN) также выполняется за O(n), где n — переданное клиентом количество строк для чтения за одну итерацию. SCAN не панацея и может оказаться бесполезной альтернативой, ведь если вы не ограничиваете строго выборку максимального значения за одну итерацию, то ничто не мешает появлению внезапных длительных блокирующих запросов (если верить документации, то сканирование 1 миллиона ключей на локальном ноутбуке может занимать 40 мс).При работе с кластером нужно строже всего соблюдать запрет на использование команд KEYS и SCAN, так как все данные будут находиться в одной базе и придётся перебирать все ключи.Решить проблему блокирующего поиска по шаблону можно несколькими способами:
- Если у вас standalone-конфигурация, то поможет разбивка ключей по разным базам. Также можно развернуть отдельную версию Redis, и тогда при использовании SCAN ключи будут перебираться только внутри конкретной базы и только среди необходимого набора ключей.
- В случае с кластерами:
- Если вы не ограничены в ресурсах и избавиться от частого сканирования невозможно, то следует развернуть отдельный кластер под подобные операции.
- Если вы ограничены в ресурсах, то следует пересмотреть способ хранения данных и исследовать все возможности Redis. Быть может, необходимости в поиске по шаблону нет и вы сможете обойтись наименее затратными по сложности командами.
На практике мы используем несколько вариантов в зависимости от ситуации. Пересмотр способа хранения может показаться надуманным решением, но однажды подобный анализ помог выявить мёртвую функциональность, которая больше всего нагружала базу.
КонфигурацияУпомянутые параметры статистики можно посмотреть, выполнив команду INFO.maxclientsОпределяет максимальное количество одновременно подключенных клиентов. Слишком маленькое значение может привести к недоступности Redis'а, клиенты будут получать сообщение об ошибке: max number of clients reached. Если такое поведение и предполагалось, то стоит обратите внимание, какими именно клиентами заполнено пространство. Возможно, это простаивающие соединения. Увидеть количество клиентов, которым было отказано в установлении соединения, можно через параметр rejected_connections.timeoutПо умолчанию timeout установлен в 0, это означает, что сервер не будет закрывать соединения даже после долгого простоя. Такая ситуация может возникнуть из-за неправильной конфигурации клиента, который не закрывает соединения. Привести это может к большому количеству открытых соединений и невозможности подключиться к серверу (при достижении maxclients).Как может выглядеть список клиентов при плохо настроенном клиенте:
id=26490 addr=192.168.0.1:12840 fd=6811 name= age=72920 idle=72635 flags=N db=135 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
id=2430 addr=192.168.0.2:58482 fd=675 name= age=73514 idle=73514 flags=N db=135 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=set
id=2431 addr=192.168.0.3:33384 fd=676 name= age=73514 idle=73513 flags=N db=135 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=mget
Установка этого параметра не избавит вас от некорректно настроенного клиента, но может помочь увеличить время жизни приложения за счёт принудительного обрыва простаивающего соединения.Текущее количество клиентов можно посмотреть в статистике через параметр connected_clients. Следует настроить уведомление, когда значение приближается к максимально допустимому. Также стоит обратить особое внимание на idle-соединения, их наличие поможет выявить клиенты с дефектами. Отдельного параметра, показывающего количество таких клиентов, нет, но посчитать их можно, выполнив команду:
redis-cli client list | grep -v "idle=0" | wc -l
tcp-keepaliveПо умолчанию имеет значение 300, полезен для обнаружения мёртвых клиентов.Если timeout и tcp-keepalive установлены в 0, то соединения могут находиться в состоянии idle до перезапуска сервера.maxmemoryЗадаёт максимально возможное количество потребляемой памяти. Указывать можно как абсолютные значения, так и проценты. Рекомендуется установить ограничение, если на сервере с Redis есть и другие приложения. Тогда Redis не сможет захватить всё свободное пространство. При достижении указанного значения система попытается высвободить память, руководствуясь алгоритмом, указанным в maxmemory-policy:
- volatile-lru — вытеснение недавно используемых ключей, у которых задан срок действия;
- allkeys-lru — вытеснение недавно используемых ключей;
- volatile-lfu — вытеснение наиболее часто используемых ключей, у которых задан срок действия;
- allkeys-lfu — вытеснение наиболее часто используемых ключей;
- volatile-random — удаление случайных ключей у которых задан срок действия;
- allkeys-random — удаление случайных ключей;
- volatile-ttl — удаление ключей, у которых истекает срок действия;
- noeviction — отключает вытеснение, будет просто возвращаться ошибка.
Следить за количеством вытесненных ключей можно в статистике через параметр evicted_keys. Чтобы заметить момент, когда память начинает заканчиваться, стоит настроить уведомления на perc_memory. Этот параметр можно посчитать по формуле:
perc_memory = used_memory / maxmemory * 100
Далее используйте perc_memory в качестве порогового значения, рекомендуется сигнализировать о проблеме, если значение приближается к 85.requirepassУстановка пароля не является обязательной процедурой, и по умолчанию параметр остаётся пустым. Стоит заметить, что отсутствие пароля может привести к потере, компрометации и порче данных, а также к несанкционированному доступу на сервер (https://book.hacktricks.xyz/pentesting/6379-pentesting-redis). Не стоит забывать, что Redis может находиться не только в защищённом от посторонних глаз production-окружении, но и на тестовом стенде, откуда можно получить исходный код вашего приложения.unixsocketЕсли ваше приложение находится на одном сервере с Redis, попробуйте использовать unix-сокеты, это поможет уменьшить задержу.Эффективность использованияВ этом разделе мы не будем рассматривать системные метрики вроде CPU и RAM, а сосредоточимся на внутренней статистике приложения.Здесь представлены не все параметры, часть советов по отслеживанию эффективности уже дана в разделе «Конфигурация».Представленные ниже параметры полезно выводить на графиках чтобы следить за их изменениями.КлючиСтоит отслеживать количество ключей, чтобы видеть всю картину происходящего. Эта метрика поможет заметить аномалии и внезапную просадку, чтобы затем по дополнительным метрикам разобраться в причинах происходящего (будь то вытеснение или штатная ситуация).
➜ ~ redis-cli info keyspace
# Keyspace
db0:keys=4234823493,expires=72334549,avg_ttl=42892
Кэш-промахиЭта метрика покажет, сколько раз запрашивали данные, которых уже нет в хранилище. Вычисляется по формуле:
hit_rate = keyspace_hits / (keyspace_hits + keyspace_misses)
Если значение hit_rate маленькое, то данные слишком рано исчезают, а приложение ожидает их увидеть. Такое может быть из-за истечения срока действия или политики вытеснения ключей в связи с нехваткой памяти (maxmemory-policy). Если Redis у вас используется как кеш перед основным хранилищем, то побочным эффектом станет увеличение задержки в работе приложения из-за необходимости часто обращаться к основной базе данных.
➜ ~ redis-cli info stats | grep keyspace
keyspace_hits:480683
keyspace_misses:65
КлиентыЭта метрика показывает количество клиентов в единицу времени. В случае с кластером и проблемой неравномерного распределения будет заметно, что на какой-то из нод клиентов в разы больше.Клиенты, выполняющие блокирующие операцииОперации над списками (BLPOP, BRPOP, BRPOPLPUSH, BLMOVE, BZPOPMIN, BZPOPMAX) могут приводить к длительным блокировкам. Увидеть количество таких клиентов можно через параметр blocked_clients. Эти команды будут блокировать до тех пор, пока список, с которым они работают, не перестанет быть пустым или пока не отвалятся по таймауту. Настройте мониторинг увеличения этого параметра, если он растёт, то это звоночек, что ваше приложение внезапно может стать медленным.
➜ ~ redis-cli info clients | grep blocked
blocked_clients:5
Большой разрыв между количеством клиентов на нодах кластераКоличество подключений на нодах может отличаться на два порядка и более. Причины разные: клиент, который не закрывает соединение и при первом подключении обращается к «первой» ноде за картой слотов, или неравномерное распределение ключей. Следить за этим поможет комплексный набор метрик ключей и соединений по всем нодам или профилирование кластера и составление отчёта.Пропускная способностьТекущее количество команд — хорошая метрика, позволяющая в реальном времени наблюдать за активностью и доступностью Redis. Количество команд, обработанных за секунду, показывает параметр instantaneous_ops_per_sec. Отслеживая его, можно увидеть аномальное поведение, такое как плавные и резкие падения до нуля, что может сигнализировать о блокирующих клиентах.
➜ ~ redis-cli info stats | grep ops
instantaneous_ops_per_sec:73
Обработка грядки инсектицидамиДля упрощения профилирования конфигурационных файлов была написана утилита insecticide, она поможет упростить и ускорить анализ конфигурационных файлов, найдёт возможные проблемы или даст советы по настройке вашего Redis'а.Подробную инструкцию по установке и использованию вы можете найти в репозитории: https://github.com/city-mobil/insecticideПример использованияРезультатом работы будет отчёт с рекомендацией, причиной и критичностью. Для получения отчёта достаточно передать путь до конфигурационного файла redis.conf:
➜ ~ insecticide --redis-version 6 --config=/etc/redis/redis.conf
Parameter: timeout
[CRITICAL]
Advice: Set timeout
Reason: If timeout equal 0, clients connections won't be closed. They will be in idle status until server will be restart.
Parameter: tcp-keepalive
[CRITICAL]
Advice: For better experience you should use default value: 300 if you don't have any reason for change it.
Reason: This option is useful in order to detect dead peers (clients that cannot be reached even if they look connected). Moreover, if there is network equipment between clients and servers that need to see some traffic in order to take the connection open, the option will prevent unexpected connection closed events.
Parameter: maxmemory
[CRITICAL]
Advice: Parameter maxmemory is not set. Index: 0
Reason: Set variable for Param maxmemory and Index 0
Parameter: appendonly
[WARNING]
Advice: Read this page and make decision: <https://redis.io/topics/persistence>
Reason: Persistence disabled. Your data just exists as long as the server is running
Parameter: loglevel
[WARNING]
Advice: In production use a less aggressive logging policy (notice or warning)
Reason: Many rarely useful info, but not a mess like the debug level
Parameter: requirepass
[CRITICAL]
Advice: Parameter requirepass is not set. Index: 0
Reason: Set variable for Param requirepass and Index 0
ПланыВ ближайших планах — сделать инструмент, который позволит подробно анализировать Redis (в том числе кластер), чтобы выяснить:
- равномерность распределения ключей;
- разницу между количеством клиентов между нодами;
- долгие idle-соединения;
- разницу в размере данных между нодами кластера;
- долю кеш-промахов;
- недавний slowlog.
Подводя итогХочется отметить, что всё индивидуально и эффективность использования зависит от того, какие данные вы храните и насколько они вам нужны. Добиться максимального результата для кеш-сервера, шины данных или постоянного хранилища — это абсолютно разные задачи, и приведённые в статье советы подходят не для каждого случая. Из общих рекомендаций я бы выделил:
- Следите за количеством подключённых клиентов и за библиотеками, которыми пользуются разработчики, проводите аудит сервисов.
- Настройте мониторинг состояния системы в реальном времени: количество команд, кеш-промахов, ключей, нагрузка на сеть, CPU, RAM.
- По возможности ограничивайте использование команд из групп admin, dangerous, slow и blocking.
- Заведите чек-лист и проверяйте redis.conf перед вводом сервера в эксплуатацию.
===========
Источник:
habr.com
===========
Похожие новости:
- [SQL, Microsoft SQL Server, Администрирование баз данных] Управление и оптимизация баз данных в ApexSQL — анонс вебинара
- [NoSQL, MongoDB] Иерархия потребностей по Маслоу при разработке документации (перевод)
- [Open source, Программирование, Управление разработкой, Управление проектами] Открываем доступ к Platform V — опенсорсному суперфреймворку Сбера
- [Анализ и проектирование систем, Администрирование баз данных, Хранение данных] Как из одной базы данных сделать 10 разных, храня только инкременты: обзор решения
- [Системное администрирование, MySQL, Серверное администрирование, Администрирование баз данных] Создаем базу данных MySQL с Ansible (перевод)
- [Серверное администрирование, Администрирование баз данных, Хранение данных, Хранилища данных] Автоматизация в центрах обработки данных
- [Open source, Управление проектами, Монетизация IT-систем, История IT, Финансы в IT] Как Unix-way убивает десктопный Linux
- [Open source, Открытые данные, Звук] Новый владелец Audacity отказался от использования телеметрии после возмущений пользователей
- [Open source, Python, Машинное обучение, Изучение языков] Сам себе Гутенберг. Делаем параллельные книги
- [Open source, Программирование, Scala] SCALA 3 (перевод)
Теги для поиска: #_open_source, #_nosql, #_administrirovanie_baz_dannyh (Администрирование баз данных), #_redis, #_nosql, #_profiler, #_citymobil, #_opensourse, #_golang, #_blog_kompanii_sitimobil (
Блог компании Ситимобил
), #_open_source, #_nosql, #_administrirovanie_baz_dannyh (
Администрирование баз данных
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 04:50
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Чуть более года назад мне посчастливилось погрузиться в углублённое изучение Redis. Всё, что я знал про него на тот момент, это две команды — get и set. Примерно в это же время у нас начался плавный переход со Standalone Redis на Redis Cluster.Почитать про переход на кластер можно тут, а сегодня я хочу рассказать о том, что я узнал, о проблемах, которые могут возникнуть, как их отлавливать и что со всем этим делать.Большую часть времени ваша грядка будет работать и ничего плохого не произойдёт, но если не начать за ней ухаживать, то могут возникнуть серьёзные проблемы:
# Пользователь **cache** не должен выполнять долгие запросы и может работать только
# с ключами в пространстве имён **cache:** такая схема поможет избежать чтения # данных непредназначенных для данного пользователя user cache -@dangerous -@admin -@slow -@blocking ~cache:* on >password_1 Пользователь admin должен обладать всеми возможностями Не следует задавать пароль в открытом виде: >password_1 Пользуйтесь sha256 хешем #<hash> user admin +@all on #cbd908627c922e9c4589ba7ae04d332861462c8300868c3e9f6f5da628cedcb
id=26490 addr=192.168.0.1:12840 fd=6811 name= age=72920 idle=72635 flags=N db=135 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
id=2430 addr=192.168.0.2:58482 fd=675 name= age=73514 idle=73514 flags=N db=135 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=set id=2431 addr=192.168.0.3:33384 fd=676 name= age=73514 idle=73513 flags=N db=135 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=mget redis-cli client list | grep -v "idle=0" | wc -l
perc_memory = used_memory / maxmemory * 100
➜ ~ redis-cli info keyspace
# Keyspace db0:keys=4234823493,expires=72334549,avg_ttl=42892 hit_rate = keyspace_hits / (keyspace_hits + keyspace_misses)
➜ ~ redis-cli info stats | grep keyspace
keyspace_hits:480683 keyspace_misses:65 ➜ ~ redis-cli info clients | grep blocked
blocked_clients:5 ➜ ~ redis-cli info stats | grep ops
instantaneous_ops_per_sec:73 ➜ ~ insecticide --redis-version 6 --config=/etc/redis/redis.conf
Parameter: timeout [CRITICAL] Advice: Set timeout Reason: If timeout equal 0, clients connections won't be closed. They will be in idle status until server will be restart. Parameter: tcp-keepalive [CRITICAL] Advice: For better experience you should use default value: 300 if you don't have any reason for change it. Reason: This option is useful in order to detect dead peers (clients that cannot be reached even if they look connected). Moreover, if there is network equipment between clients and servers that need to see some traffic in order to take the connection open, the option will prevent unexpected connection closed events. Parameter: maxmemory [CRITICAL] Advice: Parameter maxmemory is not set. Index: 0 Reason: Set variable for Param maxmemory and Index 0 Parameter: appendonly [WARNING] Advice: Read this page and make decision: <https://redis.io/topics/persistence> Reason: Persistence disabled. Your data just exists as long as the server is running Parameter: loglevel [WARNING] Advice: In production use a less aggressive logging policy (notice or warning) Reason: Many rarely useful info, but not a mess like the debug level Parameter: requirepass [CRITICAL] Advice: Parameter requirepass is not set. Index: 0 Reason: Set variable for Param requirepass and Index 0
=========== Источник: habr.com =========== Похожие новости:
Блог компании Ситимобил ), #_open_source, #_nosql, #_administrirovanie_baz_dannyh ( Администрирование баз данных ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 04:50
Часовой пояс: UTC + 5