Pull to refresh

Comments 26

UFO just landed and posted this here
Интересное, надо пощупать. Мы сейчас просто через haproxy отдаём тот редис, которого сентинелы выбрали мастером.
Абсолютно согласен, это было отличное решение в свое время. Нам не подошло из-за одного нюанса — латенси на чтении.
Если мы идем в редиску через прокси, или балансер — то теряем очень много времени на доступе по сети (сотни миллисекунд), это при том, что сам редис вычитывает у себя значение из мема за единицы миллисекунд.
Второй момент — на балансер переносится Single point of failure. Т.е. раньше было — падает редиска и ничего не работает, теперь стало — падает балансер и ничего не работает.
Получается, нужно докручивать дополнительную логику (keepalived, lvs etc.) — и опять же, учить клиентов.
В общем — получается очень дорого.
Если поднять такую проксю на каждом клиенте, то и латенси сильно не увеличится, и single point of failure не образуется
> с 6+ нод, смысла флашить данные на диск нет никакого

По две ноды на хеш слот, даже если это разные ДЦ — вполне могут выйти из строя одновременно, или уйти в ребут из-за человеческой ошибки. Нельзя ли включить сохранение на диск на слейвах, а на мастерах выключить?
Отличная идея! Но есть нюанс: к примеру, из кластера вылетел мастер, а слейв (тот, который флашит на диск) стал мастером, и теперь он тормозит весь кластер :/

У редиса есть один юз кейс, про который очень часто забывают - в нем нельзя хранить мега важную инфу, потеря которой чревата (деньги, балансы, файлы, сообщения которые должны быть доставлены).
В нашем случае, если упадет один мастер и его реплика — у нас останется 66,6% данных, и самое худшее, что произойдет — юзера внезапно разлогинит. Кеши и разные другие штуки мы нагенерим, процессы перезапустим.

И еще момент — если у нас балансировка между ДЦ, мы наверное с ними подписывали контракты и гарантии SLA, и если оба ДЦ падают в одно время — наверное ничего работать не будет, не только редиски.

Данные потерять очень легко. Чтобы вашей машине с редисом не было плохо — убедитесь что на железке есть хотя бы 2 ядра — на мейн тред и форк под рдб или aof rewrite, а так же половина свободной памяти (иначе негде будет делать слепок данных для рерайта или снепшота) — не будет проблем с латенси. Помимо этого можно сменить конфигурацию персистности на append only file с синком раз в секунду и снэпшот ночью когда нагрузки нет. Тогда вероятность потерять данные значительно ниже.

не нужен никакой двойной объем памяти, CoW существует с незапамятных времен. Форк процесса редиса наследует его память в состоянии «снапшота», и просто записывает ее на диск, упаковывая в более компактный формат хранения
попробуйте засунуть 70гб данных в редис на машине со 100 гб и потом сделайте BGSAVE, может быть, память забивается по какой-то другой причине, поправьте меня если это так, но по моему опыту цпу на форке 100% (понятно — надо это все пожать) и память тоже забивается абсолютно вся, потом адские свопы на диск… в общем страх
Самая печаль, что и на двойном объёме памяти оно тупит при сохранении на диск.

В смысле сильно возрастает время отклика для приложения
А еще мастер после восстановления не переезжает обратно. Никаких приоритетов нет. В итоге может оказаться что 2 мастера в одной машине/стойке и выход ее из строя гарантированно кладет кластер. То что слевы вот они рядом живые и здоровые никого не волнует.
Можно перевести на человеческий фразу про «сохраняем существующую нерабочую слотмапу»?
Конечно.
Инициализируете переменную, в которую сохраняете значение хеша от команды 'CLUSTER SLOTS'.
Суть в том, чтобы на стороне апликейшна дождаться, когда пересоберется кластер (поменяется слотмапа), и продолжить работу, как ни в чем не бывало.
Спасибо. Скажите, вы замеряли, как долго приходится ожидать, насколько много запросов не завершаются в разумные сроки? Не лучшим ли бывает закончить запрос с какой-нибудь ошибкой и предложить клиенту повторить его?
На запрос существует таймаут (as you wish), а на нашем наборе данных (гигабайты в кластере) пересборка и промутинг занимает примерно 2 секунды.
Само собой, если это аффектит клиента — это маленький таймаут и ошибка типа «Ooops! Internal server error», если это процесс в бэкграунде — таймаут больше, и рестарт в случае таймаута.
У Sеntinel было преимущество. Можно читать с localhost сколько угодно. А в Кластере чтение ограниченно скоростью сетевого интерфеса.
Бывали случаи, когда популярный на чтение ключ увеличивался в размерах ( до 1-2Мбайт). Как вы с таким боролись? Sеntinel это переживал вообще без осечек.
Если есть деньги, то Вы очень правильно выбрали. Aerospike — это очень хорошее продакшн решение.
Кстати, у них есть community edition — 1 инстанс Aerospike.
Отлично. Мы тоже на Aerospike летим. Он не безпроблемный. Но сильно продвинутее, чем redis.
UFO just landed and posted this here
Хотелось бы узнать, чем ваше решение лучше (или может быть хуже) чем использование Riak (https://habrahabr.ru/post/75202/).
Спасибо за статью! Мы как раз сейчас в development-е работаем с single instance Redis-а, а в продакшн придётся, по-видимому, поднимать кластер.

Несколько вопросов:

1) О какой нагрузке в вашем случае идёт речь (например, в одновременных подключениях / в запросах в секунду)? (интересует граница, за которой сингл-инстанс с записью на диск становится неприменим)

2) Итак, я правильно понимаю, что минимальная осмысленная конфигурация кластера — 6 нод: 3 мастера/3 слейва и при сбое мастера он автоматом переконфигурируется для использования соответствующего слейва в качестве мастера?

3) А как выглядит подключение к кластеру в Java-коде, допустим? (Какой драйвер используете, кстати?) В качестве параметра подключения указывается массив IP-адресов?
Постараюсь ответить на Ваши вопросы:
1) К сожалению, метрику по количеству запросов в секунду мы не снимали, но могу сказать, что это сотни конекшнов (в зависимости от нагрузки), которые постоянно что-то пишут, или читают, или слушают канал. По идее, чтобы упереться в ограничение, связанное с IO, необходимо специально начудить (по делофту, если Redis is busy, он скипает операцию записи, и продолжает писать/читать).

2) Абсолютно правильно.

3) Используем форкнутый и допиленный Jedis — https://github.com/xetorthio/jedis
Реализация всех клиентов к кластеру Redis очень похожа: задается массив IP (у нас это Consul, который знает где какие редиски), и клиент загребает всю инфу про кластер с первой по списку рабочей ноды. И дальше, соответсвенно, работает уже со своей информацией о кластере.
Надеюсь преимущества Redis описаны не в сравнении с мемкешем, ибо их всего два: персистенность и возможность манипулировать структурами в значениях.
Ну и есть так же заморачиваться на отказоустойчивость, то можно мемкеш для сессий приготовить ничуть не хуже.
Sign up to leave a comment.

Articles