В современном мире облачных технологий и распределённых сервисов производительность и масштабируемость систем играют решающую роль. Особенно это касается компаний, предоставляющих услуги поиска как сервис, где задержки в работе напрямую влияют на опыт конечных пользователей. Algolia, известная своей высокой скоростью и масштабируемостью поискового движка, столкнулась с серьёзной проблемой, которая привела к заметному ухудшению производительности при работе на платформе Microsoft Azure. Корень проблемы кроется в непреднамеренном двойном шифровании данных на уровне аппаратного обеспечения — феномене, который длительно оставался незамеченным и существенно снижал производительность ввода-вывода дисков. Эта история — пример того, как даже мелкие детали в инфраструктуре могут кардинально повлиять на всю систему, и как важно не останавливаться на поверхностных проверках, а проводить глубокий анализ и тесно сотрудничать с поставщиками облачных услуг для поиска эффективных решений.
Algolia — высокопроизводительная платформа поиска, работающая на базе собственного проприетарного движка и предназначенная для обработки больших массивов данных в режиме реального времени. При хранении поисковых индексов используются бинарные файлы, имеющие размер в несколько гигабайт, что обеспечивает минимальные задержки при поисковых запросах. Многооблачная архитектура построена на Kubernetes, что даёт возможность гибко масштабировать инфраструктуру и разворачивать сервисы на разных площадках, таких как AWS, Google Cloud и Azure. Проблемы с производительностью на Azure начали проявляться, когда pods поискового движка демонстрировали непривычно высокие показатели загрузки диска при работе с индексами. Где на AWS и других средах задержки при загрузке индексов считались аномальными уже при превышении 10 миллисекунд, на Azure наблюдались задержки до 400 миллисекунд, а в некоторых случаях пиковые показатели доходили до нескольких секунд.
Эта непредсказуемая и серьёзная деградация тормозила работу поискового движка, особенно заметно это было при частом обновлении индексов — вплоть до четырёх раз в секунду. Каждый переразгруз индексных данных с диска блокировал обработку поисковых запросов, что приводило к росту общей латентности и простой CPU из-за ожидания операций ввода-вывода. Временным решением стала агрессивная масштабируемость — добавление большого количества виртуальных машин для поддержания необходимого уровня обслуживания клиентов. Однако такой подход был крайне затратным и не мог считаться долгосрочным. Поэтому компания приступила к детальному исследованию с целью выявить настоящую причину узкого места.
Для начала сравнили спецификации используемого оборудования. На Azure применялись машины Standard_E16d_v5 с локальными высокоскоростными SSD дисками на SATA. На AWS — инстансы r6i.4xlarge с сетевыми дисками EBS gp3, предварительно настроенными на сопоставимый уровень IOPS и пропускной способности. Несмотря на на первый взгляд схожие параметры, характер дисков и архитектура платформ отличались.
Azure использовал локальные временные (ephemeral) диски, встроенные непосредственно в аппаратную платформу, что в теории должно обеспечивать минимальную задержку ввода-вывода. В противоположность этому, AWS полагался на сетевые SAN-решения с хорошей производительностью. Различия в аппаратной конфигурации не объясняли столь разительный разброс в производительности, что направило внимание исследователей на другие параметры, в частности на шифрование. В обоих облаках применялась нативная шифровка данных на дисках на уровне гипервизора: в Azure — функция Encryption at Host, в AWS — шифрование EBS. Для исключения влияния шифрования на производительность были проведены простые бенчмарки с помощью fio, которые не выявили отклонений.
Однако синтетические тесты не учитывали специфику поведения реальной нагрузки поисковых индексов, поэтому была реализована сложная имитация, максимально приближенная к настоящему сценарию рабочих процессов. Новая нагрузка предусматривала параллельную запись и чтение с диска, отражающие работу компонентов Searcher и Driver внутри поискового кластера. Эти испытания подтвердили, что на Azure задержки ввода-вывода действительно значительно выше по сравнению с AWS. При отключении механизма Encryption at Host наблюдался резкий рост производительности, что подтвердило роль шифрования как фактор значительного торможения. Подробный анализ производительности показал наличие системных блокировок, связанных с работой kcryptd — очереди в Linux, обрабатывающей задачи шифрования и расшифровки.
Тестирование обхода этой очереди с помощью настроек cryptsetup при ручном шифровании дисков дало поразительный результат: задержки почти полностью исчезли, а показатель IO Await снизился с 18 миллисекунд до микросекундного уровня. Ситуация показала, что механизм работы шифрования и его интеграция на уровне ядра и гипервизора вызывают неоправданную нагрузку. Для более детального изучения и привлечения специалистов Azure был подготовлен детальный воспроизводимый сценарий нагрузки с использованием fio, который имитировал параллельный запись и чтение в соответствии с архитектурой поискового приложения Algolia. Данный тест позволил специалистам Microsoft воспроизвести проблему в контролируемой среде и исследовать её причины глубже. Совместная работа с инженерами Microsoft выявила, что начиная с версии 5 и выше, виртуальные машины Azure автоматически включают аппаратное шифрование своих временных дисков.
При одновременном активном Encryption at Host на гипервизоре происходит unintended double encryption — двойное шифрование данных, что приводит к значительному падению производительности. До этого момента такое поведение было малоизвестно и не отражалось в официальной документации. После детального обсуждения и предоставления доказательной базы Microsoft обновила свою документацию, включив разъяснения о последствиях и способах предотвращения двойного шифрования. Были внедрены патчи и изменения, которые позволили устранить проблему на стороне инфраструктуры, что дало возможность Algolia отказаться от избыточного масштабирования и довести производительность до требуемого уровня. Эта история — важное напоминание о том, что производственные узкие места часто могут иметь скрытый, нетривиальный корень.