Pull to refresh

Comments 74

>проблема больших данных
Больших это сколько терабайт?

>Не использовать персистентность редиса
Т.е. вы надеетесь что все целиком никогда не рухнет, а если рухнет у вас будет даунтайм на время заполнения редисов?

1) В нашем случае это несколько сотен Гб, для In-Memory это не мало.
2) Если ВСЕ целиком рухнет, да, у нас будет даунтайм, с этим не поспоришь, но наш способ позволяет избавиться от единой точки отказа ( в статье эту тему не затронули ).
А если попробовать увеличить производительность за счет более производительных дисков?
Активировать вновь персистентность на SSD дисках при этом заставим Redis работать в режиме Master/Slave все данные добавляете/обновляете в мастере, а получение данные выполняете с Slave?

И еще вопрос — у вас обновление информации в Redis идет напрямую из приложения или через сервер очередей?
1) В общем случае персистентность в редисе работает, я бы только не рекомендовал режим, в котором Redis форкается перед сбросом данных. В нашем случае, за ненадобностью, проще отказаться от этой функции.

2) И так и так. Если не секрет, то почему это важно?
интересуюсь потому что мы сейчас сами стоим перед выбором технологии
У нас архитектура позволяет многие сообщения положить в очередь и уже на бэкэнде в сервисах их обработать и там же идет большая часть обращений к редису. Но я считаю, что редис крайне быстр и к нему можно ходить и с фронта на прямую.
ну вот мы тоже хотели на монго стоить архитектуру, но теперь думаю
Монга и редис не взаимо исключаемы, а скорее дополняемы.

В редисе доступны только запросы по ключу т.е. вы не можете сделать выборку всех товаров к примеру с категорией 5 или ценой больше 1000.
Можно поддерживать set, в котором будут перечислены все id товаров категории 5 или ценой больше 1000. =)
Если необходимые выборки заранее известны и их не очень много, то это вполне решение.
А тип set разве не подходит? На сколько я помню на нем в редисе даже фасетчатый поиск строят.
Правильно ли я понимаю, что в вашем случае чисто в set хранить данные не получиться и нужно будет продублировать данные из других типов? Как результат возникает проблема с необходимость увеличить объем ОЗУ кластера + вопрос неконсистентности данных ввиду дублирования?
Да, правильно. Но я хотел донести основную идею: «Если у вас саморез, то не надо тянуться за молотком, нужно взять отвертку». Редис — это узкоспециализированная БД, ей не стоит заменять базы данных с «богатым инструментарием».
А чем второй режим лучше? Он append only.
Кстати, и это немаловажно, у редиса шикарная документация. И вот тут в деталях описаны плюсы и минусы различных подходов обеспечения персистентности.

Лично меня крайне сильно смущает в первом подходе необходимость форка. Пока форкается процесс, он не работает + копирует всю память, это приводит к тому, что реально можно использовать только половину оперативной памяти сервера, т.к. если занять больше, то редис при форке упадет.
В современных GNU/Linux системах fork-нутый процесс не копирует полностью память, а делает copy-on-write. В итоге объём потребляемой памяти при fork будет зависеть только от скорости обновления данных.
Могу лишь поделиться нашим опытом: в итоге либо сильно падает время ответа на время форка, либо процесс полностью лочится.
я бы только не рекомендовал режим, в котором Redis форкается перед сбросом

Почему? В смысле, в чем там подводный камень.
Чуть выше писал, что у редиса отличная документация.

Отвечая на ваш вопрос, я писал о режиме RDB, который на момент форка перестает обслуживать запросы. В документации сказано, что это происходит от миллисекунд до секунд. В нашем случае даже это критично, хотя мы наблюдали и более долгие остановки.
Почему ничего не рассказали про данные? Что у вас в хадупе, что в редисе, как они туда-сюда перетекают? Как происходит решардинг, когда падает один из редисов? Плавно автоматом или принудительно вся база рехешится?
Я так понял, у вас рекомендации одни для всех, или для каждого юзера свои? То есть вы просто парсите товарные выгрузки, пихаете их в память и отдаёте на каждом запросе пользователю? Или есть какая-то сверсекретная магия?
Почему ничего не рассказали про данные?

Что Вам могло быть интересно про данные? Постараюсь в коментариях ответить.

Что у вас в хадупе, что в редисе, как они туда-сюда перетекают?

С хадупом работают мои коллеги, но я постараюсь ответить на ваш вопрос.
Для хадупа связь редис-хадуп односторонняя. Хадуп только заливает данные в редис, но не читает их от туда.
На сколько я знаю, никаких специальных средств для работы с редисом из хадупа не применяется, к примеру для заливки данных из спарка применяется просто драйвер jedis + модификация для поддержки нашего шардинга.

Плавно автоматом или принудительно вся база рехешится?

Постучим по дереву, нам пока такое пригодилось однажды, и мы в ручном режими изменили конфиги и перезалили данные.

Я так понял, у вас рекомендации одни для всех, или для каждого юзера свои?

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

То есть вы просто парсите товарные выгрузки, пихаете их в память и отдаёте на каждом запросе пользователю? Или есть какая-то сверсекретная магия?

Мы отдаем не товарную выгрузку, а рекомендации к товару, т.е. к этой футболке подойдут вот эти кроссовки, поэтому некоторая магия все-таки есть.
Не буду рисковать вдаваться в детали не относящихся к теме статьи.
Нет, почему-то прошли мимо. Может подойти для наших задач?
В своё время использовали для массового складирования данных от клиентов и последующего извлечения после простого map-reduce. Очень понравилось кеширование map-reduce – время получения ответа практически мгновенное. Еще всё прекрасно с горизонтальным масштабированием – просто устанавливается еще один сервер и при настройке указывается, что надо подключаться к имеющемуся (как в одном ДЦ, так и в разных). На чтение/запись скорость отличная для нас была (точные цифры сказать уже не могу — не помню). Из нюансов – для совсем мелочи не подходит, так как по дефолту берёт себе под кеши от 4Гб памяти :)

Вообще, достаточно интересный продукт, обязательно посмотрите.
Спасибо, обязательно изучим вариант.
Подниму старую тему. Удалось пощупать? Если да, то на сколько понравилось?
Почему вы пишите что Redis хранит только текстовые данные? Его строки — binary safe. Можно спокойно сохранять любые бинари. Например JSON можно легко заменить на MessagePack например у которого огромное количество binding-ов под самые разные платформы и хорошая скорость сериализации.
Интересная мысль, спасибо, обязательно изучим.
Остаток от деления на число серверов в шарде страдает в случае добавления новых узлов. В вашем случае с перезаливкой это может и не так критично (хотя перезаливка всех узлов наверняка занимает значительное время), но остальным, особенно у кого БД содержит данные (а не просто кэш) это врядли подойдет. Для решения этой проблемы существуют алгоритмы консистентного хэширования, например ketama
Для их задачи с read-only in-memory данными их вариант — лучшее решение. Залить всё в оперативку — это не решардить по медленным дискам, поэтому ничего страшного абсолоютно, даже с полным решардом при добавлении нового сервера.
комент предназначен для поста выше

Как мне кажется, если вы работаете с БД ключ-значение то при обнавлении БД всегда существует состояние в ктором часть ключей обновилось, а часть еще нет.

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

Мы у себя эту проблему решаем следующим образом: мы сначало подключаем новый сервер к сервисам которые заливают данные и они обновляют ключи в старых редисах и заливают данные на новые сервера. Затем мы сообщаем фронтам(сервисам которые читают данные) о том, что появился новый сервер и они начинают читать только обнавленные ключи со всех(старый и новых) серверов.
Еще есть airospike, который дает кластерность из коробки. В продакшене многими уже используется, например у ivi.ru именно airospike.
Круто, я что-то такого зверя на ivi.ru не видел. Расскажите где мы его используем?
Да на него мы смотрели, но смутило, что он платный и не так распространен как redis.
Погодите, а причем тут клиенты Redis и шардинг?
Есть StackExchange, который все базовые вещи делать умеет, а шардингом сейчас занимается сам Redis.
В 3 версии Redis (под Windows уже идет портирование) есть рекомендация указывать в имени ключа данные в фигурных скобках posts_{userId}.
В этом случае, если экземпляр запущен как кластер, он парсит имя, находит эти скобки, берет хэш от данных внутри них и на основе этой информации выбирает нужную ноду и решардинг при добавлении новых узлов происходит автоматом.
1) А почему нет? В статье пример: «как задачу шардинга решить только через клиент».
2) StackExchange: мы обязательно изучим этот драйвер и его возможности, но на момент, когда мы делали выбор БД, еще не было стабильной 3-й версии редиса и не было StackExchange-драйверов.
Только как всегда, есть свои проблемы.
Например, есть команда MGET, которая возвращает множество значений по множеству ключей.
В обычном Redis, который запущен как кластерный, она будет работать некорректно, если значения лежат на разных шардах, но о, чудо, она работает отлично, если у вас Enterprise версия Redis (redislabs). Ну вы поняли…
Отличное предостережение :)
В нашем случае драйвер правильно группирует запросы и отправляет на нужный редис.
А вместо самописного шардинга вы рассматривали twemproxy github.com/twitter/twemproxy? У самого проблемка с шардингом возникла — сначал тоже хотел сам написать, но потом осознал что чего-это я тут напрягаюсьсам и нашел готовое внешнее решение. Пока только 5 дней работает в продакшене но я доволен :)
У нас было несколько итераций поиска решения этой задачи, но именно этот прокси, по-моему, мы не исследовали. Если будут проблемы — обязательно отпишите в этот тред.
тьфу тьфу тьфу надеюсь не будут ) но если будут проблемы отпишу обяззательно
Оно, кажется, так и не научилось использовать sentinel.
там собственно свой фэйловер имеется по настраиваемому таймауту и возвращение для своих нужд полне хватило
Зашел сюда, чтобы написать про твемпрокси. Кушаем — ненарадуемся.
Твемпрокси ставится рядом с клиентом. И внутри себя умеет выкидывать сбойные сервера редиски или на время или навсегда.
«Рядом с клиентом» в смысле клиент — бэкэнд (т.е. какой-то конкретный сервер), либо клиент — приложение. И во втором случае «случай падения сервера с twemproxy» нет, потому что в этом случае его клиент, приложение, тоже лежит?
Ничего не мешает упасть процессу на сервере(на том где клиент), так что это все еще SPOF. Придется городить самим high availability этой прокси.
Ничего не мешает упасть и процессу вашего приложения или серверу с приложением целиком, так что пока у вас один сервер приложения это все-равно единственная точка отказа. Если серверов приложения у вас больше — все хорошо в любом случае. Упал сервер или прицесс приложения или процесс твемпрокси — не важно. Процессы поднимутся апстартом(или что там у вас), сервер поднимется админом и все будут счастливо жить дальше.
Вы правы. Фронтов больше чем один поэтому не страшно падение одного из них.
Клиент — клиент редиски т.е. бэкэнд приложения (или кто там у вас клиент редиски). И падения сервера с твемпрокси нет, потому, что в этом случае, скорее всего, упал весь сервер.
И еще 5 копеек: маленький баш скрипт да или монит можно думаю — проверяем каждую минуту — процесс запущен — круто, если нет — убили процесс и стартанули заново (тут еще на всяк случай убить пид файл для надежности )
Обычно, в операционной системе уже есть средста для этого.
У нас есть что-то подобное и где-то даже применяется, но из-за того, что все сервисы задублированы, мы предпочитаем после падения посмотреть последние записи в логе, а уже потом перезапускать.
Есть вопрос если давно пользуете twemproxy сколько он зажирает ресурсов при длительном процессе использования месяц-пол года? А то я на вский случай взял large instance ec2 под него и смотрю как-то у меня пока нет необходимости в 8гб озу но кто его знает может разростется
Не могу вам точно ответить, потому что все твемпрокси стоят рядом с клиентами редиски, а по отдельным процессам я память не мониторю, только по серверам. Могу лишь сказать, что проблемм каких то он ни разу не создавал за последние пару лет.
О спасибо большое — как раз задумвался а не добавить ли мне редис сервер к твемпрокси )
:) Говорю же, твемпрокси нужно ставить туда где вы редиской пользуетесь. На сервер с вашим приложением. Рядом с клиентом редиски. А ферму редиски держать отдельно.
Т.е. к примеру у нас 2 севера приложений, 2 сервера с редиской. Получается, что twemproxy тоже два, на каждом из серверов приложений. А они между собой как-то общаются для отслеживания состояния фермы с редиской или каждый из них автономен и сам решает вопрос куда роутить запросы и сам отслеживает доступность серверов фермы?
Да, все верно. Нет, между собой они не общаются, каждый сам по себе. Поэтому, теоретически, возможны ситуации когда один инстанс твемпрокси считает, например, что отвалилась первая редиска, а второй считает что отвалилась вторая редиска. Или еще интереснее, только один из инстансов считает что отвалилась редиска а второй пишет в обе редиски. Разумеется, на практике такое бывает редко и не долго, но лучше всего если ваше приложение будет к этому готово. Вообще, как только у вас больше одного сервера чего угодно (и чтобы вам там не обещали) забудьте о простой жизни, потому что CAP теорема не дремлет а вместе с Мерфи они сделают вашу жизнь насыщенной и увлекательной :)
А по какому алгоритму они ключи распределяют по серверам?
По хэшу, а хеш на выбор (там куча алгоритмов). Ну и можно задать при помощи hash_tag чтобы данные попадали на один сервер т.е. хэш будет считаться не по всему ключу, а только по этому тегу.
т.е. my_key и my_other_key скорее всего попадут на разные сервера, зато my_key{group1} и my_{group1}_other_key попадут на один сервер.
Там есть 3 типа на выбор судя по докам ketama, modula, random. (https://github.com/twitter/twemproxy) distribution:…
Хммм — у меня 5 web серваков и 2 редис сервера — зачем мне ставить 2 twemproxy? Я сделал отдельный сервак для twemproxy и все запросы шлю к нему а он уже решает куда рассылать дальше(собственно как обычный лоад балансер такой получается только с постоянным распределением по ключу ) — или я что-то не верно осознал?
Предлагается ставить не 2, а 5 в вашем случае для того чтобы избавиться от SPOF ( единой точки отказа ).
Все-таки плохой из меня обьясняльщик. Схематически так:
аааа осознал, спасибо за график для тупых) — да имеет смысл
А elasticsearch для этих целей не рассматривали?
Очень проницательно. Мы иногда думаем о таком подходе, но смущает то, что это не общая практика. Скажите, у вас есть опыт такого использования ES? Он масштабируется горизонтально?
Только сейчас обсуждали с коллегой переход в одном крупном проекте с sphinx на elasticsearch. Все круто (ожидаемо). Из особенностей которые я, к примеру, учитываю — Java -> много ОЗУ, много ресурсов. Поэтому в таком контексте это не мой случай. Но у вас-то проблем с ОЗУ нет. С другой стороны, как я понял, у вас и с редиской проблем тоже нет.
Есть ещё довольно мощный и быстрый tarantool (http://tarantool.org/). Его активно используют такие проекты как avito и badoo.
Sign up to leave a comment.