Подробное введение в распределенные системы

Что такое распределенная система и почему она такая сложная?

С постоянно растущей технологической экспансией в мире распределенные системы становятся все более и более распространенными. Это обширная и сложная область изучения информатики.

Цель этой статьи - познакомить вас с распределенными системами в базовой манере, показать вам представление о различных категориях таких систем, не углубляясь в детали.

Что такое распределенная система?

Распределенная система в ее простейшем определении - это группа компьютеров, работающих вместе, чтобы конечный пользователь выглядел как один компьютер.

Эти машины имеют общее состояние, работают одновременно и могут выходить из строя независимо, не влияя на время безотказной работы всей системы.

Я предлагаю постепенно прорабатывать пример распределения системы, чтобы вы могли лучше все это понять:

Пойдем с базой данных! Традиционные базы данных хранятся в файловой системе одной машины, и всякий раз, когда вы хотите получить / вставить в нее информацию - вы общаетесь с этой машиной напрямую.

Чтобы мы могли распространять эту систему баз данных, нам нужно, чтобы эта база данных работала на нескольких машинах одновременно. Пользователь должен иметь возможность разговаривать с любой машиной, которую он выберет, и не должен быть в состоянии сказать, что он разговаривает не с одной машиной - если он вставляет запись в узел №1, узел №3 должен иметь возможность вернуть эту запись.

Зачем распространять систему?

Системы всегда распределяются по необходимости. Суть в том, что управление распределенными системами - сложная тема, полная ловушек и мин. Развертывать, поддерживать и отлаживать распределенные системы - это головная боль, так зачем вообще туда идти?

Распределенная система позволяет вам масштабировать по горизонтали . Возвращаясь к нашему предыдущему примеру с одним сервером базы данных, единственный способ справиться с большим объемом трафика - это обновить оборудование, на котором работает база данных. Это называется вертикальным масштабированием .

Вертикальное масштабирование - это хорошо, хотя вы можете, но после определенного момента вы увидите, что даже самого лучшего оборудования недостаточно для достаточного трафика, не говоря уже о непрактичном размещении.

Горизонтальное масштабирование означает просто добавление дополнительных компьютеров, а не обновление оборудования одного из них.

Это значительно дешевле, чем вертикальное масштабирование после определенного порога, но это не его основной случай предпочтения.

Вертикальное масштабирование может поднять вашу производительность только до возможностей новейшего оборудования. Этих возможностей оказывается недостаточно для технологических компаний с умеренными и большими нагрузками.

Лучшее в горизонтальном масштабировании - это то, что у вас нет ограничений на масштаб масштабирования - всякий раз, когда производительность снижается, вы просто добавляете еще одну машину, потенциально до бесконечности.

Простое масштабирование - не единственное преимущество распределенных систем. Не менее важны отказоустойчивость и низкая задержка .

Отказоустойчивость - кластер из десяти машин в двух центрах обработки данных по своей природе более отказоустойчив, чем одна машина. Даже если один центр обработки данных загорится, ваше приложение все равно будет работать.

Низкая задержка - время прохождения сетевого пакета по миру физически ограничено скоростью света. Например, минимально возможное времяпередачизапроса в оба конца (то есть туда и обратно) в оптоволоконном кабеле между Нью-Йорком и Сиднеем составляет 160 мс. Распределенные системы позволяют иметь узел в обоих городах, позволяя трафику попадать в узел, который находится ближе всего к нему.

Однако для того, чтобы распределенная система работала, вам необходимо, чтобы программное обеспечение, работающее на этих машинах, было специально разработано для работы на нескольких компьютерах одновременно и решения возникающих вместе с этим проблем. Это оказалось нелегким делом.

Масштабирование нашей базы данных

Представьте, что наше веб-приложение стало безумно популярным. Представьте также, что наша база данных начала получать вдвое больше запросов в секунду, чем она может обрабатывать. Ваше приложение сразу же начнет снижать производительность, и ваши пользователи это заметят.

Давайте работать вместе и сделать нашу базу данных масштабируемой в соответствии с нашими высокими требованиями.

В типичном веб-приложении вы обычно читаете информацию гораздо чаще, чем вставляете новую или изменяете старую.

Есть способ повысить производительность чтения - так называемая стратегия репликации первичной реплики . Здесь вы создаете два новых сервера баз данных, которые синхронизируются с основным. Загвоздка в том, что вы можете читать только из этих новых экземпляров.

Всякий раз, когда вы вставляете или изменяете информацию - вы обращаетесь к первичной базе данных. Он, в свою очередь, асинхронно сообщает репликам об изменении, и они также сохраняют его.

Поздравляем, теперь вы можете выполнять в 3 раза больше запросов на чтение! Разве это не здорово?

Ловушка

Попался! Мы немедленно потеряли C в гарантиях ACID нашей реляционной базы данных , что означает согласованность.

Видите ли, теперь существует возможность, при которой мы вставляем новую запись в базу данных, сразу после этого выдаем для нее запрос на чтение и ничего не получаем обратно, как будто ее не существует!

Передача новой информации от первичной реплики к реплике не происходит мгновенно. На самом деле существует временное окно, в котором вы можете получить устаревшую информацию. Если бы это было не так, ваша производительность записи пострадала бы, так как ей пришлось бы синхронно ждать распространения данных.

Распределенные системы имеют несколько компромиссов. Если вы хотите адекватно масштабировать, вам придется смириться с этой конкретной проблемой.

Продолжая масштабировать

Используя подход базы данных реплик, мы можем до некоторой степени горизонтально масштабировать наш трафик чтения. Это здорово, но мы наткнулись на стену в отношении нашего трафика записи - он все еще находится на одном сервере!

Здесь у нас не так много вариантов. Нам просто нужно разделить наш трафик записи на несколько серверов, так как один не может его обработать.

Один из способов - использовать стратегию репликации с несколькими основными источниками. Там вместо реплик, с которых вы можете только читать, у вас есть несколько основных узлов, поддерживающих чтение и запись. К сожалению, это очень быстро усложняется, поскольку теперь у вас есть возможность создавать конфликты (например, вставлять две записи с одинаковым идентификатором).

Давайте воспользуемся другой техникой, называемой шардингом(также называется секционированием ).

С помощью шардинга вы разделяете свой сервер на несколько меньших серверов, называемых шардами. Все эти шарды содержат разные записи - вы создаете правило относительно того, какие записи входят в какой шард. Очень важно создать такое правило, чтобы данные распределялись равномерно .

Возможный подход к этому - определить диапазоны в соответствии с некоторой информацией о записи (например, пользователи с именем AD).

Этот ключ сегментирования следует выбирать очень осторожно, поскольку нагрузка не всегда одинакова для произвольных столбцов. (например, у большего числа людей имена начинаются с C, а не с Z ). Одиночный осколок, который получает больше запросов, чем другие, называется горячей точкой, и его следует избегать. После разделения повторное сегментирование данных становится невероятно дорогостоящим и может привести к значительному простою, как это было в случае печально известного 11-часового перебоя в работе FourSquare.

Чтобы не усложнять наш пример, предположим, что наш клиент (приложение Rails) знает, какую базу данных использовать для каждой записи. Также стоит отметить, что существует множество стратегий для шардинга, и это простой пример, иллюстрирующий концепцию.

Мы уже довольно много выиграли - мы можем увеличить наш трафик записи в N раз, где N - количество шардов. Это практически не дает нам почти никаких ограничений - представьте, насколько детально мы можем получить это разбиение.

Ловушка

Все в программной инженерии - это более или менее компромисс, и это не исключение. Шардинг - задача не из простых, и ее лучше избегать, пока она действительно не понадобится.

Мы сделали запросы по ключамкроме разделенного ключа невероятно неэффективно (им нужно пройти через все шарды). SQL- JOINзапросы еще хуже, и сложные запросы становятся практически непригодными.

Децентрализованные против распределенных

Прежде чем мы продолжим, я хотел бы провести различие между этими двумя терминами.

Несмотря на то, что слова звучат одинаково и логически могут означать одно и то же, их различие оказывает значительное технологическое и политическое влияние.

Децентрализованные по-прежнему распределены в техническом смысле, но все децентрализованные системы не принадлежат одному субъекту. Ни одна компания не может владеть децентрализованной системой, иначе она больше не была бы децентрализованной.

Это означает, что большинство систем, которые мы рассмотрим сегодня, можно рассматривать как распределенные централизованные системы - и именно этим они созданы.

Если задуматься - сложнее создать децентрализованную систему, потому что тогда вам нужно справиться со случаем, когда некоторые из участников являются злонамеренными. Это не относится к обычным распределенным системам, поскольку вы знаете, что все узлы принадлежат вам.

Примечание. Это определение часто обсуждается, и его можно спутать с другими (одноранговое, федеративное). В ранней литературе это тоже определялось по-другому. Тем не менее, то, что я дал вам в качестве определения, - это то, что, как мне кажется, наиболее широко используется сейчас, когда этот термин популяризировали блокчейн и криптовалюты.

Категории распределенных систем

Теперь мы рассмотрим пару категорий распределенных систем и перечислим их наиболее широко известные производственные применения. Имейте в виду, что большинство таких цифр устарели и, скорее всего, значительно больше на момент чтения этого сообщения.

Распределенные хранилища данных

Распределенные хранилища данных наиболее широко используются и известны как распределенные базы данных. Большинство распределенных баз данных - это нереляционные базы данных NoSQL, ограниченные семантикой «ключ-значение». Они обеспечивают невероятную производительность и масштабируемость за счет согласованности или доступности.

Известный масштаб - Apple, как известно, использует 75000 узлов Apache Cassandra, хранящих более 10 петабайт данных, еще в 2015 году.

Мы не можем углубляться в обсуждение распределенных хранилищ данных, не представив сначала теорему CAP.

Теорема CAP

Доказанная еще в 2002 году теорема CAP утверждает, что распределенное хранилище данных не может одновременно быть согласованным, доступным и устойчивым к разделам.

Несколько быстрых определений:

  • Согласованность - то, что вы читаете и записываете последовательно, это то, что вы ожидаете (помните ошибку с репликацией базы данных несколько абзацев назад?)
  • Доступность - вся система не умирает - каждый исправный узел всегда возвращает ответ.
  • Толерантность к разделам - система продолжает функционировать и обеспечивать гарантии согласованности / доступности, несмотря на наличие сетевых разделов.

На самом деле допуск разделения должен быть задан для любого распределенного хранилища данных. Как упоминалось во многих местах, в том числе в этой замечательной статье, согласованность и доступность невозможны без допустимости разделов.

Подумайте об этом: если у вас есть два узла, которые принимают информацию, и их соединение прерывается - как они оба станут доступными и одновременно обеспечат вам согласованность? У них нет возможности узнать, что делает другой узел, и поэтому они могут либо отключиться (недоступны), либо работать с устаревшей информацией (несогласованные) .

В конце концов, вам остается выбрать, хотите ли вы, чтобы ваша система была строго согласованной или высокодоступной в сетевом разделе .

Практика показывает, что для большинства приложений доступность важнее. Вам не обязательно всегда нужна сильная последовательность. Даже в этом случае этот компромисс не обязательно должен быть сделан потому, что вам нужна 100% гарантия доступности, а скорее потому, что задержка в сети может быть проблемой при необходимости синхронизации машин для достижения высокой согласованности. Эти и другие факторы заставляют приложения обычно выбирать решения, обеспечивающие высокую доступность.

В таких базах данных используется самая слабая модель согласованности - конечная согласованность (объяснение сильной и конечной согласованности) . Эта модель гарантирует, что, если для данного элемента не производится никаких новых обновлений, в конечном итоге все обращения к этому элементу будут возвращать последнее обновленное значение.

Эти системы предоставляют свойства BASE (в отличие от ACID традиционных баз данных)

  • B asically A vailable - система всегда возвращает ответ
  • S часто состояние - Система может изменяться с течением времени, даже во время без входа (из - за возможную последовательность)
  • Е вентальная согласованность - при отсутствии ввода данные рано или поздно распространятся на каждый узел - таким образом, они станут согласованными.

Примеры таких доступных распределенных баз данных - Cassandra, Riak, Voldemort

Конечно, есть и другие хранилища данных, которые предпочитают более высокую согласованность - HBase, Couchbase, Redis, Zookeeper.

Теорема CAP сама по себе достойна нескольких статей - некоторые из них посвящены тому, как можно настроить свойства CAP системы в зависимости от того, как ведет себя клиент, а другие - о том, как это не понимается должным образом.

Кассандра

Cassandra, как упоминалось выше, представляет собой распределенную базу данных без SQL, которая предпочитает свойства AP вне CAP, обеспечивая в конечном итоге согласованность. Я должен признать, что это может вводить в заблуждение, так как Cassandra легко настраивается - вы можете сделать так, чтобы она обеспечивала сильную согласованность за счет доступности, но это не общий вариант использования.

Cassandra использует согласованное хеширование, чтобы определить, какие узлы за пределами вашего кластера должны управлять данными, которые вы передаете. Вы устанавливаете коэффициент репликации , который в основном указывает, сколько узлов вы хотите реплицировать свои данные.

При чтении вы будете читать только с этих узлов.

Cassandra обладает огромной масштабируемостью, обеспечивая абсурдно высокую пропускную способность записи.

Несмотря на то, что эта диаграмма может быть предвзятой и похоже, что она сравнивает Cassandra с базами данных, настроенными для обеспечения строгой согласованности (иначе я не могу понять, почему MongoDB упадет в производительности при обновлении с 4 до 8 узлов), это все равно должно показать, что правильно настроено вверх Кластер Cassandra способен.

Несмотря на это, в распределенных системах компромисс, который обеспечивает горизонтальное масштабирование и невероятно высокую пропускную способность, Cassandra не предоставляет некоторых фундаментальных функций баз данных ACID, а именно транзакций.

Консенсус

Транзакции базы данных сложно реализовать в распределенных системах, поскольку они требуют, чтобы каждый узел согласовал правильное действие (прерывание или фиксация). Это называется консенсусом и является фундаментальной проблемой в распределенных системах.

Достижение типа соглашения, необходимого для проблемы «фиксации транзакции», несложно, если участвующие процессы и сеть полностью надежны. Однако реальные системы подвержены ряду возможных сбоев, таких как сбои процессов, разделение сети и потеря, искажение или дублирование сообщений.

Это создает проблему - оказалось, что невозможно гарантировать достижение правильного консенсуса в течение ограниченного периода времени в ненадежной сети.

Однако на практике есть алгоритмы, которые довольно быстро достигают консенсуса в ненадежной сети. Cassandra фактически обеспечивает легкие транзакции за счет использования алгоритма Paxos для распределенного консенсуса.

Распределенных вычислений

Распределенные вычисления - это ключ к тому потоку обработки больших данных, который мы наблюдали в последние годы. Это метод разделения огромной задачи (например, совокупности 100 миллиардов записей), которую ни один компьютер не может практически выполнить самостоятельно, на множество более мелких задач, каждая из которых может уместиться в одной стандартной машине. Вы разделяете свою огромную задачу на множество более мелких, заставляете их выполняться на многих машинах параллельно, соответствующим образом агрегируете данные, и вы решили свою первоначальную проблему. Этот подход снова позволяет вам масштабировать по горизонтали - когда у вас есть более крупная задача, просто включите в расчет больше узлов.

Known Scale - в 2012 году у Folding @ Home было 160 тыс. Активных машин.

Первым новатором в этой области был Google, которому из-за необходимости большого объема данных пришлось изобрести новую парадигму распределенных вычислений - MapReduce. Они опубликовали статью об этом в 2004 году, а позже сообщество разработчиков открытого исходного кода создало на его основе Apache Hadoop.

Уменьшение карты

MapReduce можно просто определить как два шага - сопоставление данных и их сокращение до чего-то значимого.

Давайте снова рассмотрим это на примере:

Допустим, мы являемся Medium и храним огромный объем нашей информации во вторичной распределенной базе данных для складских целей. Мы хотим получить данные, представляющие количество хлопков, выпускаемых каждый день в течение апреля 2017 года (год назад).

Этот пример максимально короткий, ясный и простой, но представьте, что мы работаем с огромным количеством данных (например, анализируем миллиарды хлопков в ладоши). Очевидно, что мы не будем хранить всю эту информацию на одной машине, и мы не будем анализировать все это только на одной машине. Мы также будем запрашивать не производственную базу данных, а некую «складскую» базу данных, созданную специально для низкоприоритетных автономных заданий.

Каждое задание карты - это отдельный узел, преобразующий как можно больше данных. Каждое задание просматривает все данные в данном узле хранения и сопоставляет их с простым кортежем даты и номера один. Затем выполняются три промежуточных шага (о которых никто не говорит) - перемешивание, сортировка и разделение. Они в основном упорядочивают данные и удаляют их в соответствующее задание сокращения. Поскольку мы имеем дело с большими данными, каждое задание Reduce разделено для работы только на одну дату.

Это хорошая парадигма, которая, на удивление, позволяет вам многое с ней делать - например, вы можете связать несколько заданий MapReduce.

Лучшие методы

MapReduce в настоящее время является устаревшим и вызывает некоторые проблемы. Поскольку он работает партиями (заданиями), возникает проблема, когда в случае сбоя задания вам необходимо перезапустить все это. Сбой двухчасового задания может действительно замедлить весь конвейер обработки данных, а вы этого ни в коем случае не хотите, особенно в часы пик.

Еще одна проблема - время ожидания результатов. В аналитических системах в реальном времени (которые все имеют большие данные и, следовательно, используют распределенные вычисления) важно, чтобы ваши последние обработанные данные были как можно более свежими, и уж точно не данными, полученными несколько часов назад.

Таким образом, появились другие архитектуры, которые решают эти проблемы. А именно Lambda Architecture (сочетание пакетной обработки и потоковой обработки) и Kappa Architecture (только потоковая обработка). Эти достижения в этой области принесли им новые инструменты - Kafka Streams, Apache Spark, Apache Storm, Apache Samza.

Распределенные файловые системы

Распределенные файловые системы можно рассматривать как распределенные хранилища данных. Это то же самое, что и концепция - хранение и доступ к большому количеству данных в кластере машин, представляющих собой единое целое. Обычно они идут рука об руку с распределенными вычислениями.

Известный масштаб - Yahoo известен тем, что запустил HDFS на более чем 42000 узлов для хранения 600 петабайт данных еще в 201 году.

Википедия определяет различие в том, что распределенные файловые системы позволяют получать доступ к файлам с использованием тех же интерфейсов и семантики, что и локальные файлы, а не через специальный API, такой как Cassandra Query Language (CQL).

HDFS

Распределенная файловая система Hadoop (HDFS) - это распределенная файловая система, используемая для распределенных вычислений через структуру Hadoop. Получив широкое распространение, он используется для хранения и репликации больших файлов (размером в ГБ или ТБ) на многих машинах.

Его архитектура состоит в основном из NameNodes и DataNodes . NameNodes отвечают за хранение метаданных о кластере, например, какой узел содержит какие блоки файлов. Они действуют как координаторы сети, выясняя, где лучше всего хранить и реплицировать файлы, отслеживая состояние системы. DataNodes просто хранят файлы и выполняют такие команды, как репликация файла, запись нового и другие.

Неудивительно, что HDFS лучше всего использовать с Hadoop для вычислений, поскольку он обеспечивает осведомленность о данных для вычислительных заданий. Затем указанные задания запускаются на узлах, хранящих данные. Это увеличивает локальность данных - оптимизирует вычисления и снижает объем трафика в сети.

IPFS

Межпланетная файловая система (IPFS) - это новый захватывающий одноранговый протокол / сеть для распределенной файловой системы. Используя технологию Blockchain, он может похвастаться полностью децентрализованной архитектурой без единого владельца и точки отказа.

IPFS предлагает систему именования (аналогичную DNS), называемую IPNS, и позволяет пользователям легко получать доступ к информации. Он хранит файл через историческое управление версиями, аналогично тому, как это делает Git. Это позволяет получить доступ ко всем предыдущим состояниям файла.

Он все еще находится в стадии интенсивной разработки (v0.4 на момент написания), но уже видел проекты, заинтересованные в создании на нем (FileCoin).

Распределенный обмен сообщениями

Системы обмена сообщениями обеспечивают центральное место для хранения и распространения сообщений / событий внутри вашей общей системы. Они позволяют отделить логику вашего приложения от прямого взаимодействия с другими системами.

Известный масштаб. Кластер LinkedIn Kafka обрабатывал 1 триллион сообщений в день с пиковыми значениями 4,5 миллиона сообщений в секунду.

Проще говоря, платформа обмена сообщениями работает следующим образом:

Сообщение транслируется из приложения, которое потенциально его создает (называемого производителем ), передается на платформу и читается потенциально несколькими приложениями, которые в нем заинтересованы (называемые потребителями ).

Если вам нужно сохранить определенное событие в нескольких местах (например, создание пользователя в базе данных, на складе, в службе отправки электронной почты и во всем, что вы можете придумать), платформа обмена сообщениями - самый чистый способ распространения этого сообщения.

Потребители могут либо получать информацию от брокеров (модель вытягивания), либо заставлять брокеров передавать информацию непосредственно потребителям (модель выталкивания).

Есть несколько популярных первоклассных платформ обмена сообщениями:

RabbitMQ - брокер сообщений, который позволяет более детально управлять траекториями сообщений с помощью правил маршрутизации и других легко настраиваемых параметров. Его можно назвать умным брокером, так как в нем много логики и он тщательно отслеживает сообщения, которые проходят через него. Предоставляет настройки как для AP, так и для CP из CAP . Использует push-модель для уведомления потребителей.

Kafka - брокер сообщений (и вся платформа), который находится на более низком уровне, так как в нем не отслеживается, какие сообщения были прочитаны, и не допускается сложная логика маршрутизации. Это помогает достичь потрясающей производительности. На мой взгляд, это самая большая перспектива в этой области с активной разработкой со стороны сообщества разработчиков ПО с открытым исходным кодом и поддержкой команды Confluent. Kafka, вероятно, наиболее широко используется ведущими технологическими компаниями. Я написал подробное введение к этому, где подробно расскажу обо всех его достоинствах.

Apache ActiveMQ - самый старый из группы, датируемый 2004 годом. Использует JMS API, что означает, что он ориентирован на приложения Java EE. Он был переписан на ActiveMQ Artemis, который обеспечивает выдающуюся производительность на уровне Kafka.

Amazon SQS - сервис обмена сообщениями, предоставляемый AWS. Позволяет быстро интегрировать его с существующими приложениями и избавляет от необходимости управлять собственной инфраструктурой, что может быть большим преимуществом, поскольку такие системы, как Kafka, как известно, сложно настроить. Amazon также предлагает два похожих сервиса - SNS и MQ, последний из которых в основном является ActiveMQ, но управляется Amazon.

Распределенные приложения

Если вы объедините 5 серверов Rails за одним балансировщиком нагрузки, все они подключены к одной базе данных, можно ли назвать это распределенным приложением? Вспомните мое определение сверху:

Распределенная система - это группа компьютеров, работающих вместе, чтобы конечный пользователь выглядел как один компьютер. Эти машины имеют общее состояние, работают одновременно и могут выходить из строя независимо, не влияя на время безотказной работы всей системы.

Если вы считаете базу данных разделяемым состоянием, вы можете возразить, что ее можно классифицировать как распределенную систему, но вы ошибаетесь, поскольку вы пропустили часть определения « совместная работа ».

Система является распределенной, только если узлы взаимодействуют друг с другом для координации своих действий.

Поэтому что-то вроде приложения, выполняющего свой внутренний код в одноранговой сети, лучше классифицировать как распределенное приложение. Тем не менее, это все ненужная классификация, которая не служит никакой цели, а показывает, насколько мы привередливы в группировании вещей.

Известный масштаб - BitTorrent-рой из 193 000 узлов для эпизода Игры престолов, апрель 2014 г.

Виртуальная машина Erlang

Erlang - это функциональный язык с отличной семантикой для параллелизма, распределения и отказоустойчивости. Виртуальная машина Erlang сама обрабатывает распространение приложения Erlang.

Его модель работает за счет наличия множества изолированных легковесных процессов, каждый из которых может общаться друг с другом через встроенную систему передачи сообщений. Это называется актерской моделью.а библиотеки Erlang OTP можно рассматривать как распределенную структуру акторов (по аналогии с Akka для JVM).

Модель - это то, что помогает достичь большого параллелизма довольно просто - процессы распределены по доступным ядрам системы, в которой они запущены. Поскольку это неотличимо от сетевых настроек (помимо возможности отбрасывать сообщения), виртуальная машина Erlang может подключаться к другим виртуальным машинам Erlang, работающим в том же центре обработки данных или даже на другом континенте. Этот рой виртуальных машин запускает одно отдельное приложение и обрабатывает сбои машин с помощью передачи управления (запуск другого узла планируется).

Фактически, распределенный уровень языка был добавлен для обеспечения отказоустойчивости. Программное обеспечение, работающее на одной машине, всегда подвержено риску того, что эта единственная машина выйдет из строя и ваше приложение отключится. Программное обеспечение, работающее на многих узлах, упрощает обработку сбоев оборудования, если приложение было создано с учетом этого.

BitTorrent

BitTorrent - один из наиболее широко используемых протоколов для передачи больших файлов через Интернет через торренты. Основная идея состоит в том, чтобы облегчить передачу файлов между разными одноранговыми узлами в сети без необходимости проходить через главный сервер.

Используя клиент BitTorrent, вы подключаетесь к нескольким компьютерам по всему миру для загрузки файла. Когда вы открываете файл .torrent, вы подключаетесь к так называемому трекеру , который представляет собой машину, которая действует как координатор. Это помогает в обнаружении одноранговых узлов, показывая вам узлы в сети, у которых есть нужный вам файл.

У вас есть два типа пользователей: пиявка и сеялка . Пиявщик - это пользователь, который загружает файл, а сидер - это пользователь, который загружает указанный файл.

Самое забавное в одноранговых сетях заключается в том, что вы, как обычный пользователь, имеете возможность присоединиться к сети и внести свой вклад в нее.

BitTorrent и его предшественники (Gnutella, Napster) позволяют добровольно размещать файлы и загружать их другим пользователям, которым они нужны. Причина, по которой BitTorrent так популярен, заключается в том, что он был первым в своем роде, предлагающим стимулы для участия в сети. Фрирайдинг , когда пользователь мог загружать только файлы, был проблемой с предыдущими протоколами обмена файлами.

BitTorrent в некоторой степени решил проблему фрирайда, заставив сидеры загружать больше тем, у кого лучшая скорость загрузки. Он работает, стимулируя вас загружать файлы одновременно с загрузкой. К сожалению, после того, как вы закончите, ничто не заставит вас оставаться активным в сети. Это приводит к нехватке сидеров в сети, у которых есть полный файл, и, поскольку протокол сильно зависит от таких пользователей, появились такие решения, как частные трекеры. Приватные трекеры требуют, чтобы вы были членом сообщества (часто только по приглашению), чтобы участвовать в распределенной сети.

После достижений в этой области были изобретены торренты без трекера. Это было обновление протокола BitTorrent, который не полагался на централизованные трекеры для сбора метаданных и поиска пиров, а вместо этого использовал новые алгоритмы. Одним из таких примеров является Kademlia (Mainline DHT), распределенная хеш-таблица (DHT), которая позволяет вам находить одноранговые узлы через других одноранговых узлов. Фактически, каждый пользователь выполняет обязанности трекера.

Распределенные реестры

Распределенный реестр можно рассматривать как неизменяемую базу данных с возможностью добавления, которая реплицируется, синхронизируется и используется всеми узлами распределенной сети.

Известный масштаб - 4 января 2018 года у сети Ethereum был пик в 1,3 миллиона транзакций в день.

Они используют шаблон Event Sourcing, позволяя вам восстановить состояние реестра в любой момент его истории.

Блокчейн

Блокчейн - это текущая базовая технология, используемая для распределенных реестров, и фактически положила начало их деятельности. Это последнее и величайшее нововведение в распределенном пространстве позволило создать первый в истории действительно распределенный платежный протокол - Биткойн.

Блокчейн - это распределенный реестр, содержащий упорядоченный список всех транзакций, которые когда-либо происходили в его сети. Транзакции группируются и хранятся в блоках. Вся цепочка блоков - это, по сути, связанный список блоков (отсюда и название) . Такие блоки требуют больших вычислительных ресурсов для создания и тесно связаны друг с другом посредством криптографии.

Проще говоря, каждый блок содержит специальный хэш (который начинается с X нулей) содержимого текущего блока (в форме дерева Меркла) плюс хеш предыдущего блока. Для создания этого хэша требуется много ресурсов процессора, потому что единственный способ получить его - это использовать грубую силу.

Майнеры - это узлы, которые пытаются вычислить хеш (с помощью брутфорса). Все майнеры соревнуются друг с другом за то, кто может предложить случайную строку (называемую одноразовым кодом ), которая при объединении с содержимым дает вышеупомянутый хеш. Как только кто-то находит правильный одноразовый номер - он транслирует его по всей сети. Затем указанная строка проверяется каждым узлом отдельно и принимается в их цепочку.

Это превращается в систему, в которой абсурдно дорого модифицировать блокчейн и абсурдно легко проверить, что в него не вмешиваются.

Изменение содержимого блока обходится дорого, потому что это приведет к получению другого хеша. Помните, что от него зависит хеш каждого последующего блока. Если бы вы изменили транзакцию в первом блоке изображения выше - вы бы изменили корень Меркла. Это, в свою очередь, изменит хэш блока (скорее всего, без необходимых начальных нулей) - это изменит хэш блока №2 и так далее, и так далее. Это означает, что вам нужно будет подобрать новый одноразовый номер для каждого блока после того, который вы только что изменили.

Сеть всегда доверяет и воспроизводит самую длинную действительную цепочку. Чтобы обмануть систему и в конечном итоге создать более длинную цепочку, вам потребуется более 50% общей мощности процессора, используемой всеми узлами.

Блокчейн можно рассматривать как распределенный механизм для возникающего консенсуса . Консенсус не достигается в явном виде - нет выборов или фиксированного момента, когда достигается консенсус. Вместо этого консенсус - это возникающий продукт асинхронного взаимодействия тысяч независимых узлов, которые следуют правилам протокола.

Эта беспрецедентная инновация недавно вызвала бум в сфере технологий, и люди предсказывают, что она ознаменует создание Web 3.0. На данный момент это определенно самое захватывающее пространство в мире разработки программного обеспечения, наполненное чрезвычайно сложными и интересными проблемами, ожидающими своего решения.

Биткойн

То, чего не хватало в предыдущих протоколах распределенных платежей, было способом практически предотвратить проблему двойных расходов в режиме реального времени распределенным образом. Исследования дали интересные предложения [1], но Биткойн был первым, кто реализовал практическое решение с явными преимуществами перед другими.

Проблема двойного расходования утверждает, что субъект (например, Боб) не может потратить свой единственный ресурс в двух местах. Если у Боба есть 1 доллар, он не сможет передать его одновременно Алисе и Заку - это всего лишь один актив, его нельзя дублировать. Оказывается, действительно сложно добиться этой гарантии в распределенной системе. Есть несколько интересных подходов к смягчению последствий, предшествующих блокчейну, но они не решают проблему полностью на практике.

Биткойн легко решает проблему двойных расходов, так как за раз в цепочку добавляется только один блок. Двойное расходование невозможно в пределах одного блока, поэтому даже если два блока будут созданы одновременно, только один окажется в конечной самой длинной цепочке.

Биткойн полагается на сложность накопления мощности процессора.

В то время как в системе голосования злоумышленнику нужно только добавить узлы в сеть (что легко, поскольку свободный доступ к сети является целью проектирования), в схеме, основанной на мощности процессора, злоумышленник сталкивается с физическим ограничением: получение доступа ко все большему и большему количеству мощное оборудование.

Это также причина, по которой злонамеренные группы узлов должны контролировать более 50% вычислительной мощности сети, чтобы фактически проводить любую успешную атаку. Меньше этого, и остальная часть сети быстрее создаст более длинный блокчейн.

Ethereum

Ethereum можно рассматривать как программируемую программную платформу на основе блокчейна. У него есть собственная криптовалюта (эфир), которая способствует развертыванию смарт-контрактов на его блокчейне.

Смарт-контракты - это фрагменты кода, которые хранятся в виде единой транзакции в цепочке блоков Ethereum. Чтобы запустить код, все, что вам нужно сделать, это выполнить транзакцию со смарт-контрактом в качестве пункта назначения. Это, в свою очередь, заставляет узлы-майнеры выполнять код и любые его изменения. Код выполняется внутри виртуальной машины Ethereum.

Solidity , родной язык программирования Ethereum, используется для написания смарт-контрактов. Это полный по Тьюрингу язык программирования, который напрямую взаимодействует с блокчейном Ethereum, позволяя запрашивать состояние, такое как балансы или другие результаты смарт-контрактов. Чтобы предотвратить бесконечные циклы, для запуска кода требуется некоторое количество эфира.

Поскольку блокчейн можно интерпретировать как серию изменений состояния , многие распределенные приложения (DApps) были созданы на основе Ethereum и аналогичных платформ.

Дальнейшее использование распределенных реестров

Доказательство существования - служба для анонимного и безопасного хранения доказательств существования определенного цифрового документа в определенный момент времени. Полезно для обеспечения целостности документа, владения и отметки времени.

Децентрализованные автономные организации (DAO) - организации, которые используют блокчейн как средство достижения консенсуса по предложениям организации по улучшению. Примеры - система управления Dash, проект SmartCash.

Децентрализованная аутентификация - сохраните вашу личность в блокчейне, что позволит вам везде использовать единый вход (SSO). Соврин, Цивик

И многие, многие другие. Технология распределенного реестра действительно открывала безграничные возможности. Некоторые из них, скорее всего, были изобретены, пока мы говорим!

Резюме

За короткий промежуток времени в этой статье нам удалось определить, что такое распределенная система, почему вы должны ее использовать, и немного перебрать каждую категорию. Вот некоторые важные вещи, о которых следует помнить:

  • Распределенные системы сложны
  • Их выбирают исходя из масштаба и цены.
  • С ними труднее работать
  • Теорема CAP - компромисс согласованности / доступности
  • У них есть 6 категорий - хранилища данных, вычисления, файловые системы, системы обмена сообщениями, бухгалтерские книги, приложения.

Откровенно говоря, мы едва коснулись поверхности распределенных систем. У меня не было возможности подробно рассмотреть и объяснить основные проблемы, такие как консенсус, стратегии репликации, порядок событий и время, отказоустойчивость, рассылка сообщения по сети и другие.

Осторожно

Позвольте мне оставить вас с прощальным предупреждением:

Вы должны как можно больше уходить от распределенных систем. Накладные расходы на сложность, которые они несут сами по себе, не стоят затраченных усилий, если вы можете избежать проблемы, решив ее другим способом или каким-то другим готовым решением.

[1]

Борьба с двойными расходами с использованием кооперативных P2P-систем, 25–27 июня 2007 г. - предлагаемое решение, в котором срок действия каждой «монеты» может истечь, и для нее назначается свидетель (валидатор).

Bitgold , декабрь 2005 г. - Общий обзор протокола, очень похожего на протокол Биткойна. Говорят, что это предшественник Биткойна.

Дополнительная литература по распределенным системам:

Разработка приложений с интенсивным использованием данных, Мартин Клеппманн - отличная книга, в которой рассказывается обо всем в распределенных системах и многом другом.

Специализация по облачным вычислениям, Университет Иллинойса, Coursera - длинная серия курсов (6), посвященных концепциям распределенных систем и приложений.

Jepsen - Блог, объясняющий множество распределенных технологий (ElasticSearch, Redis, MongoDB и т. Д.)

Спасибо, что нашли время прочитать эту длинную (~ 5600 слов) статью!

Если по какой-либо причине вы нашли это информативным или сочли, что это принесло вам пользу, пожалуйста, не забудьте дать ему столько хлопков, сколько вы считаете, что он заслуживает, и подумайте о том, чтобы поделиться с другом, который мог бы использовать введение в эту замечательную область исследования.

~ Станислав Козловский

Обновить

В настоящее время я работаю в Confluent. Confluent - компания, занимающаяся большими данными, основанная самими создателями Apache Kafka! Я безмерно благодарен за предоставленную мне возможность - в настоящее время я работаю над самой Kafka, и это просто потрясающе! Мы в Confluent помогаем формировать всю экосистему Kafka с открытым исходным кодом, включая новое управляемое облачное предложение Kafka-as-a-service.

Мы нанимаем на множество должностей (особенно инженеров SRE / Software) в Европе и США! Если вы заинтересованы в работе над самой Kafka, ищете новые возможности или просто любопытно - обязательно напишите мне в Twitter, и я поделюсь всеми замечательными преимуществами, которые дает работа в компании, расположенной в районе залива.