В хабре не было обзоров на «поиск более быстрой альтернативы Redis» — . Получив достаточно свежий опыт его использования, хочется восполнить этот пробел.
![KeyDB като [потенциална] алтернатива на Redis](/wp-content/uploads/2020/02/9642ef3dc712ad2e6304104facb464b7.jpeg)
Предыстория достаточно банальна: однажды при большом притоке трафика мы зафиксировали значительное снижение производительности приложения (а именно — увеличенное время отклика). В тот момент не удалось провести адекватную диагностику, поэтому позже мы запланировали серию нагрузочных тестов. После их проведения мы обнаружили узкое место: кэш базы данных в Redis. Как это часто бывает, проблему нельзя было решить немедленно и правильным образом — силами разработчиков (изменением логики работы). Включилось любопытство и желание найти обходной путь. Так и появилась эта статья.
Проблематика
О Redis в целом
Как многим известно, Redis — это однопотоковая база данных. Если быть точнее, то она такова в контексте работы с пользовательскими данными. С четвертой версии внутренние служебные операции Redis перешли на параллельное исполнение. Тем не менее, это изменение затронуло лишь небольшую часть нагрузки, поскольку основная работа сосредоточена на пользовательских данных.
На эту тему было сказано множество слов, но разработчики Redis упорно не хотят внедрять полноценную параллельность, указывая на то, что это существенно усложнит приложение и увеличит накладные расходы, а также может привести к появлению новых багов. Их позиция такова: если вы столкнулись с проблемой одноядерности — это ваши проблемы с архитектурой приложения, и необходимо что-то менять в ней. Среди пользователей, впрочем, есть и «другой лагерь» — те, кто уперся в одно ядро и утверждает, что Redis сами создают себе узкое место. В случае реальных больших нагрузок — рано или поздно — неизбежно возникнет эта проблема, что накладывает значительные ограничения на архитектуру и/или вынужденные усложнения в ней.
Не буду высказывать оценку тому или иному мнению. Вместо этого поделюсь нашим конкретным случаем и тем, как мы его решили.
Наш кейс
В един от проектите се сблъскахме с проблема, че разработчиците настроили изключително агресивно кеширане на данни от базата данни (PostgreSQL) с помощта на Redis. Това беше единственият начин, който при резки увеличения на трафика спасяваше самата PostgreSQL и, следователно, приложението.
След серия натоварващи тестове проведохме анализ на ситуацията и установихме, че Redis опира на едно ядро (така нареченото „в полка“), след което следваше бързо влошаване на приложението. „Задушаването“ имаше геометричен прогрес: веднага след като се достигаше лимитът на производителността на Redis, всичко спираше да работи.
Изглеждаше по следния начин:
![KeyDB като [потенциална] алтернатива на Redis](/wp-content/uploads/2020/02/c0f55ca1d9f28f8c305bb74cdc77a84a.jpeg)
От страна на New Relic беше категорично идентифициран проблемът:
![KeyDB като [потенциална] алтернатива на Redis](/wp-content/uploads/2020/02/ce72e290f84560d143f2d6c128358477.jpeg)
А ето и статистиката за операцията get в Redis:
![KeyDB като [потенциална] алтернатива на Redis](/wp-content/uploads/2020/02/31d98a6bb2985cfbe391976e24b8a8a6.jpeg)
След като предоставихме проблема в детайли на разработчиците, се оказа, че „в момента не може да се реши проблема“. Така започнаха търсенията на решение от страна на експлоатацията, като отговорът беше вече споменатата KeyDB.
Въпреки това, преди да преминем към прегледа й, трябва да споменем, че в проекта се използва standalone Redis, тъй като клъстерното решение на базата на Sentinel значително изостава по отношение на латентност. Едно от очевидните решения беше създаването на няколко реплики на кеша: и нека приложението да обхожда навсякъде с балансиране! Но след консултация с разработчиците, бяхме принудени да отхвърлим този вариант поради активния и сложен механизъм за инвалидиране на кеша в приложението. Същият проблем се отнасяше и за шардировката на кеша.
Бърз преглед на KeyDB
В търсене на възможно решение на проблема, открихме . То е форк на Redis, разработен и разпространявано под лиценз BSD. Проектът е доста млад: съществува от началото на 2019 година. Историята му е такава, че авторите също веднъж са се сблъскали с ограниченията на Redis… и решили да направят свой форк. В допълнение на известните проблеми, той предлага и допълнителни възможности, които са налични само в enterprise версията на Redis.
За тези, които искат да се запознаят по-подробно с KeyDB, има добра , която представя СУБД и кратки benchmarks, сравняващи я с нейния „родител“ — Redis.
На първо място, това, което ни привлече в KeyDB, беше потенциалното решение на нашите проблеми, а също така ни интересуваха и някои допълнителни функции. Използването на KeyDB обещаваше следните предимства:
- полна многопоточност;
- пълна и абсолютна съвместимост с Redis (това беше особено важно за нас, тъй като не беше възможно да направим каквито и да е промени от страна на приложението), което също така обещаваше безпроблемна миграция;
- вграден механизъм за резервно копиране в S3 хранилище;
- лесна за внедряване активна репликация;
- интуитивна кластеризация и шардиринг без Sentinel и други помощни софтуер.
Над 3000 звезди и много сътрудници в GitHub също изглеждаха обещаващо. Приложението се развива активно и се поддържа, което е очевидно от комитите, комуникацията в насочванията и затворените (приети) PR. Отговорите от основния мейнтейнер винаги са любезни и бързи. В общи линии, аргументите бяха достатъчни.
Миграция и резултати
Въпреки че проектът за миграция беше своеобразно приключение (заради новостта на KeyDB), нямаше много за губене. В крайна сметка връщането на промените е достатъчно бързо и лесно — благодарение на факта, че цялата инфраструктура е разположена в Kubernetes, а вградените механизми перфектно решават такива задачи.
В общи линии, подготвихме Helm шаблони, преместихме приложението в тестовата среда на новата база данни и пуснахме всичко, като го предоставихме за QA отдела на клиента.
Започна тестване, което продължи около седмица, и не навлязохме в детайлите. Знаем само, че клиентът е проверил стандартните функции на работата с Redis с помощта на PHP драйвера , и проведе QA тестване на потребителския интерфейс. След това получихме зелена светлина: не бяха открити никакви странични ефекти при използването на новия софтуер. Тоест от гледна точка на приложението, всичко остана непроменено..
Следва да се отбележи, че не сме променяли нищо и в конфигурацията: буквално — просто заменихме използвания образ. Същото важи и за мониторинга и експортирането на метрики в Prometheus: работи отлично с KeyDB без никакви корекции. Така че може смело да се каже, че от гледна точка на експлоатацията, това беше просто идеален преход.
Благодарение на всичко това, след преминаването на приложението към новата база данни, можете да не променяте нищо, а като "стабилизационна мярка" - да го оставите в този вид да работи на живо за известно време. Въпреки това, ако искате да видите увеличаване на производителността (или изобщо някакви промени), не забравяйте, че по подразбиране параметърът KeyDB, отговарящ за многопоточността (server-threads), е равен на един, тоест базата данни работи точно така, както Redis..
След преминаването, тестването и известно време на работа с новото приложение (с KeyDB) решихме да повторим натоварвателното тестване с същите параметри, които бяха използвани за Redis. Какви бяха резултатите?..
По графика за потребление на CPU веднага стана очевидно премахването на проблемите с "тавана" на едно ядро: процесът започна да използва наличните ресурси:
![KeyDB като [потенциална] алтернатива на Redis](/wp-content/uploads/2020/02/8a3a168507ef75a8e1cdf69e1d30d996.jpeg)
А впоследствие пробвах да "изморя" приложението и видях потребление до три ядра...
Според показанията на New Relic, уеб приложението като цяло, с подобно натоварване, започна да се държи значително по-адекватно. Някаква деградация на производителността все пак се наблюдаваше, но сравнявайки с подобен график по-горе, можете сами да оцените значителния напредък:
![KeyDB като [потенциална] алтернатива на Redis](/wp-content/uploads/2020/02/f46bf41bd6b8d190f5117d049ed2dce5.jpeg)
Показателят за закъснение на новата база данни (KeyDB) също се влоши, но оставаше в допустимите стойности:
![KeyDB като [потенциална] алтернатива на Redis](/wp-content/uploads/2020/02/b9e0a3103a51707628a9f500dfdd53ad.jpeg)
По следващия график е добре видно, че броят на заявките към самата KeyDB е подобен:
![KeyDB като [потенциална] алтернатива на Redis](/wp-content/uploads/2020/02/0a067239194adb39eb3c3738fa73860e.jpeg)
Обобщавайки тези синтетични тестове, можем да кажем, че както Redis, така и KeyDB показват значителна деградация на производителността в закъснение (40 мс+) при съществен ръст на броя на паралелните връзки (1000+). В нашия случай, уеб приложението успяваше да "сваля" закъснението на Redis и при по-малък брой връзки (400+), въпреки че за KeyDB такова натоварване остана приемливо.
Изводи
Примерно в этом контексте ясно видно, насколько сильно сообщество Open Source влияет на развитие интересных проектов. На просторах интернета я наткнулся на хорошую мысль: «Крупная компания разрабатывает интересный продукт, открывает часть его функций, но важнейшую часть оставляет платной. Сообщество пользуется сервисом, и в какой-то момент кто-то решает создать форк, добавив в него те самые платные функции и сделав их доступными для всех». В этом плане KeyDB — яркий пример.
Что касается самой миграции, она прошла удивительно гладко, и мы не столкнулись с такой значительный прирост в производительности, который можно было бы ожидать, глядя на графики разработчиков KeyDB... Однако это лишь наш индивидуальный случай, где могут быть множество отклонений, включая уже знакомую архитектуру приложения (например, огромное количество команд get в Redis вместо более эффективного варианта агрегированных запросов mget…). Тем не менее, нам удалось добиться положительных результатов, а также реализовать множество полезных функций, которые мы продолжим внедрять в ближайшем будущем.
В общем, KeyDB выглядит многообещающим: по мере получения практического опыта работы с этой СУБД (а опыт еще предстоит накапливать!) и развития проекта, мы рассмотрим возможность его применения и в других случаях.
Тем не менее, данную статью не следует расценивать как руководство (и тем более — призыв) к повсеместному отказу от Redis в пользу KeyDB. Несмотря на наш положительный опыт, очевидно, что это не идеальное решение. Ситуация была специфической: для быстрого решения конкретной проблемы, требовавшей минимальных затрат, это решение оправдало себя. Будет ли KeyDB полезен в вашем случае? По крайней мере, теперь вы знаете, что такая возможность существует.
P.S.
Прочетете също в нашия блог:
- «»;
- «»;
- «»;
- «».
Източник: habr.com
