Книга: Алгоритмы для жизни: Простые способы принимать верные решения
Назад: Пакетная коммутация
Дальше: Экспоненциальная задержка: алгоритм прощения

Признание

Ни одна передача не может быть на 100 % надежной.
Винт Серф и Боб Кан
Фраза «Чудны дела твои, Господи» была не просто первым сообщением, переданным на большое расстояние. Она была также и вторым: Альфред Вейл отправил эту цитату обратно Морзе в палату Верховного суда как способ подтвердить получение.
Ответ Вейла убедил Морзе и собравшихся вокруг него членов Законодательного собрания в том, что его сообщение было получено (предполагалось, конечно, что Вейл не знал заранее, каким будет текст сообщения). Но как Вейл мог убедиться, что его подтверждение достигло адресата?
Программисты знают это понятие как проблему византийских генералов. Представьте себе двух генералов на противоположных концах долины, в которой расположился их общий враг. Генералы пытаются скоординировать атаку. Только в случае идеальной синхронизации их действия увенчаются успехом, потому что атаковать в одиночку – это самоубийство. Дело осложняется тем, что все сообщения от одного генерала к другому должны быть переданы из рук в руки через всю долину, которая полна врагов, то есть существует вероятность, что сообщение никогда не будет доставлено.
Допустим, первый генерал предлагает время для атаки, но не начнет ее, не будучи уверенным, что второй генерал выдвинулся ему навстречу. Второй принимает приказ и отправляет обратно подтверждение. Но он не будет атаковать, если не будет точно знать, что первый генерал это подтверждение получил (так как в противном случае первый не выступит). Первый генерал получил подтверждение, но не будет атаковать, пока не будет уверен, что второй об этом знает. Следование этой логической цепочке подразумевает бесконечные серии сообщений и, очевидно, ни к чему не приведет. Коммуникация – одна из тех восхитительных вещей, которые работают только на практике; в теории это невозможно.
В большинстве случаев последствия ошибок в коммуникации редко бывают столь плачевными, а потребность в уверенности столь абсолютной. В TCP сбой обычно приводит к повторной передаче данных, а не к смерти, поэтому его обычно достаточно для сеанса, который называют тройным рукопожатием. Посетитель говорит «привет», сервер принимает это «привет» и говорит «привет» в ответ, посетитель принимает, и если сервер получает вот это третье сообщение, то никакого дальнейшего подтверждения уже не требуется. Но даже после того, как это первичное соединение выполнено, остается риск, что последующие пакеты могут быть повреждены, утеряны в процессе передачи или доставлены испорченными. Доставка почтовых отправлений может быть подтверждена уведомлением о вручении; доставка же пакетов онлайн подтверждается тем, что называется пакетами подтверждения, или ACK. Они имеют решающее значение для функционирования сети.
Принцип работы ACK одновременно прост и детально продуман. Помимо сценария тройного рукопожатия, каждый компьютер дает другому нечто вроде серийного номера (и было условлено, что после отправления каждого пакета этот серийный номер увеличивается на единицу, как номера чеков в чековой книжке). К примеру, если ваш компьютер инициирует связь с веб-сервером, он должен отправить этому серверу, скажем, число 100. Посылаемый сервером АСК в свою очередь указывает серийный номер, с которого будут начинаться все отправляемые сервером пакеты (например, 5000), и также сообщает: «Готов к 101». АСК вашего компьютера получает число 101 и передает: «Готов к 5001». (Имейте в виду, что обе эти схемы нумерации независимы друг от друга и число, с которого начинается последовательность, как правило, выбирается случайным образом.)
Такой механизм действия позволяет с точностью определить, в какой момент пакеты сбились с пути. Если сервер ожидает 101, а вместо этого получает 102, он отправит АСК к пакету 102, который все еще гласит: «Готов к 101». Если в ответ он получит следующий пакет 103, то он снова напомнит: «Готов к 101». Три подобных внеочередных АСКа дадут вашему компьютеру сигнал, что 101 не просто задерживается, а безвозвратно потерялся, и он повторно отправит этот пакет. На этот раз сервер (который сохранил пакеты 102 и 103) отправит АСК «Готов к 104», сигнализирующий о том, что последовательность была восстановлена.
Все эти подтверждения дают в сумме значительный объем трафика. Мы представляем себе, например, передачу объемного файла как одностороннюю операцию, но на самом деле реципиент посылает обратно отправителю сотни контрольных сообщений. Отчет, составленный в конце 2014 года, показал, что почти 10 % восходящего направления интернет-трафика в часы пик приходится на Netflix, о котором мы привыкли думать, что он отправляет данные исключительно в нисходящем направлении, к пользователям. Но все эти видео производят огромное количество АСКов.
В сфере человеческих отношений беспокойство о том, что сообщение действительно дошло до собеседника, пронизывает весь разговор. Говорящий может неосознанно прибавлять «понимаешь» в конце каждого предложения, а слушатель в свою очередь не может удержаться от кивков и бесконечного потока междометий «ну», «да-да», «согласен», «понял», «угу». Мы делаем это даже в личном разговоре, а уж в беседе по телефону это зачастую единственный способ дать понять собеседнику, что вы еще не отключились и продолжаете слушать. Неудивительно, что самой успешной в XXI веке маркетинговой кампанией оператора беспроводной связи стала повторяемая вновь и вновь крылатая фраза инженера сетевого контроля качества: «Ты меня слышишь?!»
Когда что-то в этой словесной баталии идет не так, мы нередко недоумеваем. Как говорит блогер и разработчик программного обеспечения Тайлер Трит:
В распределенной системе мы стараемся гарантировать доставку сообщения, ожидая подтверждения, что оно было получено, но в любой момент что-то может пойти не так. Было ли сообщение сброшено? Был ли сброшен АСК? Сломался ресивер? Или просто все тормозит? Сеть тормозит? Или это я торможу?
В задаче, с которой сталкиваются византийские генералы, напоминает он нам, «дело не в сложности разработки, а в невозможности результата».
Ранние сетевые исследования, замечает Винт Серф, основывались на предположении, что «мы можем построить надежную сеть». Но, с другой стороны, «интернет был основан на предположении, что сеть вовсе не обязательно должна быть надежной, и приходилось осуществлять непрерывные повторные передачи для возобновления соединения».
По иронии судьбы, одно из немногих исключений – это передача человеческого голоса. Голосовые коммуникации в режиме реального времени, такие как Skype, например, обычно не используют протокол TCP, который лежит в основе большей части интернета. На заре сетевых коммуникаций исследователи обнаружили, что передавать человеческий голос, используя надежные, устойчивые протоколы со всеми их АСК и повторными передачами утерянных данных, убийственно. Люди сами обеспечивают «ошибкоустойчивость». Как объясняет Серф, «в случае с речью, если пакет теряется, вы просто говорите: "Повтори еще раз, пожалуйста, я что-то пропустил"».
По этой причине услуги телефонной связи, которые автоматически снижают фоновые помехи до тишины, оказывают своим абонентам медвежью услугу. Фоновые помехи являются свидетельством того, что звонок еще не прерван, и любое молчание – это осознанный выбор другой стороны. Когда их нет, приходится учитывать возможность прерывания соединения и постоянно просить подтверждения, что связь еще есть. Поводом для беспокойства во всех протоколах пакетной коммутации также служит тот факт, что любое средство передачи основывается на асинхронном режиме очередности – будь то написание писем, текстовых сообщений или пробные переписки на сайтах знакомств. Каждое сообщение может быть последним, и зачастую невозможно определить, взял ли собеседник паузу для ответа или давно уже закончил разговор.
Так как же обращаться с человеком (или с компьютером), если общение столь ненадежно?
Первый вопрос заключается в том, сколько времени должно пройти в ожидании ответа, прежде чем мы можем смело констатировать сбой. Отчасти это зависит от вида самой сети: в телефонном разговоре наше волнение – вопрос нескольких секунд, в переписке по электронной почте – нескольких дней, а в обычном почтовом сообщении – нескольких недель. Чем длиннее путь от отправителя к получателю и обратно, тем дольше можно не обращать внимания на молчание – и тем больше информации может потенциально находиться в стадии доставки, прежде чем отправитель понимает, что что-то не так. В сетевой работе тот факт, что стороны могут должным образом корректировать свои ожидания с учетом своевременности реагирования, является ключевым моментом правильного функционирования системы.
Второй же вопрос, разумеется, заключается в том, что нам нужно делать, когда мы обнаруживаем сбой.
Назад: Пакетная коммутация
Дальше: Экспоненциальная задержка: алгоритм прощения