Вступление
Облачные вычисления находятся на подъеме по нескольким причинам: они гибки, относительно дешевы по сравнению с поддержкой внутренней инфраструктуры и обеспечивают превосходную автоматизацию распределения ресурсов, что еще больше снижает затраты.
Облачные вычисления также обеспечивают горизонтальную масштабируемость, что крайне важно для многих компаний в современную цифровую эпоху. Когда объем обрабатываемых данных растет год от года, нельзя полагаться на старомодные модели вертикальной масштабируемости. В эту эпоху распределенных вычислений данные должны быть распределены по нескольким более дешевым системам, где данные могут надежно храниться, обрабатываться и при необходимости возвращаться пользователю.
Создание таких систем не простая задача, но, к счастью, есть решения, которые идеально вписываются в облачную архитектуру. Я говорю об Apache Ignite .
Готовность к окружающей среде
Я собираюсь использовать облако AWS для развертывания кластера Ignite. Итак, давайте немного поговорим о настройках среды.
Здесь, в учебных целях, достаточно самых маленьких машин бесплатного уровня. Я выбрал образ Ubuntu 18.04, но это не имеет большого значения.
Перед развертыванием наших первых машин нам необходимо настроить так называемую группу безопасности. Здесь должны быть определены сетевые правила для портов, необходимых для экземпляров Ignite.
Два диапазона портов были явно настроены. Диапазон портов 47500-47600 используется механизмом обнаружения (тот, который позволяет узлам находить друг друга и формировать кластер), а 47100-47200 используется подсистемой связи, которая позволяет узлам отправлять друг другу прямые сообщения.
Теперь, после настройки Security Group, пришло время запустить и настроить наши машины.
Машины запущены, но им не хватает необходимого программного обеспечения: Java. Не проблема; просто используйте следующую команду для установки Java:
Оболочка
xxxxxxxxxx
1
~/sudo apt install openjdk-8-jdk
Для дистрибутивов RedHat / Centos команда выглядит немного иначе:
Оболочка
xxxxxxxxxx
1
~/sudo yum install java-1.8.0-openjdk.x86_64
Большой! Мы в одном шаге от запуска и запуска нашего первого экземпляра Ignite в облаке!
Я скачал последний бинарный дистрибутив с официального сайта и распаковал его:
Оболочка
xxxxxxxxxx
1
~/ignite$ wget http://mirror.linux-ia64.org/apache//ignite/2.7.6/apache-ignite-2.7.6-bin.zip
2
~/ignite$ unzip apache-ignite-2.7.6-bin.zip
А теперь давайте начнем:
Оболочка
xxxxxxxxxx
1
~/ignite/apache-ignite-2.7.6-bin$ ./bin/ignite.sh
Мы уже добились больших успехов. Мы подготовили среду, выяснили, где взять двоичные файлы и как запустить узел Ignite, используя эти двоичные файлы.
Однако, чтобы иметь действительно распределенную систему, нам нужен еще один узел. Просто повторите все эти шаги (создайте и настройте экземпляр AWS, загрузите и распакуйте двоичные файлы) и запустите еще один экземпляр Ignite.
И теперь пришло время собрать кластер из имеющихся у нас узлов. Да, запуска группы узлов недостаточно для построения кластера, и это становится очевидным из журналов: каждый узел имеет следующую строку в журналах.
Это сообщение означает, что два узла сформировали два независимых кластера вместо того, чтобы обнаруживать друг друга и формировать один.
Чтобы создать действительно кластерную среду, нам необходимо углубить наше понимание того, как кластер собирается.
Специальная служба под названием Discovery играет решающую роль в этом процессе. Это позволяет узлам находить друг друга и формировать кластер. Когда узел запускается, он запрашивает свой экземпляр Discovery, чтобы найти существующий кластер, и пытается присоединиться к нему вместо создания нового.
Настройка DiscoverySPI для определения местоположения кластера является обязанностью конечного пользователя и чрезвычайно проста. Все, что нам нужно сделать, это настроить и предоставить его Discovery; давайте сделаем это и исправим наши изолированные узлы.
Откройте файл конфигурации в вашем любимом текстовом редакторе …
Оболочка
xxxxxxxxxx
1
~/ignite/apache-ignite-2.7.6-bin$ vim config/default-config.xml
… добавить следующий блок:
XML
xxxxxxxxxx
1
<property name="discoverySpi">
2
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
3
<property name="ipFinder">
4
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
5
<property name="addresses">
6
<list>
7
<value>172.31.3.57</value>
8
</list>
9
</property>
10
</bean>
11
</property>
12
</bean>
13
</property>
Этот блок должен находиться прямо под корневым элементом файла конфигурации. Самое главное здесь значение , переданное в адреса собственности. Для каждого сервера это должен быть либо частный адрес, либо публичный IP-адрес другого сервера .
Вкладка «Описание» каждого узла содержит информацию об общих и частных IP-адресах наших узлов AWS:
Обеспечение использования кластера: подключение удаленного клиента
До сих пор мы создали облачную среду с нуля, развернули, настроили и собрали кластер Ignite. Мы также расширили наше понимание распределенных систем. Теперь пришло время сделать что-то полезное с нашим новым кластером: подключитесь к нему с помощью удаленного клиента, загрузите некоторые данные и убедитесь, что они есть.
Ignite предоставляет несколько способов подключения к кластеру: тонкие клиенты, интерфейсы JDBC / ODBC и т. Д. Но я собираюсь использовать толстые клиентские подключения, которые действительно просты. Фактически, толстый клиент — это почти обычный серверный узел Ignite, за исключением того, что он не хранит данные кэша локально (и некоторые технические детали, но мы не будем сейчас углубляться в них), поэтому его конфигурация очень похожа.
Я начинаю с моей любимой IDE и создаю самый простой проект Java: проект командной строки. Я добавляю в classpath проекта три файла jar из того же бинарного дистрибутива, который я уже видел. (Это тот же пакет, который мы использовали для развертывания наших серверов Ignite в облаке.) Это jar-файлы: ignite-core-2.7.6.jar, cache-api-1.0.0.jar и annotations-13.0.jar.
Вот конфигурация в Java для моего клиента:
Джава
xxxxxxxxxx
1
IgniteConfiguration cfg = new IgniteConfiguration();
2
cfg.setClientMode(true);
3
4
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
5
ipFinder.setAddresses(Arrays.asList("54.154.28.251"));
6
TcpDiscoverySpi spi = new TcpDiscoverySpi();
7
spi.setIpFinder(ipFinder);
8
9
cfg.setDiscoverySpi(spi);
Здесь мы видим те же свойства, которые мы уже настроили для узлов сервера: DiscoverySPI, IpFinder и так далее. Здесь много общего, за исключением выделенного логического флага, который превращает обычный узел Ignite в клиента.
Используя эту конфигурацию, я запускаю свой клиентский узел и запрашиваю его для создания кэша, помещаю в него простую строку, а затем считываю это значение обратно:
Джава
xxxxxxxxxx
1
try (Ignite client = Ignition.start(cfg)) {
2
IgniteCache cache = client
3
.getOrCreateCache(
4
new CacheConfiguration("clientCache")
5
.setBackups(1)
6
.setAffinity(new RendezvousAffinityFunction(false, 4)
7
)
8
);
9
10
cache.put(1, "myString");
11
12
System.out.println("-->>-->> value of key ‘1’: " + cache.get(1));
13
}
14
Хм, я вижу, что что-то не так. Моя простая программа запускается, но она не печатает никаких результатов. В то же время в журналах серверов я вижу, что серверы добавили клиентский узел в топологию:
Так что может быть не так? Ответ заключается в том, что в облачных средах на стороне сервера необходимо настроить еще одну вещь: an AddressResolver
.
Поскольку наши серверы работают в AWS, между ними и внешним миром существует своего рода NAT. Серверы знают свои внутренние (за NAT) IP-адреса, но не знают, каким публичным IP-адресам они назначены. Чтобы предоставить серверам информацию об этом сопоставлении и, таким образом, позволить им обмениваться данными с удаленными клиентами, нам необходимо настроить преобразователи адресов на стороне сервера.
Сначала остановите оба узла сервера. Затем добавьте следующий блок в каждую конфигурацию сервера, снова прямо под корневым элементом config XML. Здесь частные и публичные IP-адреса - это адреса одного и того же сервера, на котором изменена конфигурация:
xxxxxxxxxx
1
<property name="addressResolver">
2
<bean class="org.apache.ignite.configuration.BasicAddressResolver">
3
<constructor-arg>
4
<map>
5
<entry key="<private IP>" value="<public IP>"/>
6
</map>
7
</constructor-arg>
8
</bean>
9
</property>
Перезапустите серверы, чтобы применить изменения и перезапустить программу. Помните, что публичный IP-адрес может измениться после перезагрузки виртуальной машины, поэтому конфигурация нашего первого кластера не очень надежна.
Теперь мы видим ожидаемый результат: программа завершает работу и извлекает из кэша значение, которое было только что помещено туда.
Заключение
Развертывание кластера Ignite в облаке AWS требует некоторых простых приемов. И когда сделаны первые шаги, мы можем сделать более интересные вещи, такие как потоковая передача данных в кластер с помощью потоков данных, выполнение запросов или использование других интерфейсов, таких как подключение JDBC / ODBC, для подключения к кластеру.
Однако следует помнить, что для разработки более полезных приложений требуется больше ресурсов, и бесплатные экземпляры AWS очень быстро исчерпывают свои возможности. Независимо от того, используется ли Ignite в качестве основной базы данных или в качестве слоя кэширования в памяти, увеличение объема памяти означает повышение производительности, а для сред, подобных продуктам, мощные экземпляры уровня x1 являются лучшими.