One place for hosting & domains

      данных

      Создание резервного пула хранения данных с помощью 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

      Использование типа данных MySQL BLOB для хранения изображений с PHP в Ubuntu 18.04


      Автор выбрал Girls Who Code для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Большие двоичные объекты (BLOB) — это тип данных MySQL для хранения двоичных данных, таких как изображения, мультимедийные файлы и файлы PDF.

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

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

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

      В этом обучающем модуле мы используем тип данных MySQL BLOB для сохранения изображений в коде PHP в Ubuntu 18.04.

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

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

      Шаг 1 — Создание базы данных

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

      Введите пароль пользователя root для вашей базы данных MySQL и нажмите ENTER, чтобы продолжить.

      Затем запустите следующую команду для создания базы данных. В этом обучающем модуле мы назовем базу данных test_company:

      • CREATE DATABASE test_company;

      После создания базы данных вы увидите следующее:

      Output

      Query OK, 1 row affected (0.01 sec)

      Затем создайте учетную запись test_user на сервере MySQL и обязательно замените PASSWORD на надежный пароль:

      • CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'PASSWORD';

      Вывод должен выглядеть так:

      Output

      Query OK, 0 rows affected (0.01 sec)

      Чтобы предоставить пользователю test_user полные права доступа к базе данных test_company, выполните команду:

      • GRANT ALL PRIVILEGES ON test_company.* TO 'test_user'@'localhost';

      Вы должны увидеть следующее:

      Output

      Query OK, 0 rows affected (0.01 sec)

      Очистите таблицу прав доступа, чтобы СУБД MySQL перезагрузила разрешения:

      На экран должно быть выведено следующее:

      Output

      Query OK, 0 rows affected (0.01 sec)

      Мы подготовили базу данных test_company и пользователя test_user. Теперь мы можем перейти к созданию таблицы products для сохранения образцов продуктов. Позднее мы используем эту таблицу для вставки и получения записей, чтобы продемонстрировать работу объектов MySQL BLOB.

      Выполните выход из сервера MySQL:

      Снова войдите в систему под учетными данными созданного пользователя test_user:

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

      После выбора базы данных test_company MySQL выведет на экран следующее:

      Output

      Database changed

      Затем создайте таблицу products, запустив команду:

      • CREATE TABLE `products` (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50), price DOUBLE, product_image BLOB) ENGINE = InnoDB;

      Эта команда создает таблицу с именем products. В таблице имеется четыре столбца:

      • product_id: в этом столбце используется тип данных BIGINT, за счет чего обеспечивается поддержка больших списков продуктов, где может содержаться до 2⁶³-1 элементов. Вы пометили столбец как PRIMARY KEY для уникальной идентификации продуктов. Чтобы MySQL обрабатывала генерирование новых идентификаторов для вставленных столбцов, вы использовали ключевое слово AUTO_INCREMENT.

      • product_name: в этом столбце хранятся названия продуктов. Мы использовали тип данных VARCHAR, поскольку это поле обычно обрабатывает не более 50 бувенно-числовых символов. Предел в 50 символов — это гипотетическое значение, используемое для целей этого обучающего модуля.

      • price: для демонстрационных целей мы добавили в таблицу products столбец price для хранения информации о розничной цене продуктов. Поскольку некоторые продукты могут иметь значения с плавающей запятой (например, 23.69, 45.36, 102.99), мы использовали тип данных DOUBLE.

      • product_image: в этом столбце данные типа BLOB используются для хранения двоичных данных изображений продуктов.

      Мы использовали для таблицы InnoDB, СИСТЕМУ ХРАНЕНИЯ, поддерживающую широкий набор функций, включая транзакции MySQL. После выполнения этой команды для создания таблицы products вы увидите на экране следующее:

      Output

      Query OK, 0 rows affected (0.03 sec)

      Выполните выход с сервера MySQL:

      Вы увидите следующее

      Output

      Bye

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

      Шаг 2 — Создание скриптов PHP для подключения к базе данных и ее заполнения

      На этом шаге мы создадим скрипт PHP для подключения к базе данных MySQL, созданной нами на шаге 1. Этот скрипт подготовит три образца продуктов и вставит их в таблицу products.

      Для создания кода PHP откройте новый файл в текстовом редакторе:

      • sudo nano /var/www/html/config.php

      Введите в файл следующую информацию и замените PASSWORD паролем пользователя test_user, созданным на шаге 1:

      /var/www/html/config.php

      <?php
      
      define('DB_NAME', 'test_company');
      define('DB_USER', 'test_user');
      define('DB_PASSWORD', 'PASSWORD');
      define('DB_HOST', 'localhost');
      
      $pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
      $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
      
      

      Сохраните и закройте файл.

      В этом файле мы использовали четыре константы PHP для подключения к базе данных MySQL, созданной на шаге 1:

      • DB_NAME : эта константа хранит название базы данных test_company.

      • DB_USER : эта переменная хранит имя пользователя test_user.

      • DB_PASSWORD : эта константа хранит ПАРОЛЬ MySQL для учетной записи test_user.

      • DB_HOST: сервер, где располагается база данных. В данном случае мы используем сервер localhost.

      Следующая строка в вашем файле инициирует объект данных PHP (PDO) и выполняет подключение к базе данных MySQL:

      ...
      $pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
      ...
      

      Ближе к концу файла мы зададим пару атрибутов PDO:

      • ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION: этот атрибут предписывает PDO выдать исключение, которое можно зарегистрировать для целей отладки.
      • ATTR_EMULATE_PREPARES, false: эта опция повышает безопасности, предписывая СУБД MySQL выполнять подготовку вместо PDO.

      Мы добавим файл /var/www/html/config.php в два скрипта PHP для вставки и получения записей, которые мы сейчас создадим.

      Вначале создайте скрипт PHP /var/www/html/insert_products.php для вставки записей в таблицу products:

      • sudo nano /var/www/html/insert_products.php

      Затем добавьте следующую информацию в файл /var/www/html/insert_products.php:

      /var/www/html/insert_products.php

      <?php
      
      require_once 'config.php';
      
      $products = [];
      
      $products[] = [
                    'product_name' => 'VIRTUAL SERVERS',
                    'price' => 5,
                    'product_image' => file_get_contents("https://i.imgur.com/VEIKbp0.png")
                    ];
      
      $products[] = [
                    'product_name' => 'MANAGED KUBERNETES',
                    'price' => 30,
                    'product_image' => file_get_contents("https://i.imgur.com/cCc9Gw9.png")
                    ];
      
      $products[] = [
                    'product_name' => 'MySQL DATABASES',
                    'price' => 15,
                    'product_image' => file_get_contents("https://i.imgur.com/UYcHkKD.png" )
                    ];
      
      $sql = "INSERT INTO products(product_name, price, product_image) VALUES (:product_name, :price, :product_image)";
      
      foreach ($products as $product) {
          $stmt = $pdo->prepare($sql);
          $stmt->execute($product);
      }
      
      echo "Records inserted successfully";
      

      Сохраните и закройте файл.

      Вы добавили файл config.php в верхней части файла. Это первый файл, который вы создали для определения переменных базы данных и подключения к базе данных. Также этот файл инициирует объект PDO и сохраняет его в переменной $pdo.

      Далее вы создали массив данных о продуктах, которые нужно вставить в базу данных. Помимо значений product_name и price, подготовленных в виде текстовых и числовых значений соответственно, данный скрипт использует встроенную функцию PHP file_get_contents для чтения изображений из внешнего источника и передачи их в виде строк в столбец product_image.

      Затем вы подготовили выражение SQL и использовали выражение PHP foreach{...} для вставки каждого продукта в базу данных.

      Для выполнения файла /var/www/html/insert_products.php запустите его в окне браузера, используя следующий URL. Замените your-server-IP публичным IP-адресом вашего сервера:

      http://your-server-IP/insert_products.php
      

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

      Сообщение об успешной вставке записей в базу данных

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

      Шаг 3 — Отображение информации о продуктах из базы данных MySQL

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

      Для создания файла введите следующее:

      • sudo nano /var/www/html/display_products.php

      Затем введите в файл следующую информацию:

      /var/www/html/display_products.php

      <html>
        <title>Using BLOB and MySQL</title>
        <body>
      
        <?php
      
        require_once 'config.php';
      
        $sql = "SELECT * FROM products";
        $stmt = $pdo->prepare($sql);
        $stmt->execute();
        ?>
      
        <table border="1" align = 'center'> <caption>Products Database</caption>
          <tr>
            <th>Product Id</th>
            <th>Product Name</th>
            <th>Price</th>
            <th>Product Image</th>
          </tr>
      
        <?php
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            echo '<tr>';
            echo '<td>' . $row['product_id'] . '</td>';
            echo '<td>' . $row['product_name'] . '</td>';
            echo '<td>' . $row['price'] . '</td>';
            echo '<td>' .
            '<img src = "data:image/png;base64,' . base64_encode($row['product_image']) . '" width = "50px" height = "50px"/>'
            . '</td>';
            echo '</tr>';
        }
        ?>
      
        </table>
        </body>
      </html>
      

      Сохраните изменения в файле и закройте его.

      Здесь мы опять использовали файл config.php для подключения к базе данных. Затем мы подготовили и выполнили команду SQL, используя PDO для извлечения всех элементов из таблицы products с помощью команды SELECT * FROM products.

      Затем мы создали таблицу HTML и заполнили ее данными о продуктах, используя выражение PHP while() {...}. Строка $row = $stmt->fetch(PDO::FETCH_ASSOC) отправляет запрос в базу данных и сохраняет результат в переменной $row как многомерный массив, который затем отображается как столбец таблицы HTML с использованием синтаксиса $row['column_name'].

      Изображения из столбца product_image заключены в теги <img src = "">. Мы использовали атрибуты width и height для уменьшения ширины и высоты изображений, чтобы они поместились в столбце таблицы HTML.

      Чтобы конвертировать данные, хранящиеся в объекте типа BLOB, обратно в изображения, мы использовали встроенную функцию PHP base64_encode и следующий синтаксис схемы URI данных:

      data:media_type;base64, base_64_encoded_data
      

      В данном случае image/png — это значение параметра media_type (тип файла), а закодированная строка Base64 из столбца product_image — это данные base_64_encoded_data.

      Выполните в браузере файл display_products.php, введя следующий адрес:

      http://your-server-IP/display_products.php
      

      Запустив в браузере файл display_products.php, вы увидите таблицу HTML со списком продуктов и связанных с ними изображений.

      Список продуктов из базы данных MySQL

      Это подтверждает, что скрипт PHP для извлечения изображений из базы данных MySQL работает ожидаемым образом.

      Заключение

      В этом обучающем модуле мы использовали тип данных MySQL BLOB для хранения и вывода изображений в коде PHP в Ubuntu 18.04. Мы увидели основные преимущества хранения изображений в базе данных по сравнению с их хранением в файловой системе. В число этих преимуществ входят портативность, безопасность и удобство резервного копирования. Эта технология будет вам полезна, если вы создаете приложение, для которого требуется хранить информацию и изображения вместе, например, студенческий портал или базу данных сотрудников.

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



      Source link

      Управление отсортированными наборами данных в Redis


      Введение

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

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

      Использование этого руководства

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

      Команды, указанные в этом руководстве, были протестированы на сервере Ubuntu 18.04 с версией Redis 4.0.9. Для настройки аналогичной среды вы можете воспользоваться шагом 1 нашего руководства Установка и обеспечение безопасности Redis в Ubuntu 18.04. Мы продемонстрируем, как эти команды ведут себя, выполнив их с помощью redis-cli — интерфейса командной строки Redis. Обратите внимание, что если вы используете другой интерфейс Redis, например Redli, конкретный вывод некоторых команд может отличаться.

      Также вы можете предоставить управляемый экземпляр базы данных Redis для тестирования этих команд, но при этом необходимо отметить, что в зависимости от уровня контроля, который используется вашим поставщиком базы данных, некоторые команды этого обучающего руководства могут не работать, как описано. Для предоставления управляемой базы данных DigitalOcean следуйте указаниям нашей документации по управляемым базам данных. Затем вы должны либо установить Redli, либо настроить туннель TLS в целях подключения к управляемой базе данных через TLS.

      Создание отсортированных наборов данных и добавление участников

      Для создания отсортированного набора используйте команду zadd. zadd принимает в качестве аргументов имя ключа, который будет хранить отсортированный набор, за которым следует балл участника, которого вы добавляете, и значение самого участника. Следующая команда создаст ключ отсортированного набора под названием faveGuitarists с одним участником, Joe Pass, который имеет балл 1:

      • zadd faveGuitarists 1 "Joe Pass"

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

      Output

      (integer) 1

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

      • zadd faveGuitarists 4 "Stephen Malkmus" 2 "Rosetta Tharpe" 3 "Bola Sete" 3 "Doug Martsch" 8 "Elizabeth Cotten" 12 "Nancy Wilson" 4 "Memphis Minnie" 12 "Michael Houser"

      Output

      (integer) 8

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

      • NX или XX: эти опции имеют противоположные действия, поэтому вы можете включать только одну из них в любой операции zadd:
        • NX: указывает zadd не обновлять существующих участников. С этой опцией zadd будет добавлять только новые элементы.
        • XX: указывает zadd обновлять только существующие элементы. С этой опцией zadd никогда не будет добавлять новых участников.
      • CH. Как правило, zadd возвращает только количество новых элементов, добавленных в отсортированный набор. Но если эта опция включена, zadd будет возвращать количество измененных элементов. Сюда входят новые добавленные участники и участники, баллы которых были изменены.
      • INCR: заставляет команду увеличить значение балла участника. Если участник еще не существует, команда добавит его в отсортированный набор с увеличением в качестве его балла, как если бы его первоначальный балл был равен 0. Если INCR включен, zadd будет возвращать новый балл участника, если операция успешна. Обратите внимание, что вы можете включать только одну пару «балл/участник» в момент использования этой опции.

      Вместо передачи опции INCR в zadd вы можете использовать команду zincrby, которая ведет себя точно так же. Вместо того чтобы присваивать участнику отсортированного набора значение, указанное значением балла как zadd, она увеличивает балл этого участника на это значение. Например, следующая команда увеличивает балл участника Stephen Malkmus, который был первоначально равен 4 и увеличился на 5 до 9.

      • zincrby faveGuitarists 5 "Stephen Malkmus"

      Output

      "9"

      Как и в случае с опцией INCR команды zadd, если указанный участник не существует, то zincrby создаст его со значением увеличения в качестве его балла.

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

      Наиболее основополагающий способ получения участников, удерживаемых в отсортированном наборе — использовать команду zrange. Эта команда принимает в качестве аргументов имя ключа, участников которого вы хотите получить, и ряд участников, находящихся в нем. Диапазон ряда определяется двумя числами, представляющими нулевые индексы — это означает, что 0 представляет первого участника отсортированного набора (или участника с наименьшим баллом), 1 представляет следующего и т. д.

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

      • zrange faveGuitarists 0 3

      Output

      1) "Joe Pass" 2) "Rosetta Tharpe" 3) "Bola Sete" 4) "Doug Martsch"

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

      Индексы start и stop могут также быть отрицательными числами, где -1 представляет последнего участника, -2 представляет предпоследнего участника и т. д.:

      • zrange faveGuitarists -5 -2

      Output

      1) "Memphis Minnie" 2) "Elizabeth Cotten" 3) "Stephen Malkmus" 4) "Michael Houser"

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

      • zrange faveGuitarists 5 6 WITHSCORES

      Output

      1) "Elizabeth Cotten" 2) "8" 3) "Stephen Malkmus" 4) "9"

      zrange может возвращать только ряд участников в восходящей числовой последовательности. Чтобы отменить это и вернуть диапазон в нисходящей последовательности, необходимо использовать команду zrevrange. Эту команду можно представить как временно обращающую порядок данного отсортированного набора перед возвратом участников, находящихся в указанном диапазоне. Таким образом, с zrevrange 0 будет представлять последнего участника, содержащегося в ключе, 1 будет представлять предпоследнего и т. д.:

      • zrevrange faveGuitarists 0 5

      Output

      1) "Nancy Wilson" 2) "Michael Houser" 3) "Stephen Malkmus" 4) "Elizabeth Cotten" 5) "Memphis Minnie" 6) "Doug Martsch"

      zrevrange может также принимать опцию WITHSCORES.

      Вы можете возвращать ряд участников на основании их баллов с помощью команды zrangebyscore. В следующем примере команда будет возвращать любого участника, удерживаемого в ключе faveGuitarists с баллом 2, 3 или 4:

      • zrangebyscore faveGuitarists 2 4

      Output

      1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch" 4) "Memphis Minnie"

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

      • zrangebyscore faveGuitarists 2 (4

      Output

      1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch"

      Как и в случае с zrange, zrangebyscore может принимать аргумент WITHSCORES. Он также принимает опцию LIMIT, которую вы можете использовать для получения только выбранных элементов из вывода zrangebyscore. Эта опция принимает offset, который является первым участником в диапазоне, который будет возвращать команда, и count, который определяет, сколько участников команда будет возвращать в общей сложности. Например, следующая команда будет рассматривать первые шесть участников отсортированного набора faveGuitarists, но будет возвращать только три участника из него, начиная со второго участника в диапазоне, представленного 1:

      • zrangebyscore faveGuitarists 0 5 LIMIT 1 3

      Output

      1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch"

      Команда zrevrangebyscore возвращает обращенный ряд участников на основе их баллов. Следующая команда возвращает каждого участника набора с балом между 10 и 6:

      • zrevrangebyscore faveGuitarists 10 6

      Output

      1) "Stephen Malkmus" 2) "Elizabeth Cotten"

      Как и в случае с zrangebyscore, zrevrangebyscore может принимать обе опции WITHSCORES и LIMIT. Также вы можете исключать любой конец диапазона, ставя перед ним открытую скобку.

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

      • zadd SomervilleSquares 0 Davis 0 Inman 0 Union 0 porter 0 magoun 0 ball 0 assembly

      Перед zrangebylex должно идти имя ключа, интервал запуска и интервал остановки. Интервалы запуска и остановки должны начинаться с открытой скобки (() или открытой квадратной скобки ([) — например, следующим образом:

      • zrangebylex SomervilleSquares [a [z

      Output

      1) "assembly" 2) "ball" 3) "magoun" 4) "porter"

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

      • zrangebylex SomervilleSquares [A [z

      Output

      1) "Davis" 2) "Inman" 3) "Union" 4) "assembly" 5) "ball" 6) "magoun" 7) "porter"

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

      • zrangebylex SomervilleSquares - +

      Обратите внимание, что zrangebylex не может возвращать участников отсортированных наборов в обратном лексикографическом (восходящем алфавитном) порядке. Для этого нужно использовать zrevrangebylex:

      • zrevrangebylex SomervilleSquares + -

      Output

      1) "porter" 2) "magoun" 3) "ball" 4) "assembly" 5) "Union" 6) "Inman" 7) "Davis"

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

      Получение информации по отсортированным наборам

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

      Output

      (integer) 9

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

      • zcount faveGuitarists 3 8

      Output

      (integer) 4

      zscore выводит балл указанного участника отсортированного набора:

      • zscore faveGuitarists "Bola Sete"

      Output

      "3"

      Если либо указанный участник, либо ключ не существует, zscore будет возвращать (nil).

      zrank аналогичен zscore, но вместо того чтобы возвращать балл данного участника, он возвращает его ранг. В Redis ранг — нулевой индекс участников отсортированного набора в порядке их баллов. Например, Joe Pass имеет балл 1, но, поскольку это самый низкий балл любого участника в ключе, он имеет ранг 0:

      • zrank faveGuitarists "Joe Pass"

      Output

      (integer) 0

      Есть другая команда Redis под названием zrevrank, выполняющая ту же функцию, что и zrank, но вместо этого обращающая ранги участников в наборе. В следующем примере Joe Pass имеет самый низкий балл и, соответственно, самый высокий обращенный ранг:

      • zrevrank faveGuitarists "Joe Pass"

      Output

      (integer) 8

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

      Как и zscore, zrank и zrevrank будут возвращать (nil) при отсутствии ключа или участника.

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

      • zlexcount SomervilleSquares [M [t

      Output

      (integer) 5

      Эта команда соответствует тому же синтаксису, что и команда zrangebylex, поэтому подробные данные по определению строки см. в предыдущем разделе.

      Удаление участников из отсортированных наборов

      Команда zrem может удалять один или несколько участников из отсортированного набора:

      • zrem faveGuitarists "Doug Martsch" "Bola Sete"

      zrem будет возвращать целое число, указывающее, сколько участников она удалила из отсортированного набора:

      Output

      (integer) 2

      Есть три команды Redis, которые позволяют удалять участников отсортированного набора на основе диапазона. Например, если каждый участник отсортированного набора имеет одинаковый балл, вы можете удалять участников на основании лексикографического диапазона с помощью zremrangebylex. Эта команда использует тот же синтаксис, что и zrangebylex. Следующий пример удаляет каждого участника, который начинается с заглавной буквы, из ключа SomervilleSquares, созданного в предыдущем разделе:

      • zremrangebylex SomervilleSquares [A [Z

      zremrangebylex выведет целое число, указывающее, сколько участников было удалено:

      Output

      (integer) 3

      Вы можете также удалять участников на основе диапазона баллов с помощью команды zremrangebyscore, которая использует тот же синтаксис, что и команда zrangebyscore. В следующем примере будет удален каждый участник, находящийся в faveGuitarists, с баллом 4, 5 или 6:

      • zremrangebyscore faveGuitarists 4 6

      Output

      (integer) 1

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

      • zremrangebyrank faveGuitarists 0 2

      Output

      (integer) 3

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

      Создание новых отсортированных наборов из существующих

      Redis содержит две команды, которые позволяют сопоставлять участников нескольких отсортированных наборов и создавать новые на основе этих сопоставлений: zinterstore и zunionstore. Для экспериментирования с этими командами нужно запустить следующие команды zadd для создания некоторых отсортированных наборов в качестве примеров.

      • zadd NewKids 1 "Jonathan" 2 "Jordan" 3 "Joey" 4 "Donnie" 5 "Danny"
      • zadd Nsync 1 "Justin" 2 "Chris" 3 "Joey" 4 "Lance" 5 "JC"

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

      • zinterstore BoyBands 2 NewKids Nsync

      zinterstore будет возвращать целое число, показывающее количество элементов, сохраненных в конечном отсортированном наборе. Поскольку NewKids и Nsync имеют только одного общего участника — Joey, команда будет возвращать 1:

      Output

      (integer) 1

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

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

      • zunionstore SuperGroup 2 NewKids Nsync

      Как и zinterstore, zunionstore будет возвращать целое число, показывающее количество элементов, указанных в конечном ключе. Хотя оба исходных отсортированных набора содержали пять участников, поскольку отсортированные наборы не могут содержать повторяющихся участников, а каждый ключ содержит одного участника под названием Joey, итоговое целое число будет равняться 9:

      Output

      (integer) 9

      Как и zinterstore, zunionstore перезаписывает содержимое конечного ключа, если он уже существует.

      Чтобы предоставить вам возможность лучше контролировать баллы участников при создании новых отсортированных наборов при помощи zinterstore и zunionstore, обе эти команды принимают опции WEIGHTS и AGGREGATE.

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

      В качестве следующего примера создается новый отсортированный набор, содержащий пересекающиеся ключи из отсортированных наборов NewKids и Nsync. Он взвешивает баллы в ключе NewKids с коэффициентом 3 и взвешивает баллы в ключе Nsync с коэффициентом 7:

      • zinterstore BoyBandsWeighted 2 NewKids Nsync WEIGHTS 3 7

      Если опция WEIGHTS не включена, взвешивание производится по умолчанию с коэффициентом 1 — как для zinterstore, так и для zunionstore.

      AGGREGATE принимает три подопции. Первая из них, SUM, осуществляет поведение zinterstore и zunionstore по умолчанию, добавляя баллы одинаковых участников в комбинированные наборы.

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

      • zinterstore BoyBandsWeightedMin 2 NewKids Nsync WEIGHTS 3 7 AGGREGATE MIN

      Поскольку два отсортированных набора имеют только одного совпадающего участника с одинаковым баллом (3), эта команда создаст новый набор с участником, равным более низкому значению их двух взвешенных баллов:

      • zscore BoyBandsWeightedMin "Joey"

      Output

      "9"

      Аналогично AGGREGATE может заставить zinterstore или zunionstore назначать более высокий из двух баллов с опцией MAX:

      • zinterstore BoyBandsWeightedMax 2 NewKids Nsync WEIGHTS 3 7 AGGREGATE MAX

      Эта команда создает новый набор с одним участником Joey, который имеет более высокий показатель взвешенного балла из двух:

      • zscore BoyBandsWeightedMax "Joey"

      Output

      "21"

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

      Заключение

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

      Дополнительную информацию о командах Redis можно найти в нашей серии обучающих руководств Управление базой данных Redis.



      Source link