Распределенные системы. Паттерны проектирования - [27]

Шрифт
Интервал

(10  ×   100  все  еще  равно  1000).  Однако,  поскольку  каждый  эк-земпляр  кэша  работает  со  своей  отдельной  частью  данных,  мы  можем хранить там 50 % данных (10  ×  10 из 200 Гбайт). Десяти-кратное  увеличение  объема  кэшируемых  данных  означает,  что  кэш-память используется гораздо более эффективно, поскольку  каждый элемент данных попадает только в один кэш. Роль кэша в производительности системы В главе 5 мы обсудили, как использовать кэш с целью оптими-зации  производительности  для  конечного  пользователя  и  со-кращения  задержек.  Не  была,  однако,  рассмотрена  роль  кэша  в производительности, надежности и стабильности приложения. Проще говоря, важно задать себе следующий вопрос: если кэш  откажет, как это повлияет на ваших пользователей и на работу  сервиса в целом?

Когда  мы  обсуждали  реплицированный  кэш,  этот  вопрос  был  менее  актуален,  так  как  кэш  масштабировался  горизонтально,  то есть отказ одного из экземпляров приводил бы только к крат-ковременным неисправностям. Аналогичным образом рассмо-тренный кэш поддерживал масштабирование в связи с вырос-шей нагрузкой, не влияя при этом на конечных пользователей. В  случае  с  шардированным  кэшем  все  оказывается  несколько  иначе. Поскольку конкретный пользователь или запрос всегда  соответствует  одному  и  тому  же  шарду,  в  случае  его  отказа  кэш-промахи  будут  происходить  до  тех  пор,  пока  шард  не  бу-дет  восстановлен.  Учитывая  временность  нахождения  данных  в  кэше,  такие  кэш-промахи  не  являются  проблемой  сами  по  себе — система должна знать, где взять данные. Однако извле-чение  данных  в  отсутствие  кэша  происходит  намного  медлен-нее, что означает снижение производительности для конечных  пользователей.

106 Часть II. Паттерны проектирования обслуживающих систем Производительность  кэша  выражается  в  виде  коэффициента попадания запросов . Коэффициент попадания — доля запросов,  ответ на которые содержится в кэше. В конечном итоге коэффи-циент попадания характеризует общую максимальную нагрузку  на  распределенную  систему  и  влияет  на  производительность  и мощность системы в целом.

Представьте, что уровень обработки запросов вашего приложе-ния поддерживает обработку 1000 запросов в секунду. При  превышении  этого  показателя  система  начинает  воз-вращать  HTTP-ошибки  с  кодом  500.  Если  вы  добавите  кэш  с  50%-ной  вероятностью  попадания,  количество  обрабатыва-емых запросов  возрастет  до  2000  в  секунду.  Так  происходит  потому, что из 2000 запросов одна половина может быть обслу-жена кэшем, а другая — уровнем обработки запросов. В данном  примере кэш довольно критичен для работы сервиса, поскольку  в случае его отказа уровень обработки запросов окажется пере-гружен и половина запросов завершится ошибкой. Именно по-этому  имеет  смысл  оценить  емкость  сервиса  в  1500  запросов  секунду,  а  не  в  полные  2000.  Это  позволит  удержать  сервис  в стабильном состоянии даже при отказе половины экземпляров  кэша.

Производительность системы, однако, не ограничивается коли-чеством обрабатываемых в единицу времени запросов. Произ-водительность, с точки зрения конечного пользователя, также  определяется  задержкой   выполнения  запросов.  Получить  ре-зультат из кэша, как правило, гораздо быстрее, чем сформиро-вать его с нуля. Следовательно, кэш повышает не только коли-чество одновременно обрабатываемых запросов, но и скорость  их обработки. Почему? Представьте, что система обслуживает  запрос  пользователя  за  100  миллисекунд.  Добавим  кэш  с  ве-роятностью попадания 25 %, который возвращает результат за  10  миллисекунд.  Средняя  задержка  обработки  запроса,  таким  Глава 6. Шардированные сервисы 107

образом,  уменьшилась  до  77,5  миллисекунд.  Кэш  не  только  увеличивает  количество  обрабатываемых  в  секунду  запросов,  но и ускоряет выполнение каждого отдельного запроса, поэтому  замедление обработки запросов в результате отказа части экзем-пляров  кэша  или  развертывания  новой  его  версии  беспокоит  нас не слишком сильно. Однако в некоторых случаях влияние  на производительность окажется настолько велико, что запросы  начнут скапливаться в очередях и часть из них будет отклонять-ся по истечении времени ожидания. Никогда не будет лишним  выполнять нагрузочное тестирование сервиса как при наличии,  так и при отсутствии кэша, чтобы понять его влияние на общую  производительность системы.

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