Показаны сообщения с ярлыком couchbase. Показать все сообщения
Показаны сообщения с ярлыком couchbase. Показать все сообщения

пятница, 16 мая 2014 г.

Session storage benchmark

           Уже очень давно я бьюсь над проблемой: а как настроить Redis "чтобы оно работало". Казалось бы - хранить сессии в Redis - что может быть проще ? Это ведь как раз то что доктор прописал.  Хер там был.  Чем больше я еб#### с этим редисон, тем больше я начинаю ненавидеть все что начинается на NoSQL.  Для меня скоро NoSQL будет синонимом - "не работает".  Взять к примеру Couchbase/CouchDB. На бумаге все прекрасно. Казалось-бы, вот оно счатье - настало. Все само реплицируется, партиционируется и масштабируется. Хер там был. Оно просто не работает. Если при более-менее высокой нагрузке  начнется решардинг - наступает пиз###. Производительность всего кластера настолько деградирует что это равносильно даунтайму.  И это не говоря о случайных спадов в производительности - когда у нг внутри какой-то буффер переполняется и время ответа ни с того ни с сего увеличивается в 10 раз. А через минуту все снова охеренно. Но за минуту ты легко можешь отхватить и 10 и 100 тысяч запросов.  Какая-то часть из них умрет по таймауту и покажет 50x ошибку пользователю. В погоне за успехом в кратковременных бенчмарках, которые любят размещать в блогах  - NoSQL писатели такую херню делают, что диву даешься.  Неужели они не понимают что гарантированная производительность(пусть немного медленне) - это гораздо лучше чем 100000 запросов в секунду в пике,  с временными спадами до 10 запросов в минуту.  
             Итак вернемся к нашему редису.  На первый взгляд идеальное решение для хранения сессий. Но есть маленькое но.... Он однопоточный.... То есть если вы запустили какую-нибуть тормозную команду - например KEYS, то до тех пор пока команда не выполнится - ни один коннект не будет обработан. Просто такой маленький stop the world.  Представьте что у вас 10GB база и кто-то запустил KEYS по ошибке... сколько у вас коннектов отвалится по таймауту ?? Они еще зачем-то прикручивают туда Lua интерпретатор... Если у вас однопоточный сервер  с c event-loop, то все что сложнее чем GET/SET вам просто противопоказано!  Иначе забыть можно про сколько нибуть предсказуемое время ответа. 
                Вторая проблема - RDB checkpointing.  Документация нам говорит что раз в какое-то время Redis форкает процесс, который его сохраняет на диск. Вроде все охеренно... сохранение происходит в отдельном процессе... никто никому не мешает...  Но как то честно говорит документация - на время создания снапшота все блокируется...  То есть раз в какое-то время ваш Redis будет подвисать... Причем чем больше ваша база - тем больше подвисание. Вот подвисли мы на 30 секунд - а кто запросы то обрабатывать будет ?? Хуй в пальто ? Что тут еще скажешь ... Прелестно блять, просто прелестно.  Писали писали приложение, только оно начало работать... база выросла - и на тебе жопу. И что хочешь тут то и делай. Broken by design.
               В общем вы поняли что Redis идеален если у вас маленькая база и нет нагрузки. Во всех остальных конфигурациях - ебитесь как хотите. Но спрашивается - если у вас 10 сессий в час, и 3 хромых пользователя онлайн - нахера вам Redis ??? Храните сессии в файлах и не выпендривайтесь. 
              Итак, слюни в сторону - что дальше то делать? Если Redis то работает, то не работает - нужно поставить рядом два редиса и переключатся между ними... Выглядит все просто... но чтобы поддерживать оба редиса синхронизированными - нужно настроить репликацию между ними... Если вдруг один Redis задумался - нужно переключится... И при этом не забыть развернуть репликацию... мы же не можем в slave писать... Причем переключить нужно оба сервера... а если первый сервер в серьез "задумался" ?? Он и на пинги -то не отвечает, а ты хочешь чтобы он на более сложные команды ответил... В общем мы рискуем получить рассинхронизацию - когда оба сервера будет считать себя master, а ты потом разбирайся - что и куда у тебя записалось... В общем классический split brain.  Легкая на первый взгляд задача оказалась тем еще гемороем.  Для того чтобы решить эту проблему Redis предлагает Sentinel. Охеренно, подумал читатель. Но не тут-то было:
Sentinel is currently developed in the unstable branch of the Redis source code at Github. 
         Документация честно говорит - что Redis Sentinel - он ... ну как сказать... не так уж прям чтобы очень стабильный был. Но то и понятно, задача которую он решает - не из простых. Поставили мы два редиса, два Sentinel... но тут мы понимаем что для того чтобы избежать split brain нам нужно минимум 3 инстанса .... окей, это тоже решаемо... подогнали еще сервак, воткнули туда редис с сентинелем и ждем. Чего ждем непонятно. Ну переключит Sentinel мастера на другую ноду, но нашему приложению-то кто об этом скажет ? Либо нужно писать "умных клиент", который сам будет из 3-х предложенных инстансев выбирать мастера.... либо ставить load balancer....  с недавних пор (версии 1.5.x dev) HA proxy умеет выбирать мастера из N-бэкендов. Вообще пользуюсь случаем хочу сказать - HA proxy охеренен. Просто ты работаешь и чувствуешь как там все продумано, все до мелочей. Начиная от конфигурации и заканчивая логгированием. Сразу видно что HA proxy писался для решения реальных задач в production системах, а не как очередная гиковская игрушка. Dev версии HA proxy более стабильны чем большинство релизных версий современного софта.  Сразу видно чо писал его человек старой закалки с огромным опытом. Кстати для тех кто не знает - на сайте HA proxy есть коллекция довольно занимательных статей.   В общем при правильной настройке HA proxy - то единственный компонент получившейся системы, за который я могу быть спокоен. 
             Итак, вернемся к нашим котятам. Теперь получившееся нечто надо протестировать. По возможности реальной нагрузкой... Для этих целей и был написан session_storage_bench. Этот скрипт пытается в точности эмитировать поведение php-fpm процесса: заблокировал сессию, прочитал, подождал 200ms (время обработки запроса), записал обратно, снял блокировку. Он умеет разговаривать с memcache(и другими memcache-like системами, такими как Couchbase) и с Redis. Думаю не составит большого труда написать адаптер для любого другого хранилища сессий. Также он умеет имитировать persistent коннекшены.  В общем - пользуйтесь :-)          

понедельник, 9 сентября 2013 г.

Couchbase

     Поскольку на текущем месте работы у нас используется Couchbase, я решил познакомиться с ним по ближе.  Скачал себе architecture review. Ну и покурил его на досуге. Мое первое впечатление:
  1. Интересная архитектура
  2. Отличная документация
  3. Прямо из коробки идет отличный web интерфейс -  через который можно смотреть статистику по кластеру, изменять настройки на лету. В общем приятно работать с таким софтом. 
Но есть в нем вещи которые меня очень насторожили. Уж очень гладко все на бумаге - nothing share architecture, master-master replication. Хочешь в разных датацентрах - пожалуйста, вот тебе XDCR репликация. Прям - вот оно, настало счастье программистов, не СУБД а мечта. Но если внимательно почитать документацию то понимаешь - что все построено в расчете на оптимистичный сценарий. Если все хорошо с серверами - то и мы вроде как работаем,  а если с серверами какая хрень случается - то уж как получится...
  1. По умолчанию сервер отправляет клиенту подтверждения - не дожидаясь пока данные будут реально записаны на диск. Он кладет данные в некоторый кэш, и ставит в очередь на сохранение. А сохраняться они действительно или нет - этого ты при таком раскладе не узнаешь.
  2. Можно с помощью опции сказать серверу,  чтобы он отправлял клиенту подтверждение только после успешного сохранения данных на диск.  Но вдруг диск сдохнет ? Для обеспечения консистентности нам нужно сохранить данные минимум на две ноды. К сожалению невозможно заставить Couchbase сначала сохранить данные на диск, отреплецировать данные на другую ноду - и только потом отправлять клиенту подтверждение. 
  3. Следующая вещь, которая вызвала у меня кучу вопросов - это auto failover. Да, задумано все круто, это беспорно.  Но меня интересует вопрос - вот упала нода, сколько времени  потребуется кластеру на то чтобы определить это, и перевести реплику в активное состояние ? 2 минуты ? 3 минуты ? 5 ? В документации об этом не слова. С какой частотой Couchbase клиент проверяет cluster map ? Сколько вообще времени пройдет до того момента как данные снова станут доступны ? Хз. Другого ответа нет.
  4. Еще больше вопросов возникает к управлению кластером. Что произойдет если так называемый - orchestrator, нода выбранная управлять кластером - сама двинет кони ? Согласно документации  кластер выберет нового orchestrator,  и все будет замечательно. Но что произойдет с клиентами которые в  этот момент захотят получить cluster map ? Ведь orchestrator - это обычный узел кластера, который также обслуживает определенные partition, и в случае смерти нужно чтобы кто-то перевел реплику в активное состояние, а partition который находился на умершей ноде в состояние dead.  Вообще интересный момент - как сказать сдохшей ноде, что она должна перейти в состояние dead ? Разговор с мертвецами - это под силу только Couchbase. И вообще, может нода вовсе и не умирала, а умер коммутатор в который она была воткнута ? Потом коммутатор сменили, и у нас в кластере внезапно оказалось две активных реплики одного раздела.  В общем не очевидно как будут разруливаться такие ситуации.
  5. Если продолжить фантазировать на тему сдохнувшего свича, то легко можно смоделировать ситуацию когда мы получаем классический split brain. Если внезапно кластер распадается на 2 подсети - в каждой из них будет выбрано по одному orchestrator. И каждый  из них будет думать что он то и есть настоящий,  и будет раздавать на право и на лево свою cluster map, и писать данные данные... а что потом потом делать  с этими двумя кластерами и как объеденить данные с них - это будет головоломка для dev-ops.
  6. Что еще меня повеселило - это открытие в области алгоритмов, сделанное программистами Couchbase. Встречайте - B-Superstar index, новое слово в алгоритмике. И не важно что вот уже лет 50 никто ничего нового в этой области не придумал - они новый тип индекса изобрели. Просто маркетинг головного мозга.

Можно конечно сказать что я придираюсь, и Couchbase как-то обрабатывает все эти ситуации - но реальность показывает что это не так. С нашим небольшим Couchbase кластером из 3-х нод не так давно произошла "пренеприятная" история. Он ушел в даун (или сделал вид что ушел в даун) и никто из админов долго не мог сказать что с ним стряслось.  Я процентов на 90 уверен что без косяков админов там не обошлось, но по факту - одна из трех нод умерла, одновременно с этим начался процесс  репликации и производительность кластера настолько деградировала что пациент был скорее мертв чем жив.