Таким образом, одноранговые сети столкнулись с рядом сложностей: нужно было обеспечить надлежащее масштабирование, убедить пользователей оставаться в сети после скачивания контента и обеспечить его проверку. Как будет показано далее, дизайн сети BitTorrent обеспечил решение всех этих проблем.
Решение проблем масштабирования, мотивации пользователей и проверки контента: BitTorrent
Протокол BitTorrent разработан Брэмом Коэном в 2001 году, чтобы позволить набору одноранговых узлов быстро и легко обеспечивать общий доступ к файлам. Существуют десятки бесплатных поддерживающих его клиентов, аналогично тому, как множество браузеров поддерживает протокол HTTP для взаимодействия с веб-сервером. Этот протокол доступен как открытый стандарт, его описание находится на сайте bittorrent.org.
В типичной одноранговой системе, например, организованной с помощью протокола BitTorrent, каждый пользователь обладает некоторой информацией, которая может представлять для кого-то интерес (бесплатное ПО, музыка, видео, фотографии и т.д.) Чтобы предоставить контент в общий доступ, необходимо ответить на следующие три вопроса:
1. Как пир находит другие пиры с нужным ему контентом?
2. Как контент дублируется пирами, чтобы обеспечить быстрое скачивание для всех?
3. Как пиры поощряют друг друга к тому, чтобы наряду со скачиванием контента для себя они загружали его для других?
Наличие первого вопроса объясняется тем, что не все пиры содержат весь контент. Для решения этой проблемы в протоколе BitTorrent каждый контент-провайдер создает описание контента — торрент (torrent). Торрент намного меньше, чем сам контент, и используется пиром, чтобы проверить целостность данных, которые он загружает с других пиров. Пользователи, которые хотят получить нужные им данные, должны сначала скачать торрент (допустим, найти его на веб-странице, рекламирующей контент).
Торрент — это просто файл в определенном формате, содержащий два ключевых вида информации. Прежде всего, это имя трекера — сервера, который направляет пиры к содержимому торрента. Вторым видом информации является список фрагментов одинакового размера, или сегментов (chunks), из которых состоит контент. В первых версиях BitTorrent трекер был централизованным сервером. Как и в случае Napster, централизация делала трекер единственным уязвимым звеном сети. В современных версиях BitTorrent функциональность трекера в большинстве случаев децентрализуется с помощью DHT-таблицы. Для разных торрентов могут использоваться различные размеры сегментов, обычно в диапазоне от 64 до 512 Кбайт. Файл торрента содержит имя каждого сегмента, предоставленного как 160-битный SHA-1 хеш сегмента. Мы рассмотрим криптографические хеши, такие как SHA-1, в главе 8. Пока вы можете рассматривать хеш как более длинную и безопасную контрольную сумму. Торрент-файл, содержащий размер сегментов и хеши, как минимум на три порядка меньше, чем контент, поэтому он может быть передан быстро.
Чтобы загрузить контент, описанный в торренте, пир сначала контактирует с его трекером. Трекер (tracker) — это сервер (или группа серверов, организованная с помощью DHT), который поддерживает список всех остальных пиров, активно производящих скачивание и загрузку контента. Этот набор пиров называется роем (swarm). Члены роя постоянно контактируют с трекером, чтобы сообщать, что они все еще активны, либо о том, что они покидают рой. Когда новый пир связывается с трекером, чтобы присоединиться к рою, трекер сообщает ему об остальных пирах в рое. Получение торрента и контакт с трекером — это первые два шага для загрузки контента (илл. 7.47).
Второй вопрос: каким образом делиться контентом, чтобы обеспечивать при этом быструю загрузку? Когда формируется начальный рой, некоторые пиры должны иметь все сегменты, составляющие контент. Эти пиры называются сидерами (seeders — «сеятели»). Другие пиры, которые присоединяются к рою, не будут иметь никаких сегментов; это пиры, скачивающие контент.
Илл. 7.47. BitTorrent
В то время как пир участвует в рое, он одновременно скачивает отсутствующие сегменты с других пиров и загружает имеющиеся у него сегменты тем пирам, которым они нужны. Этот обмен показан как последний шаг распределения контента на илл. 7.47. Какое-то время пир собирает сегменты, пока не загрузит весь контент. Пир может покинуть рой (и вернуться) в любое время. Обычно он остается в течение некоторого короткого периода после окончания своей собственной загрузки. Из-за появляющихся и исчезающих пиров «текучесть» в рое может быть довольно большой.
Чтобы данный метод работал корректно, каждый сегмент должен быть доступен у большого числа пиров. Если бы все получали сегменты в одинаковом порядке, многие пиры зависели бы от сидеров следующего сегмента. Это создало бы узкое место. Вместо этого пиры обмениваются списками имеющихся у них сегментов. Затем они выбирают для загрузки преимущественно редкие сегменты, которые трудно найти. Идея в том, что скачивание редкого сегмента приведет к созданию еще одной его копии, что, в свою очередь, облегчит его поиск и скачивание для других пиров. Если так будут поступать все пиры, то спустя некоторое время все сегменты станут широко доступны.
Третий вопрос касается мотивации пользователей. Узлы CDN-сетей предназначены лишь для того, чтобы предоставлять контент пользователям, но P2P-узлы работают иначе. Это компьютеры пользователей, а люди часто больше заинтересованы в том, чтобы получить нужный им фильм, чем в том, чтобы помочь в скачивании остальным. То есть у пользователей есть мотивация к тому, чтобы обмануть систему. Узлы, берущие ресурсы из системы без какого-либо ответного вклада, называют фрирайдерами (free-riders), или личерами (leechers — «пиявки»). Если их слишком много, система перестает нормально функционировать. Первые P2P-системы известны наличием таких узлов (Сарою и др.; Saroiu et al., 2003), поэтому протокол BitTorrent был призван минимизировать их количество.
BitTorrent пытается решить эту проблему путем вознаграждения пиров, которые производят достаточную исходящую загрузку. Каждый пир беспорядочно обращается к другим пирам, получает сегменты от них и в то же время пересылает сегменты к ним. Пир продолжает обмен сегментами только с небольшим количеством других пиров, что дает самую высокую производительность скачивания, и одновременно в случайном порядке пробует подключиться к другим пирам в поиске хороших партнеров. Случайные обращения к пирам также позволяют вновь прибывшим получить начальные сегменты, которыми они могут обменяться с другими пирами. Пиры, с которыми узел в данный момент обменивается сегментами, называют незаглохшими (unchoked).
Через какое-то время этот алгоритм должен сопоставить друг с другом пиры с похожей скоростью загрузки и скачивания. Чем активнее пир содействует остальным, тем больше он может ожидать в ответ. Использование набора пиров также помогает насыщать пропускную способность загрузки пиров для высокой производительности. И наоборот, если пир не пересылает сегменты на другие пиры или делает это очень медленно, рано или поздно он окажется отрезанным, или заглохшим (choked). Эта стратегия не позволяет использовать рой, не давая ничего взамен.
Этот алгоритм заглушения иногда описывается как реализация стратегии «око за око» (tit-for-tat), поощряющей сотрудничество в повторяющихся взаимодействиях. Это широко известная стратегия из теории игр, при которой: 1) у игроков нет мотивации к обману, если они постоянно играют друг с другом (как происходит в сети BitTorrent, где пиры должны периодически обмениваться сегментами) и 2) игроки наказываются при отказе от сотрудничества (как в случае заглохших пиров). Несмотря на эту схему, клиенты BitTorrent все же могут прибегать к различным способам обмана системы (Пиатек и др.; Piatek et al., 2007). Например, поскольку алгоритм сети BitTorrent поощряет выбор редких сегментов, пиры могут предоставить ложную информацию о том, какими сегментами файла они располагают (например, они могут сообщить о наличии редких сегментов) (Лиокас и др.; Liogkas et al., 2006). Кроме того, существуют программы, позволяющие клиентам сообщать трекеру ложную информацию о соотношении между объемом скачанной и переданной информации (то есть сообщать о том, что они раздавали данные другим пирам, хотя в действительности этого не было). По этим причинам критически важно, чтобы пиры проверяли сегменты, получаемые от остальных. Это можно делать путем сравнения хеша SHA-1 каждого сегмента, указанного в торрент-файле, с соответствующим вычисленным хешем SHA-1 каждого скачиваемого сегмента.
Еще одной проблемой является мотивация пиров к тому, чтобы оставаться в рое сети BitTorrent в качестве сидера даже после скачивания нужного файла. Если они не будут этого делать, может возникнуть ситуация, когда ни у кого в рое не будет целого файла или (что еще хуже) когда в рое вообще не будет определенных сегментов, что сделает невозможным скачивание файла полностью. Это особенно остро проявляется в случае непопулярных файлов (Менаше и др.; Menasche et al., 2013). Для решения проблемы мотивации были разработаны различные методы (Рамачандран и др.; Ramachandran et al., 2007).
В ходе этого раздела вы убедились, что к теме протокола BitTorrent прилагается обширная терминология: торренты, рои, личеры, сидеры, трекеры и т.д. Чтобы узнать больше о BitTorrent, ознакомьтесь с короткой статьей Коэна (Cohen, 2003).
7.5.5. Эволюция интернета
Как было упомянуто в главе 1, интернет прошел довольно причудливый исторический путь, возникнув в ходе осуществления научно-исследовательского проекта, над которым работали несколько десятков американских университетов по договору с агентством ARPA. Трудно даже определить, когда именно он появился. Возможно, это произошло 21 ноября 1969 года, когда была установлена связь между двумя узлами ARPANET, расположенными в Калифорнийском университете в Лос-Анджелесе (UCLA) и в Исследовательском институте Стэнфорда (SRI)? Или это случилось 17 декабря 1972 года, когда к ARPANET подключилась гавайская сеть AlohaNet, образовав тем самым интерсеть? Или, быть может, интернет появился 1 января 1983 года, когда ARPA официально утвердила протокол TCP/IP? А возможно, он возник в 1989 году, когда Тим Бернерс-Ли предложил создать то, что впоследствии стало Всемирной паутиной? Сложно сказать. Однако ни у кого нет сомнений, что со времен становления сети ARPANET и первых зачатков Всемирной паутины интернет подвергся огромным изменениям, значительная часть которых была обусловлена повсеместным распространением CDN и облачных вычислений. Ниже мы кратко рассмотрим этот процесс.