Как использовать серверы Redis и Memcached для кэширования

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

68 открытий445 показов
Как использовать серверы Redis и Memcached для кэширования

Чем, в первую очередь, руководствуются пользователи, открывая ваш сайт или запуская мобильное приложение? Правильно, скоростью работы! Если страница не загрузится за пару секунд, большинство посетителей просто закроет ее и уйдет к конкурентам.

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

Что такое Redis и Memcached

Разберемся, что представляют из себя обе системы и перечислим их основные различия.

Краткий обзор Redis: структура данных, поддержка персистентности, возможности

Redis — это популярная key-value система хранения данных в оперативной памяти. Она позволяет работать с большим количеством типов данных, среди них списки и множества, битовые массивы, гео-координаты и другие.

Redis нельзя назвать полноценной СУБД, однако его возможностей достаточно для того, чтобы загружать данные из основной базы данных в кэш, получать и передавать информацию, взаимодействовать с пользователем и оперативно реагировать на все запросы. Для Redis доступно несколько вариантов отказоустойчивых конфигураций и подходов, в том числе кластеризация и шардирование.

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

Краткий обзор Memcached: легковесное кэширование в памяти, простота и высокая скорость

Memcached — это сервис кэширования данных в оперативную память, созданный в далеком 2003 году. Большой плюс этого сервиса в том, что скорость его работы не зависит от количества хранимых в кэше данных, а интерфейс максимально прост. Однако есть и существенное ограничение: Memcached позволяет хранить лишь данные типа set.

Основные различия между Redis и Memcached

Сравнивая две системы, в первую очередь еще раз отметим отличия в хранимых данных: серверы Redis поддерживают несколько типов данных, тогда как Memcached способен хранить лишь множества (set). Redis умеет сохранять слепки данных на жесткий диск, для него доступна LRU-политика удаления данных и полное отключение функции освобождения места. А также, в отличие от Memcached, этот сервис поддерживает master-slave репликацию и подходит для создания очередей сообщений.

Настройка Redis для кэширования

Далее разберемся с тем, как установить Redis, задать ему базовые настройки и использовать key-value систему, запуская кэширование базы данных.

Установка Redis и базовая конфигурация

Так как Redis создан для Unix-подобных систем, его установка на Windows Server возможна только через wsl. Когда в вашем распоряжении есть сервер, например, на Ubuntu, установить Redis можно через apt или apt-get.

			sudo apt update - y
sudo apt upgrade - y
sudo apt install redis-server
		

Для проверки успешной установки можно запустить пинг сервера Redis через redis-cli:

			redis-cli
ping
		

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

			sudo nano/etc/redis/redis.conf
		


Можно изменить порт — по умолчанию Redis функционирует на 6379 — дать доступ по сети и задать пароль администратора. Для этого меняем bind 127.0.0.1 -:: 1 на bind 0.0.0.0, раскомментируем строку requirepass и в ней прописываем сам пароль. Например: requirepass averyVERYlongPASSword72349.

После внесения изменения перезапускаем Redis-server:

			sudo service redis-server restart
		

Как использовать Redis для кэширования типа ключ-значение

Благодаря тому, что Redis — достаточно универсальное in-memory хранилище, его можно использовать при кэшировании данных в формате ключ-значение в самых разных проектах. Он подойдет и для хранения API-запросов, и для пользовательских сессий, и для оптимизации работы с основными базами данных, например, Postgresql или MySQL. Каждому элементу в Redis присваивается собственный уникальный ключ, по нему в любой момент можно получить оперативный доступ, изменить или удалить запись. Максимальный объем данных в одной записи-значении — 512Mb.

В Redis доступны разные политики вытеснения, вы можете самостоятельно выбрать принцип, по которому сервер будет удалять ненужные данные при переполнении выделенной ему памяти. Паттерн кэширования также остается «на совести» разработчика.

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

Примеры использования Redis с языками программирования (например, Python или Node.js)

Разберемся, как использовать Redis из Python, добавлять и удалять данные на примере работы с помощью клиента redis-py. Первым делом его нужно установить:

			python -m pip install redis
		

Далее запишем в Redis данные и получим одну из записей по ключу.

Подключаемся к Redis.

			import redis
r = redis.Redis(host='localhost', port=6379, password=None)

		

Записываем данные.

			r.mset({"One": "Eno", "Two": "Owt"})
		

Получаем запись по ключу "Two" и выводим с декодированием.

			r.get("Two").decode("utf-8")
print Two

		

Видим в консоли:

			b'Two'
		


Для удаления используем команду delete.

			r.delete("One")
		

Подробности по использованию redis-py можно найти в официальной документации: этот клиент активно поддерживается и пользуется популярностью у разработчиков.

Настройка Memcached для кэширования

Теперь перейдем к Memcached: разберемся, как его установить и настроить, и поймем, какие ограничения имеются у этого сервиса.

Установка и настройка Memcached

Установка Memcached мало отличается от любого другого сервиса, для нее используется пакетный менеджер. В Ubuntu и Debian — apt, в CentOS или Fedora — yum. Для примера, установка на Ubuntu будет выглядеть так:

			sudo apt install memcached
		

По-умолчанию используется порт 11211, но его можно изменить в файле конфигурации /etc/memcached.conf. Основные параметры заданы буквенными ключами, для некоторых задать дополнительные настройки:

  • logfile/var/log/memcached.log
  • -v и -vv – подробный и очень подробный режимы вывода информации
  • -m – доступный максимум оперативной памяти, по-умолчанию 64Мб
  • -u – системный пользователь, от имени которого запущен сервис
  • -l 127.0.0.1 – IP-адрес, на котором Memcached будет ожидать соединения. По-умолчанию сервис недоступен по сети
  • -p – порт
  • – допустимое количество одновременных подключений
  • -P /var/run/memcached/memcached.pid

После внесения изменения в файл настроек Memcached необходимо перезапустить:

			service memcached restart
		

Принцип работы с ключ-значение в Memcached

Структура Memcached похожа на структуру хранения данных в Redis: каждому значению value присваивается уникальный ключ key. В value может храниться строка или бинарные данные.

Для внесения записи в базу достаточно воспользоваться командой <имя ключа> <флаги (можно оставить 0)> <время хранения в секундах (0 – вечно)> <объем памяти в байтах, зарезервированный для хранения значения>:

			add uni_key 0 0 8
		

После введения этой команды в строку терминала можно ввести значение для хранения.

Для получения данных используется команда get <ключ>, для удаления — delete <key>.

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

Примеры использования Memcached с популярными языками программирования.

Посмотрим, как обращаться к Memcached с помощью Python и какие основные команды можно выполнить.

Для начала установим библиотеку, например, pymemcache:

			pip install pymemcache
		

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

			from pymemcache.client import base
client = base.Client((“localhost”, 11211))
client.set(“key”, «value”)
client.get(“key”)

		

Ниже показан код, который позволит проверить наличие записи в Memcached, и при ее отсутствии запустит функцию updating_key. Предположим, что она задана заранее и получает нужное значение из основной БД.

			result = client.get(“key1”)
if result is None:
    # такого ключа у нас нет
    result = updating_key()
    # записываем полученное значение с нужным ключом в Memcached
    client.set(“key1”, result)

		

Также можно удалить запись по ключу при помощи delete:

			client.delete ("key")
		

Операции set, get и delete — основные способы взаимодействия с memcached из Python, они позволят создавать кэш и пользоваться им по мере необходимости.

Сравнение Redis и Memcached

Для типовых задач кэширования на большинстве проектов подходят оба решения. Однако каждое из них имеет свои особенности, бонусы и недостатки.

Производительность: сравнение скорости работы Redis и Memcached

Считается, что Memcached — самый быстрый сервис, который можно использовать при кэшировании. Однако на практике его производительность и скорость работы на запись вполне сравнимы с Redis. На запись миллиона ключей Memcached тратит около трех миллисекунд, Redis — около 15-ти. А операция считывания данных и вовсе выводит вперед Redis, в котором время практически не растет с ростом числа считываемых ключей, тогда как у Memcached возрастает, пусть и незначительно.

Гибкость данных: поддерживаемые типы данных в Redis и ограничение Memcached

По параметру «количество поддерживаемых типов данных» Redis обходит Memcached на голову, поскольку последний умеет хранить лишь строковые и бинарные значения. А с помощью Redis можно кэшировать помимо этих двух типов еще и списки, множества, упорядоченные множества, битовые поля и геопространственные данные.

Не будем забывать и об ограничениях Memcached, в котором длина ключа ограничена 250 байтами, а размер значения не может превышать 1 Мб по-умолчанию и 128 Мб — при внесении изменений в настройки.

Персистентность данных: плюсы и минусы каждого решения

В описании Redis мы уже упоминали о том, что он умеет записывать данные на жесткий диск. С одной стороны, это обеспечивает их сохранность, с другой занимает ресурсы сервера. Редис — однопоточная система с атомарным выполнением операций, а значит, выгрузка большого слепка данных на диск блокирует все остальные процессы. Для борьбы с этим существует несколько способов, в том числе запуск Redis cluster и разбиение задачи выгрузки данных в Redis на несколько небольших пакетов.

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

Когда использовать Redis и когда Memcached для конкретных задач.

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

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

Примеры использования кэширования в реальных проектах

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

Кэширование результатов API запросов

Мало кто создает API просто так «для галочки». Разработчик обычно предполагает, что запросы в интерфейс будут достаточно многочисленными, а некоторые из них вполне могут повторяться. Или некоторые отчеты будут требовать довольно продолжительных вычислений.

В таких ситуациях для снижения нагрузки на основную БД и ускорения получения ответов от приложения пользуются кэшированием данных в RAM. Это позволит давать быстрый доступ к одним и тем же данным без постоянного подключения к основной базе. А холодный кэш, сформированный из результатов самых тяжелых отчетов, позволит пользователю не ждать их формирования, а получить данные сразу после отправки запроса.

Кэширование сессий пользователей

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

На стороне сервера в таком случае таблица с привилегиями для каждого токена может храниться в кэше Redis или Memcached, так проверка прав доступа будет происходить максимально быстро.

Кэширование баз данных и оптимизация запросов

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

Советы по оптимизации кэширования

Несмотря на всю прелесть использования Redis и Memcached, будем помнить о том, что не все кэширование одинаково полезно. Существует несколько деталей, на которые стоит обратить внимание при проектировании и создании кэша.

Выбор правильной стратегии кэширования (Lazy caching, Write-through, Write-back)

Одна из основных проблем кэширования — возможность того, что данные устареют и не обновятся вовремя. Для борьбы с этим недугом придумано несколько стратегий:

  • Lazy caching или ленивый кэш. Такой кэш просто хранится без всяких проверок до тех пор, пока не устареет, и подходит для редко обновляемых данных. Политика устаревания настраивается для каждого случая индивидуально.
  • Write-through cache или сквозной кэш. Изменение данный проходит «насквозь», задевая сразу и кэш, и основное хранилище.
  • Write-back. В этом случае все изменения вносятся оперативно только в кэш, а в основное хранилище выгружаются по команде или с определенным интервалом.
  • Синхронизированный кэш. При получении запроса на данные, клиент проверяют метку их последнего изменения: если она не совпадает с меткой в основном хранилище, данные обновляются.

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

Настройка политики истечения срока действия кэша (TTL)

Срок действия данных в кэше или срок их «жизни» — это время, в течение которого ключ считается актуальным. Стратегия TTL, или time-to-life — утилитарный подход и в чистом виде может привести к некорректности данных в кэше. Ведь очень редко удается заранее просчитать, сколько именно секунд или дней тот или иной ключ останется неизменным и актуальным.

Поэтому большинство систем, в том числе Redis и Memcached при автоматическом освобождении места ориентируются на частоту использования конкретных ключей и время, прошедшее с момента последнего к ним обращения. Хотя кэширование в Redis поддерживает политику volatile-ttl, при которой первыми удаляются ключи с истекшим или коротким оставшимся TTL.

Управление памятью и избегание переполнения кэша

Оперативная память сервера — величина небесконечная, а для хранения кэша выделяется и вовсе лишь ее часть. Значит, каждому разработчику, использующему кэширование, придется столкнуться с проблемой переполнения. Redis и Memcached выполняют удаление устаревших ключей в автоматическом режиме. Например, Redis при достижении лимита памяти перестанет загружать в кэш новые данные и начинает удаление согласно заданным настройкам, но на чтение продолжит работать в прежнем режиме.

Redis поддерживает несколько подходов к очищению кэша: volatile-lru, volatile-ttl, volatile-random, allkeys-lru и allkeys-random, а в Memcached максимальный срок жизни каждого ключа задается в параметрах при его создании. Обе эти системы чаще всего настраиваются для удаления ключей, которые не использовались дольше всего.

Следите за новыми постами
Следите за новыми постами по любимым темам
68 открытий445 показов