Раздувание буфера: это запаздывание, глупец!
Развитие эффективной системы управления активными очередями было затруднено ложными представлениями о причинах и значении очередей.
Кетлин Николс и Ван Джейкобсон
Летом 2010 года Джим Геттис, как и многие родители, часто слышал от детей жалобы, что домашний Wi-Fi работает слишком медленно. В отличие от большинства родителей, Геттис к этому времени успел поработать в HP, Alcatel-Lucent, Консорциуме Всемирной паутины и Инженерном совете интернета. В буквальном смысле слова он был редактором технических условий HTTP, которые используются и по сей день. Поэтому там, где большинство отцов компьютерных фанатов стали бы искать проблему, Геттис ее решил.
Как объяснял Геттис целому отделу инженеров Google:
Мне пришлось однажды копировать или ресинхронизировать старые архивы Консорциума из дома в Массачусетский технологический университет за 10 миллисекунд… SmokePing сообщил о запаздывании в среднем на 1 секунду наряду с масштабной потерей пакетов, пока я просто копировал файл… Я открыл Wireshark и увидел вспышки действительно очень странного поведения. Это вовсе не было похоже на TCP, как я ожидал. Такого не должно было происходить.
Говоря простым языком, он заметил что-то… очень странное. Как в популярной шутке: самая интригующая фраза, которую можно услышать от первооткрывателя в науке, не «эврика!», а «это странно».
Вначале Геттис подумал, что что-то не так с его модемом. То, о чем говорила его семья, называя проблемой с интернетом, казалось просто «затором» в их домашней розетке. Пакеты, которые должны были отправиться в Бостон, не застревали на полпути туда; они застревали в доме.
Но чем больше Геттис вникал в происходящее, тем больше он начинал беспокоиться. Проблема негативно сказывалась не только на роутере и модеме в его доме, но в каждом доме. И проблема заключалась вовсе не в сетевых устройствах – она была в компьютерах, в десктопах, лэптопах, планшетах, смартфонах, работающих на Linux, Windows и OS X. И дело было не в аппаратном оборудовании конечного пользователя: проблема затрагивала всю инфраструктуру интернета в целом. Геттис начал обсуждать это с ключевыми сотрудниками из Comcast, Verizon, Cisco и Google, включая Ван Джейкобсона и Винта Серфа, и постепенно головоломка начала складываться.
Проблема была повсюду. И заключалась она в раздувании буфера обмена.
Буфер – это, по сути, очередь, роль которой состоит в том, чтобы сглаживать вспышки информационной передачи. Если бы вы зашли в магазин за пончиками примерно в то же время, когда и другой посетитель, это не привело бы к тому, что кассир не смог бы справиться с работой и вас попросили бы покинуть магазин и зайти в другое время. Посетители, разумеется, не пошли бы на это. Не пошел бы на это и менеджмент: такая политика гарантирует крайне неэффективное выполнение кассиром своей работы. А организация покупателей в очередь гарантирует, что средняя пропускная способность магазина приближается к максимуму. И это хорошо.
Такое превосходное средство по утилизации ресурсов имеет вполне реальные издержки – задержку в обслуживании. Когда Том взял свою дочь на фестиваль Синко де Майо в Беркли, она решила попробовать блинчик с шоколадом и бананом. Они встали в очередь и стали ждать. Через 20 минут Том сделал заказ. Но после оплаты ему пришлось ждать еще 40 минут, чтобы получить наконец блинчик. (Как и Джиму Геттису, Тому пришлось выслушать многочисленные жалобы дочери.) Прием заказов, как оказалось, занимал гораздо меньше времени, чем приготовление блинчиков, поэтому очередь для того, чтобы сделать заказ, была лишь частью задачи. По крайней мере, процесс был визуально понятным: покупатели знали, зачем они стоят в очереди. Вторая, более длинная очередь была неочевидной. В этом случае было бы гораздо правильней ограничить длину первой очереди и временно приостанавливать прием заказов, если она достигла критической отметки, оповещая об этом с помощью соответствующей таблички. Отказ части покупателей стал бы выгодней для всех (не важно, дождались бы они укорачивания очереди или ушли совсем). Для лавки с блинами это не означало бы каких-либо упущенных финансовых возможностей, поскольку в любом случае они могут продать лишь столько блинов, сколько могут приготовить в день, вне зависимости от того, как долго ждут их покупатели.
Это как раз тот феномен, который обнаружил Джим Геттис, пытаясь разобраться с домашним модемом. Поскольку он закачивал файл, его компьютер посылал модему так много пакетов, что тот едва ли мог с ними справиться. В то же время модем «делал вид», что может справиться и с еще бóльшим количеством сверх своих реальных возможностей, не отклоняя ни один из них и ставя их в огромную очередь. Таким образом, когда Геттис пытался одновременно скачать что-то (зайти на интернет-сайт или проверить почту), его ACK-пакеты застревали в очереди после процессов загрузки, ожидая, пока загружаемые файлы наконец покинут дом.
Это было похоже на попытку вести диалог, который прерывался бы на 10 или 20 секунд после каждого сказанного «ух» и «м-м-м». Говорящему пришлось бы замедлять темп рассказа, полагая, что вы его не понимаете и ничего не можете с этим поделать.
Когда буфер сети наполняется, происходит так называемое отбрасывание последнего элемента – бесцеремонный способ сообщить о том, что каждый пакет, поступающий после этой точки, будет просто отклонен и, по сути, удален. (Просьба посетителям больше не вставать в очередь после того, как она станет слишком длинной, является вариантом отбрасывания последнего элемента в человеческом контексте.)
При использовании метафоры с почтовой службой для объяснения принципа действия коммутации пакетов странно представить, что почтальон просто избавляется от каждой посылки, которая не вмещается в его грузовик утром. Хотя на самом деле это то самое «отбрасывание пакетов», которое заставляет компьютер заметить, что один из пакетов не был принят, что приведет к урезанию алгоритмом АУМУ трафика передачи информации. «Отбрасывание пакетов» – изначальный механизм обратной связи в интернете. Слишком большой буфер (как, например, ресторан, который принимает каждый заказ вне зависимости от возможностей кухни, или модем, принимающий каждый поступающий пакет вне зависимости от того, сколько потребуется ему времени на последующую отправку) предупреждает любые промедления, которые на самом деле должны происходить.
Глобально буферы используют задержку (явление, известное как запаздывание в сетевых технологиях), чтобы максимизировать пропускную способность. То есть они заставляют пакеты (или посетителей) ждать, чтобы воспользоваться более поздним периодом, когда у них будет больше ресурсов или времени. Но буфер, который перманентно работает в полном объеме, не дает вам выбора между двух зол: полное запаздывание и никакой отдачи. Сглаживание вспышек – это хорошо, если вы, как правило, разбираете информацию по мере ее поступления. Но если ваша средняя нагрузка превышает вашу среднюю скорость работы, то никакой буфер чуда не сотворит. И чем больше буфер, тем больше вы отстанете, прежде чем начнете звать на помощь. Один из фундаментальных принципов работы буферов, будь они для пакетов или управляющих рестораном, заключается в том, чтобы они работали корректно, даже когда работы нет.
Десятилетиями компьютерная память была слишком дорогой, поэтому попросту не было смысла разрабатывать модемы с уймой ненужного объема памяти. Таким образом, у модема даже не было возможности выстраивать очередь длиннее, чем он мог обработать. Но в каком-то смысле, по мере того как экономия на масштабе радикально снизила стоимость памяти, производители модемов стали встраивать в них гигабайты ОЗУ, поскольку это, по сути, был наименьший возможный объем памяти. В результате буферы в широко распространенных устройствах – в модемах, роутерах, лэптопах, смартфонах (и в основе работы самого интернета) – стали в тысячи раз больше, чем нужно, прежде чем некоторые, как Джим Геттис, выразили свои опасения по этому поводу.