Kademlia
Kademlia — это протокол распределённой хеш-таблицы (РХТ, distributed hash table, DHT) для децентрализованных пиринговых компьютерных сетей, разработанный Петаром Маймунквом и Давидом Мазьером в 2002 году[1].[2] Протокол определяет структуру сети и порядок обмена информацией между узлами через поисковые запросы. Узлы Kademlia обмениваются данными посредством UDP; каждый узел идентифицируется уникальным номером, который используется не только как идентификатор, но и для поиска значений.
Подробности функционирования
Для поиска значения, связанного с заданным ключом, алгоритм пошагово опрашивает сеть, каждый раз находя узлы, всё более близкие к целевому ключу, пока не будет найдено само значение или не останется более близких узлов. Такой подход очень эффективен: как и другие РХТ, Kademlia за время поиска связывается лишь с узлов из общего числа в системе.
Ключевым преимуществом модели является децентрализация, которая увеличивает устойчивость сети к атакам типа отказа в обслуживании (DoS). Даже если множество узлов окажутся недоступны, повреждения ограничены, поскольку сеть способна «залечивать» образовавшиеся «дыры»[1].
В реализации протокола Kademlia для I2P предусмотрены меры против возможных уязвимостей протокола, в частности — против Sybil-атак[3].
Пиринговые сети строятся на основе узлов, использующих разные протоколы обмена и поиска информации. Протоколы совершенствовались с поколениями: в первой волне (например, Napster) использовалась центральная база для координации поиска, во второй, например, Gnutella, применялся механизм массовой рассылки, а современные сети наподобие BitTorrent используют распределённые хеш-таблицы. В РХТ расположение ресурсов распределено по всей сети.
В Kademlia «расстояние» между двумя узлами рассчитывается как исключающее ИЛИ их идентификаторов, интерпретируемых как неотрицательные целые числа одинаковой длины. Такой подход позволяет считать узлы с близкими номерами «соседями», даже если они физически далеки друг от друга. Обычно идентификаторы выбираются случайно и с целью максимальной уникальности.
Оператор XOR был выбран как метрический — он обладает необходимыми свойствами «расстояния»: расстояние до самого себя равно нулю, функция симметрична и удовлетворяет неравенству треугольника. Такие свойства делают вычисление расстояния простым и дешёвым[1].
В каждом шаге поиска Kademlia приближается к цели на 1 бит; базовая сложность поиска составляет : для сети с узлов потребуется не более шагов.
Первоначальный вариант Kademlia предполагал маршрутные таблицы фиксированного размера, представленные в пре-принт версии статьи[4]. На практике наиболее распространённые реализации используют динамические таблицы.
Маршрутная таблица состоит из набора списков, по одному на каждый бит идентификатора узла. Каждый список хранит адрес, порт и node ID удалённого узла, причём каждый k-бакет соответствует множеству узлов на определённом расстоянии. В n-ый список помещаются те узлы, чей n-ый бит отличается от n-го бита текущего узла, а предыдущие n-1 бит совпадают. Таким образом, списки для наиболее далёких расстояний наиболее заполнены, а для ближних — могут быть пусты или содержать единичные записи.
Формируя список контактов, узел добавляет обнаруженных соседей при любых операциях. В каждом бакете поддерживается до k (=20) записей. Если новый кандидат претендует на место, а бакет уже заполнен, то его помещают в запасной список — и в основной попадает только при выбытии старого элемента. Такой механизм повышает устойчивость и обновляемость маршрутизации.
В демонстрационной сети размером 2^3 (8 узлов) каждый участник имеет 3 ведра (k-бакета), содержащих адреса опрошенных ранее соседей при разных значениях битов, распределённых по расстояниям.
Замечено, что узлы с большим временем жизни в сети, скорее всего, будут доступны и в будущем[5][6], поэтому Kademlia по возможности удерживает такие контакты в таблице, что положительно сказывается на устойчивости сети.
В Kademlia определено 4 типа сообщений:
- PING — проверка доступности узла.
- STORE — сохранение пары (ключ, значение) на выбранном узле.
- FIND_NODE — возвращает k ближайших известных узлов к запрашиваемому номеру.
- FIND_VALUE — аналогичен FIND_NODE, но если значение присутствует, то возвращается оно.
Каждое сообщение RPC снабжается случайным маркером инициатора, чтобы связать ответ с исходным запросом.
Запросы поиска могут выполняться асинхронно. Количество параллельных запросов ограничено. Узел начинает с опроса α наиболее близких известным ему соседей; каждый из них возвращает в ответ список из k ближайших известных ему к ключу узлов. Итерации выполняются до тех пор, пока не удастся найти более близкий к цели ID. При этом структура результатов содержит k ближайших на текущий момент ID.
При необходимости узлы могут учитывать RTT, индивидуализируя таймауты запросов.
Данные сопоставляются с ключами с помощью хеш-функции. Хранение и поиск значений реализованы по аналогии с поиском узлов. Каждое значение дублируется на k узлах, чтобы ресурс не затерялся при выходе из сети отдельных участников. Поиск останавливается, когда обнаружено значение или больше не найдено узлов, более близких к ключу.
Для популярных значений может применяться кэширование: клиент-запросчик временно сохраняет значение на одном из соседей вне группы ближайших k, облегчая балансировку нагрузки. Кэш автоматически очищается спустя определённое время.
В некоторых сетях, например, Kad, кэширование и репликация не реализуются — обновление значений происходит только при постоянном участии владельца файла.
Для подключения к сети новый узел использует процедуру bootstrapping — необходим адрес хотя бы одного участника сети. После генерации уникального node ID и обнаружения bootstrap-узла, новичок выполняет поисковый запрос на собственный идентификатор, пополняя тем самым свою таблицу и оповещая других о своём наличии. По мере заполнения k-бакетов ведра могут делиться, если в них попадают как более дальние, так и более близкие к собственному node ID значения.
Метрика XOR позволяет группировать биты идентификатора, определяя множество ведер не по каждой отдельной позиции, а по префиксу длины m. Это снижает теоретически максимальное количество итераций поиска с log₂n до log_{2^m}n.
Маршрутные таблицы могут содержать комбинации различных длин префикса имени, например, так сделано в Kad-сети, используемой eMule.
Значение для науки
Использование метрики XOR в Kademlia позволяет проводить формальный анализ протокола как алгебраической группы, в отличие от многих других DHT, где приходится применять симуляции или сложные формальные методы.
Математический анализ алгоритма
Рассмотрим сеть Kademlia из узлов с идентификаторами , каждый длины бит, интерпретируя их структуру как дерево префиксов (trie), где каждый лист — уникальный узел. Заполнение i-го ведра каждого x производится случайным выбором k контактов из множества узлов, совпадающих по префиксу длиной d–i бит.
Маршрутизация сводится к последовательным «прыжкам» по дереву, максимально приближая ID к цели.
Доказано, что при детерминированном распределении идентификаторов и в худшем случае: , где H_k — k-е гармоническое число. Для больших k среднее количество прыжков ограничено .
Если идентификаторы выбираются случайно, то: , а среднее также приближается к , где c_k зависит только от k[7]. Это объясняет эффективность поиска: нужно опросить лишь участников.
Использование в файлообменных сетях
Протокол активно применяется в файлообменных сетях. Через ключевые поисковые запросы по Kademlia можно находить информацию для скачивания.
В центральной базы файлов нет — каждый клиент отвечает за фрагмент индекса: при публикации файла рассчитывается его хэш, который становится ключом в DHT; клиент-наблюдатель ищет узлы, чьи идентификаторы близки к хэшу, и передаёт им IP-адрес издателя. Таким образом, узлы с ближайшими к хэшу идентификаторами хранят списки IP-адресов источников файла.
Пользователю достаточно знать только хэш файла, например, из magnet-ссылки или индекса, чтобы начать поиск и затем запросить список источников.
Когда ключу соответствует множество значений, клиенты собирают информацию с k ближайших к хэшу узлов.
Поиск по именам файла реализован через ключевые слова: имя делится на отдельные слова, каждое хэшируется и размещается в DHT наряду с именем файла и его ключом. Поиск производится по хэшу ключевого слова, запрашивая список файлонатов у соответствующего узла; затем нужный файл скачивается по стандартным процедурам.
Реализации
Публичные p2p-сети, использующие алгоритм Kademlia (сетевые протоколы несовместимы между собой):
- I2P — анонимная оверлей-сеть[8].
- Kad network — разработана сообществом eMule для замены серверной архитектуры eDonkey network.
- Ethereum — протокол поиска узлов в стеке блокчейна Ethereum построен на модифицированной Kademlia (нет хранения значений, взаимная верификация точек контакта и поддержка множества подпротоколов)[9].
- Overnet — прекратившая существование сеть, для которой разрабатывалась библиотека KadC.
- Mainline DHT — DHT-сеть для BitTorrent (без трекеров, протокол основан на Kademlia).
- Osiris — для управления анонимными распределёнными веб-порталами.
- Retroshare — F2F децентрализованная коммуникационная платформа (VoIP, обмен сообщениями, файлами и др.).
- Tox — полностью распределённая система обмена сообщениями, голосом и видеозвонками.
- Gnutella DHT — изначально разработана для LimeWire[10][11] и в дальнейшем поддерживалась другими gnutella-клиентами[12].
- IPFS — p2p-файловая система на основе libp2p[13].
- TeleHash — mesh-протокол, использующий Kademlia для маршрутизации соединений[14].
- iMule — файлообменная утилита для I2P.
- OpenDHT — библиотека Kademlia, используется в Jami и др[15].
- GNUnet — стек для построения защищённых приватных p2p-приложений; реализует рандомизированную версию Kademlia (R5N)[16].
- Dat — p2p-сервис обмена файлами на базе Hypercore Protocol[17].
Примечания
Литература
- Maymounkov P., Mazieres D. Kademlia: A Peer-to-peer Information System Based on the XOR Metric // Proceedings IPTPS, 2002.
- Cai X. S., Devroye L. A Probabilistic Analysis of Kademlia Networks // Lecture Notes in Computer Science, 2013, vol. 8283, pp. 711–721.
- Cai X. S., Devroye L. The Analysis of Kademlia for Random IDs // Internet Mathematics, 2015, vol. 11, issue 6, pp. 1–16. Cai, Xing Shi; Devroye, Luc (2015). “The Analysis of Kademlia for Random IDs”. Internet Mathematics. 11 (6): 1—16. arXiv:1402.1191. DOI:10.1080/15427951.2015.1051674. ISSN 1542-7951. S2CID 16547375. Дата обращения 2024-06-20.
|access-date=требует|url=(справка)


