В 2.7 мы переработали несколько областей взаимодействия между главным демоном и удалёнными агентами. Изменения находятся «под капотом», решая проблемы, которые оказывают влияние в определённых сценариях или при сильно нагруженных конфигурациях с распределёнными индексами и удалёнными узлами.
Асинхронный DNS
Это было своего рода проблемой, особенно для пользователей облачной инфраструктуры. В Linux демон будет использовать getaddrinfo_a() при наличии для асинхронного DNS. Это означает, что нам не нужно активно ждать ответа, вместо этого мы планируем задачу и когда (если) DNS отвечает, продолжаем — либо прерываем через некоторое время по тайм‑ауту. На системах, где getaddrinfo_a недоступен, мы создаём новый поток, посвящённый разрешению DNS (который также работает асинхронно).
Сетевые потоки удалённых агентов
Когда запрос поступает к распределённому индексу с удалёнными агентами, мы запускали множество потоков для подключения и отправки запроса, затем ждали, пока все они завершатся, чтобы перейти к следующим этапам. Проблема в том, что если один узел отвечает медленно, он может замедлить весь процесс. Вместо того чтобы отправлять запрос каждому узлу, который ответил, они должны были ждать, пока все будут готовы. В итоге это означало простои и увеличение общего времени ответа запроса. Теперь каждое соединение работает независимо от начала до завершения, и его часть выполнения не зависит (не задерживается) от возможных более медленных. В связи с этим в предыдущих версиях был сделан первый шаг по полному отделению «чёрных дыр»‑агентов от обычных агентов, поскольку ранее, хотя мастер и не должен был ждать ответа от агента‑чёрной дыры, он всё равно ожидал начального ответа от него — и проблемный агент‑чёрная дыра мог замедлить весь запрос.
API протокол
Третье улучшение, связанное с сетью, касается API протокола. В предыдущих версиях соединение между мастером и удалённым агентом начиналось с 'рукопожатия' — небольшого пакета, содержащего версию API. Другая сторона отвечала своей версией, и если всё в порядке, запрос начинался. Это рукопожатие было задумано как защита от возможных ошибок в адресе/порту в конфигурации агента, чтобы не отправлять более крупный пакет в таком случае. Однако мы увидели в этом пустую трату времени (учитывая сетевые задержки) и пропускной способности, просто проверяя, правильно ли пользователь настроил всё. Такое случается редко, и даже если происходит, пользователь может исправить это.
Вместо этого теперь это «рукопожатие» отправляется вместе с запросом в одном пакете, сокращая общее время, затрачиваемое на запрос к удалённому узлу. Если удалённый хост действительно неверен, мы просто отправим пакет зря, но это может заметить пользователь и исправить — нам не нужно постоянно проверять это. Это изменение протокола сохраняет совместимость со старым протоколом, поэтому если мастер обновлён до версии 2.7+, он всё ещё сможет взаимодействовать с удалёнными агентами версии < 2.7.