что такое редиска сантехника

Знакомимся с Redis

Узнаём, для чего эта СУБД нужна и как ею пользоваться.

что такое редиска сантехника. Смотреть фото что такое редиска сантехника. Смотреть картинку что такое редиска сантехника. Картинка про что такое редиска сантехника. Фото что такое редиска сантехника

что такое редиска сантехника. Смотреть фото что такое редиска сантехника. Смотреть картинку что такое редиска сантехника. Картинка про что такое редиска сантехника. Фото что такое редиска сантехника

Redis ( REmote DIctionary Server, «удалённый серверный словарь») — это нереляционная резидентная СУБД, хранящая данные в виде пар «ключ-значение».

От реляционных баз Redis отличается:

что такое редиска сантехника. Смотреть фото что такое редиска сантехника. Смотреть картинку что такое редиска сантехника. Картинка про что такое редиска сантехника. Фото что такое редиска сантехника

Разрабатывает приложения на Java, воспитывает двух котов: Котлин и Монго.

Для чего используют Redis

Redis обычно применяют:

Как начать работать с Redis

Самый лёгкий способ — запустить Redis в docker-контейнере (если не знаете, что это, — добро пожаловать сюда).

Запускаем контейнер командой:

Убедимся, что контейнер запущен:

что такое редиска сантехника. Смотреть фото что такое редиска сантехника. Смотреть картинку что такое редиска сантехника. Картинка про что такое редиска сантехника. Фото что такое редиска сантехника

Затем открываем новую сессию и интерфейс командной строки ( CLI ):

что такое редиска сантехника. Смотреть фото что такое редиска сантехника. Смотреть картинку что такое редиска сантехника. Картинка про что такое редиска сантехника. Фото что такое редиска сантехника

Можно и сразу перейти в консоль Redis:

что такое редиска сантехника. Смотреть фото что такое редиска сантехника. Смотреть картинку что такое редиска сантехника. Картинка про что такое редиска сантехника. Фото что такое редиска сантехника

Вот мы и готовы работать с Redis.

Основные команды

Рассмотрим основные операции на примере хеш-таблиц.

HSET — сохраняет значение по ключу:

В примере выше мы создали объект person1 с двумя полями ( name и age) и соответствующими значениями.

HGET — получение значения по ключу (для определённого поля):

Выше мы получили значение поля name у ключа person1.

HGETALL — получение всех пар «ключ-значение»:

Получили значения всех полей по ключу person1.

HKEYS и HVALS — получение всех ключей и соответствующих им значений:

Как работать с оставшимися структурами данных — смотрите в официальном руководстве.

Транзакции

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

После запуска команды multi интерфейс redis-cli ответил на каждую последующую состоянием QUEUED («в очереди»). Когда мы запустили команду exec, то получили выходные данные каждой команды из очереди.

Отменить транзакцию можно командой discard. Она предотвратит запуск всех команд, ранее поставленных в очередь, — и Redis снова будет выполнять команды в обычном режиме. Чтобы сообщить серверу, что вы открываете новую транзакцию, нужно снова запустить multi.

Важно понимать, что когда команда уже встала в очередь (то есть синтаксически верна), то, даже если она и вызовет ошибку при выполнении, остальные команды выполнятся всё равно. А вот если не встала (невалидна, вызвала ошибку при постановке в очередь), то Redis блок транзакции отклонит, даже не дождавшись exec. И если вы попытаетесь после этого выполнить exec, вам скажут, что транзакция была отклонена из-за предыдущих ошибок.

Как Redis обрабатывает ошибки внутри транзакций, читайте тут.

Механизм подписок

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

Механизм подписок не гарантирует, что сообщение будет доставлено. Мы отправляем сообщение в канал, а кто его примет (и примет ли) — обещать не можем, стоит помнить об этом и не использовать подписки там, где важно обратное.

Итак, клиент подписывается на канал командой:

Источник

Redis на практических примерах

что такое редиска сантехника. Смотреть фото что такое редиска сантехника. Смотреть картинку что такое редиска сантехника. Картинка про что такое редиска сантехника. Фото что такое редиска сантехника
Redis — достаточно популярный инструмент, который из коробки поддерживает большое количество различных типов данных и методов работы с ними. Во многих проектах он используется в качестве кэшируещего слоя, но его возможности намного шире. Мы в ManyChat очень любим Redis и активно используем его в нашем продукте для решения огромного количества задач. Про некоторые интересные кейсы использования этой in-memory key-value базы данных я расскажу на примерах. Надеюсь, вам они будут полезны, и вы сможете применить что-то в своих проектах.

Рассмотрим следующие кейсы:

что такое редиска сантехника. Смотреть фото что такое редиска сантехника. Смотреть картинку что такое редиска сантехника. Картинка про что такое редиска сантехника. Фото что такое редиска сантехника

Кэширование данных

Давайте начнем с самого простого, один из самых популярных кейсов использования Redis — кэширование данных. Будет полезно для тех, кто не работал с Redis. Для тех, кто уже давно пользуется этим инструментом — можно смело переходить к следующему кейсу. Для того, чтобы снизить нагрузку на БД, иметь возможность запрашивать часто используемые данные максимально быстро, используется кэш. Redis — это in-memory хранилище, то есть данные хранятся в оперативной памяти. Ещё это key-value хранилище, где доступ к данным по их ключу имеет сложность O(1) — поэтому данные мы получаем очень быстро.

Получение данных из хранилища выглядит следующим образом:

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

Таким образом, мы запишем данные в Redis и сможем их считать по тому же самому ключу в любой нужный нам момент. Но если мы будем все время писать в Redis, данные в нем будут занимать все больше и больше места в оперативной памяти. Нам нужно удалять нерелевантные данные, контролировать это вручную достаточно проблематично, поэтому пускай redis занимается этим самостоятельно. Добавим к нашему ключу TTL (время жизни ключа):

По истечении времени ttl (в секундах) данные по этому ключу будут автоматически удалены.

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

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

И соответственно массовое удаление данных по массиву ключей:

Очереди

Используя имеющиеся в Redis структуры данных, мы можем запросто реализовать стандартные очереди FIFO или LIFO. Для этого используем структуру List и методы по работе с ней. Работа с очередями состоит из двух основных действий: отправить задачу в очередь, и взять задачу из очереди. Отправлять задачи в очередь мы можем из любой части системы. Получением задачи из очереди и ее обработкой обычно занимается выделенный процесс, который называется консьюмером (consumer).

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

Со стороны консьюмера нам необходимо обеспечить получение задач из очереди, это реализуется простой командой чтения из листа. Для реализации FIFO очереди мы используем чтение с обратной записи стороны (в нашем случае мы писали через RPUSH), то есть читать будем через LPOP:

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

что такое редиска сантехника. Смотреть фото что такое редиска сантехника. Смотреть картинку что такое редиска сантехника. Картинка про что такое редиска сантехника. Фото что такое редиска сантехника

Тем самым мы вычитываем по одному сообщению из очереди. В случае если листа не существует (он пустой), то мы получим NULL. Каркас консьюмера мог бы выглядеть так:

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

Мы рассмотрели базовую реализацию простых очередей, но Redis позволяет строить более сложные очереди. Например, мы хотим знать о времени последней активности наших пользователей на сайте. Нам не важно знать это с точностью вплоть до секунды, приемлемая погрешность — 3 минуты. Мы можем обновлять поле last_visit пользователя при каждом запросе на наш бэкенд от этого пользователя. Но если этих пользователей большое количество в онлайне — 10,000 или 100,000? А если у нас еще и SPA, которое отправляет много асинхронных запросов? Если на каждый такой запрос обновлять поле в бд, мы получим большое количество тупых запросов к нашей БД. Эту задачу можно решать разными способами, один из вариантов — это сделать некую отложенную очередь, в рамках которой мы будем схлопывать одинаковые задачи в одну в определенном промежутке времени. Здесь на помощь нам придет такая структура, как Sorted SET. Это взвешенное множество, каждый элемент которого имеет свой вес (score). А что если в качестве score мы будем использовать timestamp добавления элемента в этот sorted set? Тогда мы сможем организовать очередь, в которой можно будет откладывать некоторые события на определенное время. Для этого используем следующую функцию:

Теперь возникает вопрос о том, как читать эту очередь. Если методы LPOP и RPOP для листа читают значение и удаляют его из листа атомарно (это значит, что одно и тоже значение не может быть взято несколькими консьюмерами), то sorted set такого метода из коробки не имеет. Мы можем сделать чтение и удаление элемента только двумя последовательными командами. Но мы можем выполнить эти команды атомарно, используя простой LUA скрипт!

В этом LUA скрипте мы пытаемся получить первое значение с весом в диапазоне от 0 до текущего timestamp в переменную val с помощью команды ZRANGEBYSCORE, если нам удалось получить это значение, то удаляем его из sorted set командой ZREM и возвращаем само значение val. Все эти операции выполняются атомарно. Таким образом мы можем вычитывать нашу очередь в консьюмере, аналогично с примером очереди построенной на структуре LIST.

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

Блокировки (Mutex)

Mutex (блокировка) — это механизм синхронизации доступа к shared ресурсу нескольких процессов, тем самым гарантируя, что только один процесс будет взаимодействовать с этим ресурсом в единицу времени. Этот механизм часто применяется в биллинге и других системах, где важно соблюдать потоковую безопасность (thread safety).

Для реализации mutex на базе Redis прекрасно подойдет стандартный метод SET с дополнительными параметрами:

где параметрами для установки mutex являются:

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

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

Rate limiter

Достаточно частая задача, когда мы хотим ограничить количество запросов к нашему апи. Например на один API endpoint от одного аккаунта мы хотим принимать не более 100 запросов в минуту. Эта задача легко решается с помощью нашего любимого Redis:

Таким простым методом мы можем лимитировать количество запросов к нашему API, базовый каркас нашего контроллера мог бы выглядеть следующим образом:

Pub/sub

Pub/sub — интересный механизм, который позволяет, с одной стороны, подписаться на канал и получать сообщения из него, с другой стороны — отправлять в этот канал сообщение, которое будет получено всеми подписчиками. Наверное у многих, кто работал с вебсокетами, возникла аналогия с этим механизмом, они действительно очень похожи. Механизм pub/sub не гарантирует доставки сообщений, он не гарантирует консистентности, поэтому не стоит его использовать в системах, для которых важны эти критерии. Однако рассмотрим этот механизм на практическом примере. Предположим, что у нас есть большое количество демонизированных команд, которыми мы хотим централизованно управлять. При инициализации нашей команды мы подписываемся на канал, через который будем получать сообщения с инструкциями. С другой стороны у нас есть управляющий скрипт, который отправляет сообщения с инструкциям в указанный канал. К сожалению, стандартный PHP работает в одном блокирующем потоке; для того, чтобы реализовать задуманное, используем ReactPHP и реализованный под него клиент Redis.

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

В результате такой отправки сообщения в канал, все клиенты, которые подписаны на данный канал, получат это сообщение.

Источник

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 как главное хранилище на жёстком диске, но если, по каким-то причинам, ваш вариант использования требует этого, вам необходимо начинать с самого начала. Вам стоит проектировать ваши данные разделёнными и помнить о дополнительной стоимости выделенных серверов хранения.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *