Что такое redis server
Redis
Быстрое хранилище данных в памяти с открытым исходным кодом для использования в качестве базы данных, кэша, брокера сообщений или очереди.
Что такое Redis?
Redis (расшифровывается как Remote Dictionary Server) – это быстрое хранилище данных типа «ключ‑значение» в памяти с открытым исходным кодом. Проект возник, когда Сальваторе Санфилиппо, первоначальный разработчик Redis, захотел улучшить масштабируемость стартапа в Италии. Он создал хранилище Redis, которое теперь используется в качестве базы данных, кэша, брокера сообщений и очереди.
Redis обеспечивает время отклика на уровне долей миллисекунды и позволяет приложениям, работающим в режиме реального времени, выполнять миллионы запросов в секунду. Такие приложения востребованы в сферах игр, рекламных технологий, финансовых сервисов, здравоохранения и IoT. Сегодня Redis – одно из наиболее популярных ядер с открытым исходным кодом, в течение пяти лет подряд называемое «самой любимой» базой данных от Stack Overflow. Благодаря быстрой производительности Redis широко применяется для кэширования, управления сеансами, разработки игр, создания таблиц лидеров, аналитики в режиме реального времени, работы с геопространственными данными, поддержки служб такси, чатов и сервисов обмена сообщениями, потоковой передачи мультимедиа и приложений с отправкой сообщений по модели «издатель – подписчик» (Pub/Sub).
AWS предлагает два полностью управляемых сервиса для запуска Redis. Amazon MemoryDB for Redis – совместимый с Redis надежный сервис базы данных в памяти, который обеспечивает сверхбыструю производительность. Amazon ElastiCache for Redis – полностью управляемый сервис кэширования, который ускоряет доступ к данным из первичных баз данных и хранилищ с микросекундной задержкой. Более того, ElastiCache также предлагает поддержку Memcached, другой популярной системы кэширования с открытым исходным кодом.
Подробную информацию об ускорении приложений с Amazon ElastiCache for Redis см. в онлайн-вебинаре Tech Talk.
Преимущества Redis
Производительность
Все данные Redis хранятся в памяти, что обеспечивает низкую задержку и высокую пропускную способность доступа к данным. В отличие от традиционных баз данных, хранилища данных в памяти не требуют перемещения на диск, что сокращает задержку ядра до микросекунд. Благодаря этому хранилища данных в памяти могут многократно увеличивать количество выполняемых операций и сокращать время отклика. В результате обеспечивается чрезвычайно высокая производительность. Операции чтения и записи в среднем занимают менее миллисекунды, скорость работы достигает миллионов операций в секунду.
Гибкие структуры данных
В отличие от других хранилищ на основе пар «ключ – значение», которые поддерживают ограниченный набор структур данных, Redis поддерживает огромное разнообразие структур данных, позволяющее удовлетворить потребности разнообразных приложений. Типы данных Redis включают:
Простота и удобство
Redis позволяет писать такой же сложный код с меньшим количеством простых строк. Redis позволяет писать меньше строк для хранения, использования данных и организации доступа к данным в приложениях. Разница в том, что, в отличие от языков запросов традиционных баз данных, с Redis разработчики могут использовать простую структуру команд. Например, вы можете задействовать структуру хэш-данных Redis, чтобы перемещать данные в хранилище только одной строкой кода. Решение подобной задачи с использованием хранилища данных, не поддерживающего структуры хэш‑таблиц, потребует написания серьезного объема кода для преобразования данных из одного формата в другой. Redis уже оснащен встроенными структурами данных и предоставляет множество возможностей их комбинирования и взаимодействия с данными клиента. Разработчикам под Redis доступны более ста клиентов с открытым исходным кодом. Поддерживаемые языки программирования включают Java, Python, PHP, C, C++, C#, JavaScript, Node.js, Ruby, R, Go и многие другие.
Репликация и постоянное хранение
В Redis применяется архитектура узлов «ведущий‑подчиненный» и поддерживается асинхронная репликация, при которой данные могут копироваться на несколько подчиненных серверов. Это обеспечивает как улучшенные характеристики чтения (так как запросы могут быть распределены между серверами), так и ускоренное восстановление в случае сбоя основного сервера. Для обеспечения постоянного хранения Redis поддерживает снимки состояния на момент времени (копирование наборов данных Redis на диск).
Высокая доступность и масштабируемость
Redis предлагает архитектуру «ведущий‑подчиненный» с одним ведущим узлом или с кластерной топологией. Это позволяет создавать высокодоступные решения, обеспечивающие стабильную производительность и надежность. Если требуется настроить размер кластера, доступны различные варианты вертикального и горизонтального масштабирования. В результате можно наращивать кластер в соответствии с потребностями.
Инструменты с открытым исходным кодом
Redis – проект с открытым исходным кодом, поддерживаемый активным сообществом, включая AWS. Поскольку Redis базируется на открытых стандартах, поддерживает открытые форматы данных и имеет множество клиентов, отсутствует вероятность блокировки поставщиком или технологического тупика.
Как использовать разные структуры данных Redis? Смотрим на примерах
Собрали варианты использования базы данных Redis по различным типам основных структур данных. В каких реальных системах применяют строки, списки, множества, упорядоченные множества и хэш-таблицы Redis?
Что такое база данных Redis
Redis, сокращенно от Remote Dictionary Server, представляет собой резидентное хранилище структур данных типа «ключ — значение». Программу с открытым исходным кодом на языке C написал Сальваторе Санфилиппо, она вышла 10 мая 2009 года под лицензией BSD.
В зависимости от настроек Redis может действовать как база данных, кэш или брокер сообщений. Важно отметить, что Redis — это СУБД типа NoSQL. В отличие от СУБД типа SQL (Structured Query Language), таких как MySQL и PostgreSQL, сервер Redis не хранит данные в строго определенных схемах, то есть в таблицах, строках и столбцах. Вместо этого, он хранит данные в структурах данных, что повышает гибкость системы.
Структуры данных в Redis
Какие типы данных поддерживает Redis? В этой статье мы рассмотрим строки, списки, множества, упорядоченные множества и хэши. Кроме них, поддерживаются и другие типы данных, такие как битовые карты, гиперлоги и геопространственные индексы с радиус-запросами и потоками.
Сообщество написало для базы Redis некоторые графические интерфейсы, но сегодня основным инструментом для пользователей является командная строка. А вот в популярных базах данных SQL пользователи часто предпочитают системы управления с графическим интерфейсом, например: phpMyAdmin для MySQL и PgAdmin для PostgreSQL.
Давайте подробнее рассмотрим типы данных в Redis, примеры их использования и особенности.
Строки Redis
Строки Redis — базовый тип данных, используемый всеми другими структурами данных. Он очень похож на строки в языках программирования, таких как Java или Python. Строки с произвольным типом данных считаются бинарно-безопасными и имеют максимальную длину 512 МБ.
Вот несколько полезных команд для строк Redis:
Сохранить строку ‘john’ в ключе ‘student’:
Удалить строку в конкретном ключе:
Примеры использования строк Redis
Списки Redis
Списки содержат строки, отсортированные по порядку их вставки. Вы можете добавлять элементы в начало или конец списка, что полезно для заданий очереди. Более срочные задания можно поставить перед менее приоритетными. Для вставки элемента в начале строки (слева) мы используем команду LPUSH, а для вставки в конце строки (справа) — команду RPUSH.
Рассмотрим один пример:
Обратите внимание, как команда RPUSH добавляет элемент ‘z’ в конец списка.
Примеры использования списков Redis
Множества Redis
Множества Redis — полезный тип данных, поддерживающий мощные операции, такие как пересечения и объединения. Они никак не упорядочены и обычно используются, когда вы хотите выполнить аудит и увидеть взаимосвязи между различными переменными.
Операции с множествами выполняются достаточно быстро. Независимо от количества сохраненных элементов, добавление или удаление элементов в множество занимает одно и то же время.
Кроме того, множества не допускают повторения ключей или объектов, поэтому многократное добавление ключа в множество просто проигнорируется. Это определяется функцией SADD, которая позволяет избежать дублирования нескольких похожих записей. Атрибут SADD можно использовать для проверки уникальных значений, а также планирования заданий в фоновом режиме, включая задания cron, которые представляют собой автоматизированные скрипты.
Множества особенно полезны для анализа поведения клиентов в режиме реального времени. Представим магазин одежды. Здесь упорядоченные множества Redis с помощью различных сопоставлений дадут точную картину поведения клиентов. Вы можете определить паттерны покупок в зависимости от пола и других характеристик покупателя, узнать, какие модели одежды продаются лучше, в какие часы зафиксированы максимальные продажи каждого товара.
Примеры использования множеств Redis
Упорядоченные множества
Упорядоченные множества Redis — набор строк, в котором элементы упорядочены по номерам. Это одна из самых продвинутых структур данных в Redis.
Такие множества Redis похожи на обычные, только здесь каждому члену множества присваивается особое поле с номером (score). Упорядоченные множества известны высокой скоростью, поскольку вы можете быстро вернуть упорядоченные списки и получить доступ к элементам.
Redis — главное хранилище? Что за хрень?!
Redis это размещаемое в памяти хранилище ключ-значение, обычно используемое для кэшей и подобных механизмов ускорения сетевых приложений. Мы, тем не менее, храним все наши данные в Redis — в нашей главной базе данных.
Сеть полна предупреждений и предостерегающих повествований об использовании подобного подхода. Есть ужасающие истории о потере данных, исчерпании памяти или людях неспособных эффективно управлять данными в Redis, вы, возможно, интересуетесь «О чём вы вообще думаете?». Так вот, наш рассказ, почему мы всё же решили использовать Redis и как мы преодолели все эти проблемы.
Прежде всего, я хотел бы подчеркнуть что большинство приложений вовсе не должны обращать внимания на костыли использованные, что бы пойти таким путём. Это было важно для нашего сценария использования, но мы можем быть граничным случаем.
Redis как хранилище данных
Redis быстр. Когда я говорю быстр, я имею в виду Быстр с заглавной буквы Б. Это по существу memcached с более продуманными типами данных, нежели просто строковые значения. Даже некоторые продвинутые операции такие, как пересечение множеств, выборка диапазонов zset, ослепительно быстры. Есть все поводы использовать Redis для быстроменяющихся активно запрашиваемых данных. Он довольно часто используется в качестве кэша, который может быть перестроен по данным из резервной базы данных. Это мощная замена memcached предоставляющая более продвинутое кэширование для различных видов хранимых вами данных.
Как и в memcached, всё находится в памяти. Redis сохраняется на диск, но он не сохраняет данные синхронно с тем как вы записываете их. Есть две причины из-за которых Redis в качестве главного хранилища — отстой:
— Вы вынуждены умещать все свои данные в памяти, и…
— Если сервер откажет между двумя синхронизациями с диском — вы потеряете всё что сидело в памяти.
Из-за этих двух проблем Redis обосновался в компактной нише в качестве временного кэша для данных которыми вы можете пожертвовать, но не главного хранилища данных. Предоставляя быстрый доступ к часто необходимым данным с возможностью перестроения при необходимости.
Недостаток использования более традиционных хранилищ за Redis заключается в затыке с производительностью этих хранилищ. Вам приходится жертвовать производительностью чтобы убедиться, что данные сохранены на диск. Совершенно нормальная сделка для почти каждого приложения. Вы можете получить великолепную производительность по чтению и «хорошую» производительность по записи. Я должен пояснить, что «хорошая» для меня вполне вероятно может быть безумно быстрая для большинства людей. Достаточно сказать, что «хорошая» производительность по записи должна удволетворить большинство, кроме самых высоко нагруженных приложений.
Я полагаю, что вы можете выполнить запрос на запись в Redis а потом сохраниться при помощи реляционного хранилища, но тогда остаются те же риски падения Redis и потери данных очереди записи.
Что нам нужно?
Moot предлагается как полностью бесплатный продукт. Нам, таким образом, необходимо иметь возможность обрабатывать крупные нагрузки на очень небольшом количестве железа. Если нам нужна куча больших баз данных для форума обслуживающего несколько миллионов пользователей в месяц, то нет никаких способов остаться бесплатным сервисом. Поскольку мы хотим, что бы Moot был и бесплатным и неограниченным, мы вынуждены были оптимизировать до предела.
Мы могли бы просто избежать этого установив какие-нибудь ограничения на бесплатные сервисы и брать деньги за просмотр страниц или постов. Не знаю как вы, но я, в общем, не люблю продукты, которые бесплатны «пока вы не раскрутитесь». Скажем, вы настроили форум, а потом что-то на вашем сайте станет вирусным. Внезапно, вас ошарашат счётом за превышение бесплатного уровня. И вот то, что начиналось как развлечение, из-за внезапной популярности вашего блога о теории заговоров, превращается в ужас грядущего счёта. Вас наказывают за ваш успех. Это то, чего мы хотели бы избежать.
Мы так же могли бы решить монетизироваться размещая рекламу, и позволив себе более высокие эксплуатационные расходы. Это, тем не менее, полностью расходится с нашим базовыми ценностями как бизнеса. По нашему мнению, если кто-то собирается размещать рекламу на вашем сайте, это должны быть вы а не мы. Moot должен предлагаться без условий, ограничений и приписок.
Принимая во внимание всё вышесказанное, необходимо достичь непревзойдённой производительности для постинга и чтения не взирая на инженерные сложности. Это базис для нашей возможности работать. У нас была изначальная цель, чтобы все вызовы API обрабатывались менее чем за 10мс даже под высокой нагрузкой, и даже тогда, когда обрабатываются большие сложные списки или поиски. Redis, очевидно, может обеспечить нам такую производительность, но две большие проблемы никуда не делись: Как, блин, мы сможем использовать Redis, если у нас могут быть сотни гигабайт данных, и что делать с падением сервера?
Что же теперь делать?
Так началось наше исследование способов проектирования с учётом этих ограничений. У нас с самого начала было точное понимание какими будут задачи у Moot, и наших ценностей как компании, поэтому нам повезло иметь возможность обдумать эти особенности до написания первых строчек кода. Я полагаю что эти проблемы были бы чрезмерно сложны, если бы мы решили пойти этим путём, имея множество готового кода.
Все данные в памяти. Блин.
Это самая сложна из двух проблем. Количество памяти, которое может быть на одном компьютере, конечно. Наибольшее количество на EC2 это 244-гигабайтный сервер. Хотя это по прежнему конечный объём, это довольно хороший лимит для начала. К сожалению, при этом ваш 16-ядерный сервер будет использовать только одно ядро для Redis. Что ж, как на счёт добавления по подчинённому процессу Redis на каждое ядро? Тогда у вас осталось по 15 ГБ памяти на каждый экземпляр. Опять фигня! Это плохое ограничение, если вы хотите иметь возможность выжать из сервера мощность. Это не достаточно данных для сервиса хостинга.
Мы решили спроектировать наше Redis-хранилище с самого начала разделённым среди множества Redis кластеров. Мы хэшируем и разделяем данные в блоки содержащие все структуры, относящиеся к данному сегменту данных. Данные сильно разделены с самого начала и мы можем по необходимости создавать новые блоки быстро и просто.
Для разбивки данных мы храним таблици хэшей и адресов примерно так:
Когда поступают данные, мы вычисляем хэш на основе наших требований к связности данных, потом мы проверяем в shards.map был ли он назначен какому-нибудь блоку, и если да — мы можем направить вызовы на тот блок.
Если хэш ещё не приписан к какому либо блоку, мы создаём список доступных блоков множа их в соответствии с весом. Если например выполнить:
Список будет выглядеть как-то так:
После этого мы назначаем случайный блок из списка, сохраняем в карту распределения и идём далее.
Применяя такую схему мы можем легко контролировать сколько данных поступает в блоки, добавлять новые блоки или даже исключать блоки из рассмотрения, если видим, что они заполнены.
Реально мы начали с сотен блоков так что нечего беспокоиться о нагрузке на сервера и ограничениях памяти.
Отдельные блоки остаются очень малыми. Один сервер содержит много блоков в базах данных Redis и, если эти блоки увеличиваются в размерах, мы легко можем разделить базы Redis на независимые экземпляры. Скажем у нас экземпляр Redis с 100 блоками, мы видим, что некоторые блоки увеличиваются в размере и мы разделяем Redis на два экземпляра по 50 блоков каждый. Мы можем точно настроить веса чтобы поддерживать распределение между блоками в реальном времени.
Самая сложная часть, это точно определить то, как вы сегментируете ваши данные. Это очень специфично и наш вариант сегментации, возможно, тема для отдельного поста.
Такая стратегия хранения должна разрабатываться в приложении с самого начала. Часто люди пытаются разделять данные, которые так не спроектированы, в этом то и загвоздка для их использования Redis. Поскольку мы чётко знали, что ограничение памяти будет проблемой, мы смогли спроектировать решение в самом ядре нашей системы управления данными, ещё до того как мы написали хоть одну строчку кода.
Падения сервера
Разобраться с отказами оказалось, смешно сказать, легче. У нас для кластера Redis было 3 разные роли:
— Мастер, где происходили почти все операции на запись,
— Подчинённый, гда происходили почти все чтения,
— Хранитель, выделенный для сохранения данных.
Мастер и подчинённый работают в общем как и любые другие в кластере Redis. В этом нет ничего интересного. Что мы сделали нового, это то что в каждом кластере есть по 2 сервера, используемых в качестве хранителей. Эти сервера:
— Не принимают никаких входящих соединений и не несут никакой нагрузки Redis запросов, кроме простой репликации
— Хранение AOF в ежесекундном режиме
— Ежечасный снимок RDB
— Синхронизируют AOF и RDB в S3
В виду того, что параметры производительности для хранения могут несколько различаться, один сервер хранитель может обработать различное количество блоков. Мы просто запускаем по одному экземпляру на каждый блок, который должен храниться. Другими словами, нет необходимости в отношении 1 к 1 между блоками и серверами с ролью хранителя.
У нас два этих сервера расположены в различных зонах доступности, так что даже если одна из зон выходит из строя, у нас есть работающий актуальный сервер-хранитель.
Таким образом, чтобы нам потерять данные необходим довольно большой отказ в EC2 и даже тогда, мы потеряем только около секунды данных.
Если вы рассматриваете сценарий нарушения связности сети, когда мастер может быть изолирован от подчинённых, его можно нивелировать проверкой репликации подчинённых(установить произвольный ключ в произвольное значение и проверить, обновились ли данные у подчинённого) Если мастер изолирован, мы останавливаем запись: Согласованность и Устойчивость к потере связности за счёт Доступности. Redis Sentinel тоже мог бы помочь нам с этим, но Sentinel был выпущен позже того, как мы реализовали большую часть системы. Мы не исследовали, как Sentinel мог бы вписаться бы в наше уравнение.
Конечный результат
В конце концов, мы смогли построить систему, которая под нагрузкой выполняет вызовы API за приблизительно 2 мс.
Значение 2 мс — при обслуживании нашего самого тяжёлого API-вызова, инициализационного API-вызова.
Многие наши запросы обслуживаются гораздо быстрее ( лайки например часто за 0.6-0.7 мс). Мы можем исполнять 1000 API запросов в секунду на одном API сервере. И для построения страницы требуется один API вызов. В замер включены все наши проверки данных, управление блоками, аутентификация, управление сессиями, соединениями, сериализация JSON и так далее.
Многое из этого заслуга не только ЭТИХ решений для Redis. Есть ещё несколько трюков для того, чтобы система производительно работала под высокой параллельной нагрузкой. Один из этик трюков в том, что почти половина нашего кода написана на Lua и работает прямо в Redis. Это другая вещь, которую в общем говорят не делать. Что касается того, как и почему у нас тысячи строк кода на Lua — подождите следующего поста о нашем применении Redis.
Взгляните на нашу реальную производительность, мы запустились пару дней назад, и получили неплохой начальный всплеск. Мы обслуживали 50 API вызовов в секунду и процессор нашего главного API сервера (мы до сих пор посылаем весь трафик на один) был полностью в простое. Вот графики, начиная с нашего запуска до момента написания поста.
Во время наших пиковых нагрузок всё тихо. Вы можете заметить пару всплесков, когда мы накатывали хотфиксы, но в остальном ни шороха. Более поздние всплески соответствуют обновлениям системы, исправлениям и другим проводимым системным работам. Общая нагрузка так же включает увеличенные накладные расходы на логгирование которое мы вели в период начального бета теста.
Пояснение: я ссылаюсь на API сервер как на замеряемый, так как наш сервер приложений и Redis сервер это одно и тоже. API сервер несёт на себе как несколько блоков, так и приложение. Идея была в том, чтобы маршрутизировать трафик на сервер где в основном расположен этот блок, чтобы воспользоваться unix-сокетами для подключения к Redis. Это позволят избегать излишнего сетевого трафика поэтому нет особого различия между Сервером приложений, Redis мастером и Redis подчинённым. Любой API сервер может обработать любой запрос, просто мы даём гораздо больший приоритет мастер серверу задействованного сегмента данных. Все серверы — серверы приложений, и все серверы — мастера для каких-то блоков и подчинённые для других.
tl;dr
Есть множество причин не использовать Redis как главное хранилище на жёстком диске, но если, по каким-то причинам, ваш вариант использования требует этого, вам необходимо начинать с самого начала. Вам стоит проектировать ваши данные разделёнными и помнить о дополнительной стоимости выделенных серверов хранения.
Redis — высокопроизводительное хранилище данных
Бодрый день, хаброчеловеки!
Что такое Redis?
Redis — это высокопроизводительное нереляционное распределённое хранилище данных. В отличие от Memcached, который может в любой момент удалить ваши данные, вытесняя старые записи новыми, Redis хранит информацию постоянно, таким образом он похож на MemcacheDB.
Чем Redis отличается от существующих решений?
API для работы с Memcached (MemcacheDB) позволяет хранить массивы, но эти массивы будут сериализованы и сохранены как строки, таким образом атомарные операции над такими массивами не возможны.
Redis позволяет хранить как строки, так и массивы, к которым можно применять атомарные операции pop / push, делать выборки из таких массивов, выполнять сортировку элементов, получать объединения и пересечения массивов.
Производительность
110000 запросов SET в секунду, 81000 запросов GET в секунду на Linux-сервере начального уровня (тесты).
Высокая скорость работы Redis обеспечивается тем, что данные хранятся в оперативной памяти и сохраняются на диск либо через равные промежутки времени, либо при превышении определённого количества не сохранённых запросов. Из этого вытекает, что используя Redis, вы можете потерять результаты нескольких последних запросов, что вполне приемлимо для большинства веб-приложений, учитывая, что обращение к Redis по скорости сравнимо с обращением к оперативной памяти. Тем не менее, потерь можно избежать через избыточность — Redis поддерживает неблокирующую master-slave репликацию.
Sharding
Redis, как и Memcached, может работать как распределённое хранилище на многих физических серверах. Такой функционал реализуется в клиентских библиотеках, и к сожалению, «из коробки» этот функционал реализован пока только в Ruby API, однако это не мешает вам хешировать ключ самостоятельно и получать ID сервера, к которому с этим ключом обращаться.
API для PHP доступно как в виде модуля, написанного на C, так и в виде PHP5 класса, который общается с Redis-сервером через сокеты, таким образом не требуется устанавливать модуль.
Кроме того существует PHP5 класс от отечественного разрабочика (с именем, заслуживающим доверия. Я серьёзно.) — IMemcacheClient. (Спасибо DYPA за на водку)
Перспективы развития
Разработка ведётся очень активно, комиты происходят почти каждый день, сейчас доступна версия Redis 0.900 (1.0 release candidate 1), которая очень скоро станет версией 1.0
В ближайшем будущем авторы обещают внедрить разные интересные фичи, в том числе и сжатие данных.
Лицензия и поддерживаемые платформы
Redis — написан на ANSI C и работает на большинстве POSIX-систем (Linux, MacOS X). Это бесплатное открытое ПО под BSD лицензией =)