One place for hosting & domains

      данных

      Использование JavaScript Fetch API для получения данных


      Введение

      Было время, когда для запросов API использовался XMLHttpRequest. В нем не было промисов, и он не позволял создавать чистый код JavaScript. В jQuery мы использовали более чистый синтаксис с jQuery.ajax().

      Сейчас JavaScript имеется собственный встроенный способ отправки запросов API. Это Fetch API, новый стандарт создания серверных запросов с промисами, также включающий много других возможностей.

      В этом учебном модуле мы создадим запросы GET и POST, используя Fetch API.

      Предварительные требования

      Для этого обучающего модуля вам потребуется следующее:

      Шаг 1 — Введение в синтаксис Fetch API

      Чтобы использовать Fetch API, вызовите метод fetch, который принимает URL API в качестве параметра:

      fetch(url)
      

      После метода fetch() нужно включить метод промиса then():

      .then(function() {
      
      })
      

      Метод fetch() возвращает промис. Если возвращается промис resolve, будет выполнена функция метода then(). Эта функция содержит код для обработки данных, получаемых от API.

      Под методом then() следует включить метод catch():

      .catch(function() {
      
      });
      

      API, вызываемый с помощью метода fetch(), может не работать или на нем могут возникнуть ошибки. Если это произойдет, будет возвращен промис reject. Метод catch используется для обработки reject. Код метода catch() выполняется в случае возникновения ошибки при вызове выбранного API.

      В целом, использование Fetch API выглядит следующим образом:

      fetch(url)
      .then(function() {
      
      })
      .catch(function() {
      
      });
      

      Теперь мы понимаем синтаксис использования Fetch API и можем переходить к использованию fetch() с реальным API.

      Шаг 2 — Использование Fetch для получения данных от API

      Следующие примеры кода основаны на Random User API. Используя API, вы получаете десять пользователей и выводите их на странице, используя Vanilla JavaScript.

      Идея заключается в том, чтобы получить все данные от Random User API и вывести их в элементах списка внутри списка автора. Для начала следует создать файл HTML и добавить в него заголовок и неупорядоченный список с идентификатором authors:

      <h1>Authors</h1>
      <ul id="authors"></ul>
      

      Теперь добавьте теги script в конец файла HTML и используйте селектор DOM для получения ul. Используйте getElementById с аргументом authors. Помните, что authors — это идентификатор ранее созданного ul:

      <script>
      
          const ul = document.getElementById('authors');
      
      </script>
      

      Создайте постоянную переменную url, в которой будет храниться URL-адрес API, который вернет десять случайных пользователей:

      const url="https://randomuser.me/api/?results=10";
      

      Теперь у нас есть ul и url, и мы можем создать функции, которые будут использоваться для создания элементов списка. Создайте функцию под названием createNode, принимающую параметр с именем element:

      function createNode(element) {
      
      }
      

      Впоследствии, при вызове createNode, вам нужно будет передать имя создаваемого элемента HTML.

      Добавьте в функцию выражение return, возвращающее element, с помощью document.createElement():

      function createNode(element) {
          return document.createElement(element);
      }
      

      Также вам нужно будет создать функцию с именем append, которая принимает два параметра: parent и el:

      function append(parent, el) {
      
      }
      

      Эта функция будет добавлять el к parent, используя document.createElement:

      function append(parent, el) {
          return parent.appendChild(el);
      }
      

      Теперь и createNode, и append готовы к использованию. Используя Fetch API, вызовите Random User API, добавив к fetch() аргумент url:

      fetch(url)
      
      fetch(url)
        .then(function(data) {
      
          })
        })
        .catch(function(error) {
      
        });
      

      В вышеуказанном коде вы вызываете Fetch API и передаете URL в Random User API. После этого поступает ответ. Однако ответ вы получите не в формате JSON, а в виде объекта с серией методов, которые можно использовать в зависимости от того, что вы хотите делать с информацией. Чтобы конвертировать возвращаемый объект в формат JSON, используйте метод json().

      Добавьте метод then(), содержащий функцию с параметром resp:

      fetch(url)
      .then((resp) => )
      

      Параметр resp принимает значение объекта, возвращаемого fetch(url). Используйте метод json(), чтобы конвертировать resp в данные JSON:

      fetch(url)
      .then((resp) => resp.json())
      

      При этом данные JSON все равно необходимо обработать. Добавьте еще одно выражение then() с функцией, имеющей аргумент с именем data:

      .then(function(data) {
      
          })
      })
      

      Создайте в этой функции переменную с именем authors, принимающую значение data.results:

      .then(function(data) {
          let authors = data.results;
      

      Для каждого автора в переменной authors нам нужно создать элемент списка, выводящий портрет и имя автора. Для этого отлично подходит метод map():

      let authors = data.results;
      return authors.map(function(author) {
      
      })
      

      Создайте в функции map переменную li, которая будет равна createNode с li (элемент HTML) в качестве аргумента:

      return authors.map(function(author) {
          let li = createNode('li');
      })
      

      Повторите эту процедуру, чтобы создать элемент span и элемент img:

      let li = createNode('li');
      let img = createNode('img');
      let span = createNode('span');
      

      Предлагает имя автора и портрет, идущий вместе с именем. Установите в img.src портрет автора:

      let img = createNode('img');
      let span = createNode('span');
      
      img.src = author.picture.medium;
      

      Элемент span должен содержать имя и фамилию автора. Для этого можно использовать свойство innerHTML и интерполяцию строк:

      img.src = author.picture.medium;
      span.innerHTML = `${author.name.first} ${author.name.last}`;
      

      Когда изображение и элемент списка созданы вместе с элементом span, вы можете использовать функцию append, которую мы ранее добавили для отображения этих элементов на странице:

      append(li, img);
      append(li, span);
      append(ul, li);
      

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

      .catch(function(error) {
        console.log(error);
      });
      

      Это полный код запроса, который вы создали:

      function createNode(element) {
          return document.createElement(element);
      }
      
      function append(parent, el) {
        return parent.appendChild(el);
      }
      
      const ul = document.getElementById('authors');
      const url="https://randomuser.me/api/?results=10";
      
      fetch(url)
      .then((resp) => resp.json())
      .then(function(data) {
        let authors = data.results;
        return authors.map(function(author) {
          let li = createNode('li');
          let img = createNode('img');
          let span = createNode('span');
          img.src = author.picture.medium;
          span.innerHTML = `${author.name.first} ${author.name.last}`;
          append(li, img);
          append(li, span);
          append(ul, li);
        })
      })
      .catch(function(error) {
        console.log(error);
      });
      

      Вы только что успешно выполнили запрос GET, используя Random User API и Fetch API. На следующем шаге вы научитесь выполнять запросы POST.

      Шаг 3 — Обработка запросов POST

      По умолчанию Fetch использует запросы GET, но вы также можете использовать и все другие типы запросов, изменять заголовки и отправлять данные. Для этого нужно задать объект и передать его как второй аргумент функции fetch.

      Прежде чем создать запрос POST, создайте данные, которые вы хотите отправить в API. Это будет объект с именем data с ключом name и значением Sammy (или вашим именем):

      const url="https://randomuser.me/api";
      
      let data = {
        name: 'Sammy'
      }
      

      Обязательно добавьте постоянную переменную, хранящую ссылку на Random User API.

      Поскольку это запрос POST, ее нужно будет указать явно. Создайте объект с именем fetchData:

      let fetchData = {
      
      }
      

      Этот объект должен содержать три ключа: method, body и headers. Ключ method должен иметь значение 'POST'. Для body следует задать значение только что созданного объекта data. Для headers следует задать значение new Headers():

      let fetchData = {
        method: 'POST',
        body: data,
        headers: new Headers()
      }
      

      Интерфейс Headers является свойством Fetch API, который позволяет выполнять различные действия с заголовками запросов и ответов HTTP. Если вы захотите узнать об этом больше, вы можете найти более подробную информацию в статье под названием Определение маршрутов и методов запросов HTTP в Express.

      С этим кодом можно составлять запросы POST, используя Fetch API. Мы добавим url и fetchData как аргументы запроса fetch POST:

      fetch(url, fetchData)
      

      Функция then() будет включать код, обрабатывающий ответ, получаемый от сервера Random User API:

      fetch(url, fetchData)
      .then(function() {
          // Handle response you get from the server
      });
      

      Есть и другая опция, позволяющая создать объект и использовать функцию fetch(). Вместо того, чтобы создавать такой объект как fetchData, вы можете использовать конструктор запросов для создания объекта запроса. Для этого нужно создать переменную с именем request:

      const url="https://randomuser.me/api";
      
      let data = {
        name: 'Sara'
      }
      
      var request =
      

      Для переменной request следует задать значение new Request. Конструкт new Request принимает два аргумента: URL API (url) и объект. В объекте также должны содержаться ключи method, body и headers, как и в fetchData:

      var request = new Request(url, {
          method: 'POST',
          body: data,
          headers: new Headers()
      });
      

      Теперь request можно использовать как единственный аргумент для fetch(), поскольку он также включает URL-адрес API:

      fetch(request)
      .then(function() {
          // Handle response we get from the API
      })
      

      В целом код будет выглядеть следующим образом:

      const url="https://randomuser.me/api";
      
      let data = {
        name: 'Sara'
      }
      
      var request = new Request(url, {
          method: 'POST',
          body: data,
          headers: new Headers()
      });
      
      fetch(request)
      .then(function() {
          // Handle response we get from the API
      })
      

      Теперь вы знаете два метода создания и выполнения запросов POST с помощью Fetch API.

      Заключение

      Хотя Fetch API поддерживается еще не всеми браузерами, он представляет собой отличную альтернативу XMLHttpRequest. Если вы хотите узнать, как вызывать Web API с помощью React, ознакомьтесь с этой статьей по данной теме.



      Source link

      Знакомство с реляционными базами данных


      Введение

      Системы управления базами данных (СУБД) — это компьютерные программы, которые позволяют пользователям взаимодействовать с базой данных. СУБД позволяет пользователям контролировать доступ к базе данных, записывать данные, запускать запросы и выполнять любые другие задачи, связанные с управлением базами данных.

      Однако для выполнения любой из этих задач СУБД должна иметь в основе модель, определяющую организацию данных. Реляционная модель — это один из подходов к организации данных, который широко используется в программном обеспечении баз данных с момента своего появления в конце 60-х годов. Этот подход настолько распространен, что на момент написания данной статьи четыре из пяти самых популярных систем управления базами данных являются реляционными.

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

      История реляционной модели

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

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

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

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

      Пример иерархической базы данных: классификация животных

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

      В конце 60-х годов Эдгар Ф. Кодд (Edgar F. Codd), программист из IBM, разработал реляционную модель управления базами данных. Реляционная модель Кодда позволила связать отдельные записи с несколькими таблицами, что дало возможность устанавливать между точками данных отношения «много ко многим» в дополнение к «один ко многим». Это обеспечило большую гибкость по сравнению с другими существующими моделями, если говорить о разработке структур баз данных, а значит реляционные системы управления базами данных (РСУБД) могли удовлетворить гораздо более широкий спектр бизнес-задач.

      Кодд предложил язык для управления реляционными данными, известный как Alpha , оказавший влияние на разработку более поздних языков баз данных. Коллеги Кодда из IBM, Дональд Чемберлен (Donald Chamberlin) и Рэймонд Бойс (Raymond Boyce), создали один из языков под влиянием языка Alpha. Они назвали свой язык SEQUEL, сокращенное название от Structured English Query Language (структурированный английский язык запросов), но из-за существующего товарного знака сократили название до SQL (более формальное название — структурированный язык запросов).

      Из-за ограниченных возможностей аппаратного обеспечения ранние реляционные базы данных были все еще непозволительно медленными, и потребовалось некоторое время, прежде чем технология получила широкое распространение. Но к середине 80-х годов реляционная модель Кодда была внедрена в ряд коммерческих продуктов по управлению базами данных от компании IBM и ее конкурентов. Вслед за IBM, эти поставщики также стали разрабатывать и применять свои собственные диалекты SQL. К 1987 году Американский национальный институт стандартов и Международная организация по стандартизации ратифицировали и опубликовали стандарты SQL, укрепив его статус признанного языка для управления РСУБД.

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

      Как реляционные базы данных структурируют данные

      Теперь, когда у вас есть общее понимание истории реляционной модели, давайте более подробно рассмотрим, как данная модель структурирует данные.

      Наиболее значимыми элементами реляционной модели являются отношения, которые известны пользователям и современным РСУБД как таблицы. Отношения — это набор кортежей, или строк в таблице, где каждый кортеж имеет набор атрибутов, или столбцов:

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

      Столбец — это наименьшая организационная структура реляционной базы данных, представляющая различные ячейки, которые определяют записи в таблице. Отсюда происходит более формальное название — атрибуты. Вы можете рассматривать каждый кортеж в качестве уникального экземпляра чего-либо, что может находиться в таблице: категории людей, предметов, событий или ассоциаций. Такими экземплярами могут быть сотрудники компаний, продажи в онлайн-бизнесе или результаты лабораторных тестов. Например, в таблице с трудовыми записями учителей в школе кортежи могут иметь такие атрибуты, как name, subjects, start_date и т. д.

      При создании столбцов вы указываете тип данных, определяющий, какие записи могут вноситься в данный столбец. РСУБД часто используют свои собственные уникальные типы данных, которые могут не быть напрямую взаимозаменяемы с аналогичными типами данных из других систем. Некоторые распространенные типы данных включают даты, строки, целые числа и логические значения.

      В реляционной модели каждая таблица содержит по крайней мере один столбец, который можно использовать для уникальной идентификации каждой строки. Он называется первичным ключом. Это важно, поскольку это означает, что пользователям не нужно знать, где физически хранятся данные на компьютере. Их СУБД может отслеживать каждую запись и возвращать ее в зависимости от конкретной цели. В свою очередь, это означает, что записи не имеют определенного логического порядка, и пользователи могут возвращать данные в любом порядке или с помощью любого фильтра по своему усмотрению.

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

      Пример диаграммы, показывающей, как первичный ключ таблицы EMPLOYEE действует в качестве внешнего ключа таблицы SALES

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

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

      Преимущества и ограничения реляционных баз данных

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

      Сегодня как SQL, так и базы данных, которые ее используют, несколько отклоняются от реляционной модели Кодда. Например, модель Кодда предписывает, что каждая строка в таблице должна быть уникальной, а по соображениям практической целесообразности большинство современных реляционных баз данных допускают дублирование строк. Есть и те, кто не считает базы данных на основе SQL истинными реляционными базами данных, если они не соответствуют каждому критерию реляционной модели по версии Кодда. Но на практике любая СУБД, которая использует SQL и в какой-то мере соответствует реляционной модели, может быть отнесена к реляционным системам управления базами данных.

      Хотя популярность реляционных баз данных стремительно росла, некоторое недостатки реляционной модели стали проявляться по мере того, как увеличивались ценность и объемы хранящихся данных. К примеру, трудно масштабировать реляционную базу данных горизонтально. Горизонтальное масштабирование или масштабирование по горизонтали — это практика добавления большего количества машин к существующему стеку, что позволяет распределить нагрузку, увеличить трафик и ускорить обработку. Часто это контрастирует с вертикальным масштабированием, которое предполагает модернизацию аппаратного обеспечения существующего сервера, как правило, с помощью добавления оперативной памяти или центрального процессора.

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

      Еще одно ограничение, существующее в РСУБД, заключается в том, что реляционная модель была разработана для управления структурированными данными, или данными, которые соответствуют заранее определенному типу данных, или, по крайней мере, каким-либо образом предварительно организованы. Однако с распространением персональных компьютеров и развитием сети Интернет в начале 90-х годов появились неструктурированные данные, такие как электронные сообщения, фотографии, видео и пр.

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

      Еще одно преимущество реляционных баз данных заключается в том, что почти все РСУБД поддерживают транзакции. Транзакция состоит из одного или более индивидуального выражения SQL, выполняемого последовательно, как один блок работы. Транзакции представляют подход «все или ничего», означающий, что все операторы SQL в транзакции должны быть действительными. В противном случае вся транзакция не будет выполнена. Это очень полезно для обеспечения целостности данных при внесении изменений в несколько строк или в таблицы.

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

      Заключение

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

      Чтобы узнать больше о нескольких популярных РСУБД с открытым исходным кодом, мы рекомендуем вам ознакомиться с нашим сравнением различных реляционных баз данных с открытым исходным кодом. Если вам интересно узнать больше о базах данных в целом, мы рекомендуем вам ознакомиться с нашей полной библиотекой материалов о базах данных.



      Source link

      Создание резервного пула хранения данных с помощью GlusterFS в Ubuntu 20.04


      Предыдущая версия данного обучающего руководства была написана Джастином Эллингвудом.

      Введение

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

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

      Цели

      В этом обучающем руководстве мы создадим резервный кластерный массив хранилищ, известный также как распределенная файловая система, или, как указано в документации GlusterFS, доверенный пул хранения данных (Trusted Storage Pool).​​​ Это обеспечит функциональность, аналогичную зеркальной конфигурации RAID в сети: каждый независимый сервер будет содержать свою собственную копию данных, позволяя приложениям получать доступ к любой копии, тем самым облегчая распределение нагрузки чтения.

      Этот избыточный кластер GlusterFS будет состоять из двух серверов Ubuntu 20.04. И будет действовать примерно так же, как сервер NAS с зеркальным RAID. Затем вы получите доступ к кластеру с третьего сервера Ubuntu 20.04, настроенного для работы в качестве клиента GlusterFS.

      Примечание о безопасном функционировании GlusterFS

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

      По этой причине, если вы собираетесь использовать GlusterFS в производственной среде, рекомендуется использовать его в изолированной сети. Например, вы можете настроить его для запуска в виртуальном частном облаке (VPC) или с помощью VPN, работающей между каждым из узлов.

      Если вы планируете развернуть GlusterFS в DigitalOcean, можно настроить его в изолированной сети, добавив инфраструктуру вашего сервера в виртуальное частное облако DigitalOcean. Дополнительную информацию о настройке смотрите в документации по VPC.

      Предварительные требования

      Для выполнения данного обучающего руководства вам понадобится три сервера, работающих на Ubuntu 20.04. Каждый сервер должен иметь пользователя non-root user с правами администратора, а также брандмауэр, настроенный с помощью UFW. Чтобы выполнить настройку, воспользуйтесь руководством по начальной настройке сервера Ubuntu 20.04.

      Примечание. Как указано в разделе «Цели», это обучающее руководство покажет вам, как настроить два ваших сервера Ubuntu для работы в качестве серверов пула хранения данных, а оставшийся сервер — в качестве клиента, который вы будете использовать для доступа к этим узлам.

      Для ясности в этом обучающем модуле будут использоваться компьютеры со следующими именами хостов:

      Имя хоста Роль в пуле хранения данных
      gluster0 Сервер
      gluster1 Сервер
      gluster2 Клиент

      Команды, которые следует запускать в gluster0 или gluster1, записываются на голубом или розовом фоне соответственно:

      Команды, которые следует запускать исключительно на клиенте (gluster2), имеют зеленый фон:

      Команды, которые могут или должны запускаться на нескольких компьютерах, записываются на сером фоне:

      Шаг 1 — Настройка разрешения DNS на каждом компьютере

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

      Если у вас нет свободного доменного имени, а также если вы хотите быстро что-то настроить, вы можете отредактировать файл /etc/host на каждом компьютере. Это специальный файл на компьютерах с ОС Linux, где вы можете статически настроить систему для разрешения любых имен хоста, содержащихся в файле, в статические IP-адреса.

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

      После настройки записи A для каждого сервера вы можете перейти к шагу 2. По мере выполнения данного руководства не забывайте менять glusterN.example.com и glusterN на доменное имя, которое указывает на соответствующий сервер, упоминаемый в примере команды.

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

      Используя предпочитаемый текстовый редактор, откройте этот файл с привилегиями root на каждом компьютере. Мы будем использовать nano:

      По умолчанию файл будет выглядеть примерно так, если удалить комментарии:

      /etc/hosts

      127.0.1.1 hostname hostname
      127.0.0.1 localhost
      
      ::1 ip6-localhost ip6-loopback
      fe00::0 ip6-localnet
      ff00::0 ip6-mcastprefix
      ff02::1 ip6-allnodes
      ff02::2 ip6-allrouters
      ff02::3 ip6-allhosts
      

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

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

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

      /etc/hosts

      . . .
      127.0.0.1       localhost
      first_ip_address gluster0.example.com gluster0
      second_ip_address gluster1.example.com gluster1
      third_ip_address gluster2.example.com gluster2
      
      . . .
      

      После того, как вы добавите все новые строки в файл /etc/hosts одного компьютера, скопируйте их и добавьте в файлы /etc/hosts других компьютеров. Каждый файл /etc/host должен содержать одинаковые строки, которые привязывают IP-адреса ваших серверов к именам, которые вы выбрали.

      Сохраните и закройте каждый файл после завершения. Для этого, если вы используете nano, нажмите CTRL+X, Y, затем ENTER.

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

      Шаг 2 — Настройка источников программного обеспечения на каждом компьютере

      Хотя репозитории APT по умолчанию для Ubuntu 20.04 содержат пакеты GlusterFS, на момент написания данного руководства они не являются последними версиями. Один из способов установки последней стабильной версии GlusterFS (версия 7.6 на момент написания) — добавление официального архива персонального пакета (РРА) проекта Gluster для каждого из трех серверов Ubuntu.

      Добавьте PPA для пакетов GlusterFS путем запуска следующей команды на каждом сервере:

      • sudo add-apt-repository ppa:gluster/glusterfs-7

      Нажмите ENTER, когда вам будет предложено подтвердить намерение добавить РРА.

      После добавления PPA, обновите локальный индекс пакетов каждого сервера. Это сообщит системе о наличии новых пакетов:

      После добавления официального PPA проекта Gluster для каждого сервера и обновления локального индекса пакетов вы сможете установить необходимые пакеты GlusterFS. Однако поскольку два из трех компьютеров будут работать как серверы Gluster, а третий — как клиент, вам понадобится выполнить две отдельные процедуры установки и настройки. Сначала вы установите и настроите компоненты сервера.

      Шаг 3 — Установка компонентов сервера и создание доверенного пула хранения данных

      Пул хранения данных — это любой объем емкости хранения данных от более чем одного ресурса хранения. На этом шаге вы настроите два сервера — gluster0 и gluster1 — в качестве компонентов кластера.

      Установите пакет сервера GlusterFS на gluster0 и на gluster1 с помощью команды:

      • sudo apt install glusterfs-server

      При запросе нажмите Y, а затем ENTER, чтобы подтвердить установку.

      Процесс установки автоматически настроит GlusterFS для запуска в качестве службы systemd. Однако он не запускает службу автоматически и не обеспечивает запуск при загрузке.

      Для запуска glusterd, службы GlusterFS, запустите команду systemctl start на gluster0 и на gluster1:

      • sudo systemctl start glusterd.service

      Затем запустите следующую команду на обоих серверах. Это позволит запускать службу при каждой загрузке сервера:

      • sudo systemctl enable glusterd.service

      После этого вы сможете проверить статус службы на каждом или на обоих серверах:

      • sudo systemctl status glusterd.service

      Если служба активирована и работает, вы получите следующий вывод:

      Output

      ● glusterd.service - GlusterFS, a clustered file-system server Loaded: loaded (/lib/systemd/system/glusterd.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2020-06-02 21:32:21 UTC; 32s ago Docs: man:glusterd(8) Main PID: 14742 (glusterd) Tasks: 9 (limit: 2362) CGroup: /system.slice/glusterd.service └─14742 /usr/sbin/glusterd -p /var/run/glusterd.pid --log-level INFO

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

      Демон Gluster использует порт 24007, поэтому вам нужно разрешить каждому узлу доступ к этому порту через брандмауэр каждого из узлов в пуле хранения данных. Для этого запустите следующую команду на gluster0. Не забудьте поменять gluster1_ip_address на IP-адрес gluster1:

      • sudo ufw allow from gluster1_ip_address to any port 24007

      Запустите следующую команду на gluster1. Снова не забудьте поменять gluster0_ip_address на IP-адрес gluster0:

      • sudo ufw allow from gluster0_ip_address to any port 24007

      Также вам потребуется разрешить вашему клиентскому компьютеру (gluster2) доступ к этому порту. Иначе позже вы столкнетесь с проблемами, когда попытаетесь смонтировать том. Запустите следующую команду на gluster0 и на gluster1, чтобы открыть этот порт для вашего клиентского компьютера:

      • sudo ufw allow from gluster2_ip_address to any port 24007

      Затем добавьте общее правило deny на gluster0 и на gluster1, чтобы закрыть доступ любым другим компьютерам к порту Gluster на любом из серверов.

      Теперь вы готовы к установке связи между gluster0 и gluster1. Для этого вам нужно запустить команду gluster peer probe на одном из узлов. Не имеет значения, какой из узлов вы будете использовать, но в следующем примере команда запускается на gluster0:

      • sudo gluster peer probe gluster1

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

      Output

      peer probe: success

      Вы можете проверить связь узлов в любое время путем запуска команды gluster peer status на любом из них. В этом примере команда выполняется на gluster1:

      Если вы запустите эту команду из gluster1, вы увидите следующий вывод:

      Output

      Number of Peers: 1 Hostname: gluster0.example.com Uuid: a3fae496-c4eb-4b20-9ed2-7840230407be State: Peer in Cluster (Connected)

      На этом этапе два ваших сервера взаимодействуют и готовы к созданию томов хранения друг с другом.

      Шаг 4 — Создание тома хранения

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

      Для создания тома вы будете использовать команду gluster volume create с таким общим синтаксисом:

      sudo gluster volume create volume_name replica number_of_servers domain1.com:/path/to/data/directory domain2.com:/path/to/data/directory force
      

      Вот что означают аргументы и опции команды gluster volume create:

      • volume_name: это имя, которое вы будете использовать для ссылки на том после его создания. Следующий пример команды создает том с именем volume1.
      • replica number_of_servers: после имени тома вы можете указать, какой тип тома вы хотите создать. Напомним, что цель данного обучающего руководства — создать резервный пул хранения данных, поэтому мы будем использовать тип тома replica. Для этого требуется аргумент с указанием количества серверов, на которые будут воспроизводиться данные (2 в нашем примере).
      • domain1.com:/… и domain2.com:/…: определяют расположение компьютеров и каталогов блоков (термин GlusterFS, используемый для обозначения базовой единицы хранения, включающей любой каталог, используемый в качестве части или копии большего тома, на любом компьютере), которые составят volume1. В следующем примере будет создан каталог с именем gluster-storage в корневом каталоге на обоих серверах.
      • force: эта опция отменяет любые предупреждения или опции, которые могли бы возникнуть и остановить создание тома.

      Используя правила, установленные ранее в данном обучающем руководстве, вы можете запустить эту команду для создания тома. Обратите внимание, что вы можете запускать ее либо с gluster0, либо с gluster1:

      • sudo gluster volume create volume1 replica 2 gluster0.example.com:/gluster-storage gluster1.example.com:/gluster-storage force

      Если том был создан успешно, вы увидите следующий вывод:

      Output

      volume create: volume1: success: please start the volume to access data

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

      • sudo gluster volume start volume1

      Вы получите следующий вывод, если том запущен корректно:

      Output

      volume start: volume1: success

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

      • sudo gluster volume status

      В результате вы увидите вывод, аналогичный данному:

      Output

      Status of volume: volume1 Gluster process TCP Port RDMA Port Online Pid ------------------------------------------------------------------------------ Brick gluster0.example.com:/gluster-storage 49152 0 Y 18801 Brick gluster1.example.com:/gluster-storage 49152 0 Y 19028 Self-heal Daemon on localhost N/A N/A Y 19049 Self-heal Daemon on gluster0.example.com N/A N/A Y 18822 Task Status of Volume volume1 ------------------------------------------------------------------------------ There are no active volume tasks

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

      В качестве последнего шага по настройке тома вам нужно будет открыть брандмауэр на обоих серверах, чтобы ваш клиентский компьютер смог подключиться и смонтировать том. Согласно выводу предыдущего примера команды volume1 работает на порту 49152 на обоих компьютерах. Это порт GlusterFS по умолчанию, который используется для первоначального тома, а следующий том, который вы создадите, будет использовать порт 49153, затем 49154 и т. д.

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

      • sudo ufw allow from gluster2_ip_address to any port 49152

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

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

      Шаг 5 — Установка и настройка компонентов клиента

      Теперь ваш том настроен и доступен для использования клиентским компьютером. Но перед тем, как начать работу, вам нужно установить пакет glusterfs-client из архива РРА, загруженного на клиентский компьютер на шаге 1. Зависимости этого пакета включают некоторые из общих библиотек и модулей переводчиков GlusterFS, а также необходимые для работы инструменты FUSE.

      Запустите следующую команду на gluster2:

      • sudo apt install glusterfs-client

      Вскоре вы сможете монтировать удаленный том хранения на клиентском компьютере. Однако перед этим вам нужно создать точку монтирования. Традиционно она находится в каталоге /mnt, но может использоваться, где вам удобно.

      Для удобства создайте каталог с именем /storage-pool на клиентском компьютере для использования в качестве точки монтирования. Имя каталога начинается с косой черты (/), которая помещает его в корневой каталог, поэтому вам нужно создать его с привилегиями sudo:

      Теперь вы можете монтировать удаленный том. Но прежде обратите внимание на синтаксис команды mount, которая используется для этого:

      sudo mount -t glusterfs domain1.com:volume_name /path/to/mount/point
      

      mount — это утилита, которая встречается во многих операционных системах типа Unix. Она используется для монтирования файловых систем — от внешних устройств хранения (таких как SD-карты или USB-накопители) и сетевых систем хранения (как в случае данного обучающего модуля) до каталогов в существующей файловой системе компьютера. В синтаксис команды mount входит опция -t, требующая трех аргументов: тип монтируемой файловой системы, устройство, где находится монтируемая файловая система, и каталог на клиентском компьютере, куда будет монтироваться том.

      Обратите внимание, что в синтаксисе данного примера, аргумент устройства указывает на имя хоста, после которого стоит двоеточие, а затем имя тома. GlusterFS извлекает фактические каталоги хранения на каждом хосте, что означает, что данная команда предназначена для монтирования не каталога /gluster-storage, а тома volume1.

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

      Запустите следующую команду на клиентском компьютере (gluster2) для монтирования тома в созданный вами каталог /storage-pool:

      • sudo mount -t glusterfs gluster0.example.com:/volume1 /storage-pool

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

      Эта команда покажет, что том GlusterFS смонтирован в правильном расположении:

      Output

      Filesystem 1K-blocks Used Available Use% Mounted on . . . gluster0.example.com:/volume1 50633164 1938032 48695132 4% /storage-pool

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

      Шаг 6 — Тестирование функций резервирования

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

      На клиентском компьютере (gluster2) перейдите к точке монтирования, которая была определена на предыдущем шаге:

      Затем создайте несколько тестовых файлов. Следующая команда создает десять отдельных пустых файлов в пуле хранения данных:

      • sudo touch file_{0..9}.test

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

      На gluster0:

      Output

      file_0.test file_2.test file_4.test file_6.test file_8.test file_1.test file_3.test file_5.test file_7.test file_9.test

      Также на gluster1:

      Output

      file_0.test file_2.test file_4.test file_6.test file_8.test file_1.test file_3.test file_5.test file_7.test file_9.test

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

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

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

      Шаг 7 — Ограничение функций резервирования

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

      Если вы используете конфигурацию /etc/host, имена, которые вы установили для каждого сервера,будут отслеживаться некорректно. Вместо этого следует использовать статический IP-адрес. С другой стороны, если вы используете записи DNS, настроенное вами доменное имя будет работать.

      На одном из узлов хранения (gluster0 или gluster1) запустите следующую команду:

      • sudo gluster volume set volume1 auth.allow gluster2_ip_address

      Если команда выполняется успешно, вы увидите следующий вывод:

      Output

      volume set: success

      Если вам нужно удалить ограничение в любой точке, вы можете ввести следующее:

      • sudo gluster volume set volume1 auth.allow *

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

      Если у вас несколько клиентских компьютеров, вы можете одновременно указать их IP-адреса или доменные имена (в зависимости от того, используете ли вы /etc/hosts или разрешение имени хоста DNS), разделенные запятыми:

      • sudo gluster volume set volume1 auth.allow gluster_client1_ip,gluster_client2_ip

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

      Шаг 8 — Получение информации о пуле хранения данных с помощью команд GlusterFS

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

      На ваших узлах имеется ряд различных команд для получения этой информации и взаимодействия с пулом хранения данных.

      Если вам нужна информация о каждом томе, запустите команду gluster volume info:

      Output

      Volume Name: volume1 Type: Replicate Volume ID: a1e03075-a223-43ab-a0f6-612585940b0c Status: Started Snapshot Count: 0 Number of Bricks: 1 x 2 = 2 Transport-type: tcp Bricks: Brick1: gluster0.example.com:/gluster-storage Brick2: gluster1.example.com:/gluster-storage Options Reconfigured: auth.allow: gluster2_ip_address transport.address-family: inet storage.fips-mode-rchecksum: on nfs.disable: on performance.client-io-threads: off

      Также для получения информации о подключениях данного узла, вы можете ввести:

      Number of Peers: 1
      
      Hostname: gluster0.example.com
      Uuid: cb00a2fc-2384-41ac-b2a8-e7a1793bb5a9
      State: Peer in Cluster (Connected)
      

      Если вам нужна подробная информация о работе каждого узла, вы можете проанализировать том с помощью команды:

      • sudo gluster volume profile volume_name start

      После выполнения этой команды вы сможете извлечь собранную информацию с помощью следующей команды:

      • sudo gluster volume profile volume_name info

      Output

      Brick: gluster0.example.com:/gluster-storage -------------------------------------------- Cumulative Stats: %-latency Avg-latency Min-Latency Max-Latency No. of calls Fop --------- ----------- ----------- ----------- ------------ ---- 0.00 0.00 us 0.00 us 0.00 us 30 FORGET 0.00 0.00 us 0.00 us 0.00 us 36 RELEASE 0.00 0.00 us 0.00 us 0.00 us 38 RELEASEDIR Duration: 5445 seconds Data Read: 0 bytes Data Written: 0 bytes Interval 0 Stats: %-latency Avg-latency Min-Latency Max-Latency No. of calls Fop --------- ----------- ----------- ----------- ------------ ---- 0.00 0.00 us 0.00 us 0.00 us 30 FORGET 0.00 0.00 us 0.00 us 0.00 us 36 RELEASE 0.00 0.00 us 0.00 us 0.00 us 38 RELEASEDIR Duration: 5445 seconds Data Read: 0 bytes Data Written: 0 bytes . . .

      Как показано ранее, чтобы получить список всех связанных компонентов GlusterFS, работающих на каждом узле, запустите команду gluster volume status:

      • sudo gluster volume status

      Output

      Status of volume: volume1 Gluster process TCP Port RDMA Port Online Pid ------------------------------------------------------------------------------ Brick gluster0.example.com:/gluster-storage 49152 0 Y 19003 Brick gluster1.example.com:/gluster-storage 49152 0 Y 19040 Self-heal Daemon on localhost N/A N/A Y 19061 Self-heal Daemon on gluster0.example.com N/A N/A Y 19836 Task Status of Volume volume1 ------------------------------------------------------------------------------ There are no active volume tasks

      Если вы собираетесь управлять томами хранения GlusterFS, было бы неплохо перейти на консоль GlusterFS. Это позволит вам взаимодействовать со средой GlusterFS без необходимости ввода каждый раз команды sudo gluster:

      Будет выдана подсказка, где вводить команды. Команда help поможет вам сориентироваться:

      Output

      peer help - display help for peer commands volume help - display help for volume commands volume bitrot help - display help for volume bitrot commands volume quota help - display help for volume quota commands snapshot help - display help for snapshot commands global help - list global commands

      После завершения запустите команду exit для выхода из консоли Gluster:

      Теперь вы готовы к интеграции GlusterFS с вашим следующим приложением.

      Заключение

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



      Source link