Работая в компании СТАРКОВ Групп системным инженером уже 1,5 года, я не так давно задался вопросом о том, как построить отказоустойчивый кластер Elasticsearch, который работал бы в кворуме из 3 нод, и прикрутить его к Directum RX.
Насколько я знаю, приложения пишут сразу под возможность использования кластера Elasticsearch, а вот в документации Directum RX я не нашел ничего о кластеризации данного решения и решил немного поэксперементировать в этом направлении.
Важно понимать, что Elasticsearch, даже будучи в единственном экземпляре - это тоже кластер, только из одной ноды.
Перед собой я поставил следующие задачи:
1) Собрать кластер Elasticsearch из 3 нод;
2) Собрать кластер Haproxy и Keepalived из 2 нод;
3) Протестировать работоспособность кластера при падении 1 ноды.
Версии компонентов:
1) DirectumRX - 4.9.153;
2) Elasticsearch - 7.16.3;
3) Keepalived - 2.2.4;
4) Haproxy - 2.4.24;
5) Ubuntu 22.04.5.
IP адреса серверов: 
1) Elasticsearch: 
   1 нода - 192.168.0.106
   2 нода - 192.168.0.156
   3 нода - 192.168.0.157
2) Haproxy и Keepalived:
   1 нода - 192.168.0.159
   2 нода - 192.168.0.160
3) DirectumRX:
   1 нода - 192.168.0.158
И так, начнем.
Первым делом соберем кластер Elasticsearch. Если вы раньше этого не делали, то ничего страшного. Все намного проще, чем может показаться.
Подготавливаем 3 виртуальные машины, настраиваем их как нам необходимо.
Я обычно добавляю параметр vm.max_map_count=655360 в /etc/sysctl.conf и определяю лимиты в /etc/security/limits.conf:
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
Устанавливаем Elasticsearch требуемой версии на все 3 ноды и выполняем:
systemctl daemon-reload
systemctl enable elasticsearch
После этого настраиваем Elasticsearch согласно справки Directum, а именно: добавляем плагины и подкидываем файл с синонимами в /etc/elasticsearch на всех нодах будущего кластера.
Пока ничего не запускаем. Делать это мы будем только после настройки файлов конфигурации.
1. На всех нодах выставляем параметры -Xms<count>g -Xmx<count>g в конфигурационном файле jvm.options. По умолчанию он лежит по пути /etc/elasticsearch/jvm.options.
Например, если мы хотим чтоб наш Elasticsearch использовал 10Гб оперативной памяти, укажем эти параметры следующий образом:
-Xms10g
-Xmx10g
2. Идем на 1 ноду, открываем конфигурационный файл elasticsearch.yml (По умолчанию он лежит там же, где и jvm.options). Вносим следующее содержимое:
# Указываем имя кластера и имя ноды
cluster.name: my-application
node.name: node-1
# Задаем путь к данным
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
# Разрешаем слушать на всех интерфейсах
network.host: 0.0.0.0
# Указываем ip адрес 1 ноды
cluster.initial_master_nodes: ["192.168.0.106"]
# Отключаем GeoIP
ingest.geoip.downloader.enabled: false
# Отключаем модуль безопасности X-Pack
xpack.security.enabled: false
# Указываем на каких сетевых интерфейсах слушать HTTP-соединения Elasticsearch
http.host: 0.0.0.0
# Указываем на каких сетевых интерфейсах будет слушать транспортный протокол Elasticsearch
transport.host: 0.0.0.0
3. Запускаем Elasticsearch командой:
systemctl start elasticsearch
4. Проверяем, что наш кластер создался командой:
curl -k http://localhost:9200/_cat/nodes?v
В ответ мы получим список нод текущего кластера.
ip            heap.percent ram.percent cpu load_1m load_5m load_15m node.role   master name
192.168.0.106           15          97   1    0.02    0.02     0.00 cdfhilmrstw *      node-1
Проверить текущее состояние кластера можно командой:
curl -k http://localhost:9200/_cat/health?v
5. Теперь мы должны подключить к нашему кластеру еще 2 ноды. Для этого открываем elasticsearch.yml на всех нодах и дописываем необходимые данные:
1 нода
cluster.name: my-application
node.name: node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
ingest.geoip.downloader.enabled: false
xpack.security.enabled: false
cluster.initial_master_nodes: ["192.168.0.106", "192.168.0.156", "192.168.0.157"]
discovery.seed_hosts: ["192.168.0.106", "192.168.0.156", "192.168.0.157"]
ingest.geoip.downloader.enabled: false
xpack.security.enabled: false
http.host: 0.0.0.0
transport.host: 0.0.0.0
2 нода
cluster.name: my-application
node.name: node-2
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
ingest.geoip.downloader.enabled: false
xpack.security.enabled: false
cluster.initial_master_nodes: ["192.168.0.106", "192.168.0.156", "192.168.0.157"]
discovery.seed_hosts: ["192.168.0.106", "192.168.0.156", "192.168.0.157"]
ingest.geoip.downloader.enabled: false
xpack.security.enabled: false
http.host: 0.0.0.0
transport.host: 0.0.0.0
3 нода
cluster.name: my-application
node.name: node-3
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
ingest.geoip.downloader.enabled: false
xpack.security.enabled: false
cluster.initial_master_nodes: ["192.168.0.106", "192.168.0.156", "192.168.0.157"]
discovery.seed_hosts: ["192.168.0.106", "192.168.0.156", "192.168.0.157"]
ingest.geoip.downloader.enabled: false
xpack.security.enabled: false
http.host: 0.0.0.0
transport.host: 0.0.0.0
Как видите, мы добавили еще 2 ip адреса в параметр cluster.initial_master_nodes.
Эти ip адреса соответствуют 2 другим нодам нашего кластера. Данный параметр используется для определения списка нод, которые могут стать мастерами в кластере.
Мы также добавили новый параметр discovery.seed_hosts и указали в него все тот же перечень ip адресов нашего кластера. Он используется для указания списка ip адресов нод, которые могут быть использованы для обнаружения других нод в кластере.
6. Теперь запускаем 2 и 3 ноду:
systemctl start elasticsearch
7. После того, как 2 и 3 ноды запустились, перезапускаем 1 ноду - она же мастер:
systemctl restart elasticsearch
При внесении правок в конфигурационные файлы, обычно рекомендуют мастер-ноду перезапускать в последнюю очередь, чтоб не вызвать неожиданных ошибок.
 
8. Проверяем работоспособность нашего кластера командами:
curl -k http://localhost:9200/_cat/nodes?v
curl -k http://localhost:9200/_cat/health?v
Вывод должен быть примерно таким:
ip            heap.percent ram.percent cpu load_1m load_5m load_15m node.role   master name
192.168.0.157           33          96   0    0.00    0.01     0.00 cdfhilmrstw -      node-2
192.168.0.102           14          95   0    0.00    0.00     0.00 cdfhilmrstw -      node-1
192.168.0.156           53          97   0    0.02    0.01     0.00 cdfhilmrstw *      node-3
И таким:
epoch      timestamp cluster          status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1730297270 14:07:50  my-application green           3         3      7   3    0    0        0             0                  -                100.0%
Во втором выводе важно отметить столбец status, именно он говорит нам о том, как чувствует себя наш кластер. Если статус green, значит все хорошо.
На этом подготовка кластера Elasticsearch завершена. Переходим к настройке Haproxy и Keepalived.
Здесь все еще проще, и я уверен что вы все это делали не один раз. Однако я немного проговорю некоторые нюансы.
1. Первым делом на серверах выделенных под этот кластер внесем некоторые изменения в настройки параметров ядра системы.
Идем в /etc/sysctl.conf и добавляем пару параметров:
net.ipv6.conf.all.disable_ipv6 = 1 
net.ipv6.conf.default.disable_ipv6 = 1 #этими двумя строками отключаем IPv6 net.ipv4.ip_nonlocal_bind = 1 #позволяет отдельным локальным процессам выступать от имени внешнего (чужого) IP-адреса 
net.ipv4.conf.all.arp_ignore = 1 #отвечать на ARP-запрос только в том случае, если целевой IP-адрес является локальным, сконфигурированным на входящем интерфейсе 
net.ipv4.conf.all.arp_announce = 1 #избегать локальных адресов, которые отсутствуют в целевой подсети этого интерфейса 
net.ipv4.conf.all.arp_filter = 0 #выключает связывание IP-адреса с ARP-адресом 
net.ipv4.conf.ens160.arp_filter = 1
Кое-что тут нужно будет подправить,  оставлю вам небольшую пасхалку на подумать.
После того как закончили вносить правки, применяем их:
sysctl -p
2. Настраиваем master-ноду Keepalived, создаем файл по пути /etc/keepalived/keepalived.yml и вносим в него следующее:
global_defs {
    notification_email {
        palchikov@starkovgrp.ru
        smtp_connect_timeout 30
        enable_traps
    }
}
vrrp_script haproxy {
    script "killall -0 haproxy"
    interval 2
    weight 2
}
vrrp_instance VRRP1 {
    state MASTER             # Говорим что наша нода будет мастером
    interface enp0s3         # Указываем интерфейс
    virtual_router_id 69
    priority 50              # Приоритет должен быть выше чем на backup ноде
    advert_int 1
    garp_master_delay 10
    debug 1
    authentication {
        auth_type PASS
        auth_pass 1066
    }
    unicast_src_ip 192.168.0.159 # Указываем ip адрес master ноды
    unicast_peer {
        192.168.0.160            # Указываем ip адрес backup ноды
    }
    virtual_ipaddress {
        192.168.0.161/24 brd 192.168.0.255 scope global # Задаем параметры виртуального ip адреса
    }
    track_script {
        haproxy
    }
}
3. Настраиваем backup-ноду Keepalived, создаем файл по пути /etc/keepalived/keepalived.yml и вносим в него следующее:
global_defs {
    notification_email {
        palchikov@starkovgrp.ru
        smtp_connect_timeout 30
        enable_traps
    }
}
vrrp_script haproxy {
    script "killall -0 haproxy"
    interval 2
    weight 2
}
vrrp_instance VRRP1 {
    state BACKUP                  # Говорим что наша нода будет бэкапом
    interface enp0s3              # Указываем интерфейс
    virtual_router_id 69
    priority 49                   # Указываем приоритет ниже чем у мастера
    advert_int 1
    garp_master_delay 10
    debug 1
    authentication {
        auth_type PASS
        auth_pass 1066
    }
    unicast_src_ip 192.168.0.160  # Указываем ip адрес backup ноды
    unicast_peer {
        192.168.0.159             # Указываем ip адрес master ноды
    }
    virtual_ipaddress {
        192.168.0.161/24 brd 192.168.0.255 scope global
    }
    track_script {
        haproxy
    }
}
4. Следующий этап - настроить Haproxy.
Конфигурация на обоих серверах должна быть идентична. У меня получилось следующее, но в реалиях конкретного случая конфигурация может меняться:
frontend haproxy_test
        bind *:80
        mode http
        default_backend haproxy_backend
backend haproxy_backend
        mode http
        balance source
        option http-server-close
        option httpchk
        server el01 192.168.0.102:9200 check
        server el02 192.168.0.156:9200 check
        server el03 192.168.0.157:9200 check
Как вы видите, указана балансировка типа Source. Это алгоритм балансировки, при котором активный сервер всегда один, а другие в ожидании. Они включаются по очереди только после выхода из строя активного сервера.
Я также настроил проверку сервисов таким образом, что Haproxy должен получать статус код 200, и если он его не получает, то переводит запросы на другую ноду кластера. 
5. Запускаем Haproxy и Keepalived с помощью systemctl start ... и аналогичным образом добавим эти сервисы в автозагрузку.
6. Проверяем, что все у нас работает корректно. Для этого мы идем на мастер-ноду и вводим команду ip a:
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:43:22:4d brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.159/24 brd 192.168.0.255 scope global enp0s3
       valid_lft forever preferred_lft forever
    inet 192.168.0.161/24 brd 192.168.0.255 scope global secondary enp0s3
       valid_lft forever preferred_lft forever
Мы сразу видим наш виртуальный ip адрес.
Вводим эту же команду на бэкап-ноде:
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:f3:7d:8b brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.160/24 brd 192.168.0.255 scope global enp0s3
       valid_lft forever preferred_lft forever
Виртуальный ip не указан, значит пока все работает так, как мы и предполагали.
Далее отключаем Haproxy на мастер-ноде:
systemctl stop haproxy
И еще раз проверяем ip адреса на обеих нодах:
Мастер-нода:
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:43:22:4d brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.159/24 brd 192.168.0.255 scope global enp0s3
       valid_lft forever preferred_lft forever
Бэкап-нода:
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:f3:7d:8b brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.160/24 brd 192.168.0.255 scope global enp0s3
       valid_lft forever preferred_lft forever
    inet 192.168.0.161/24 brd 192.168.0.255 scope global secondary enp0s3
       valid_lft forever preferred_lft forever
Магия, не иначе... Идем дальше)))
Рассказывать и показывать как устанавливается и настраивается DirectumRX я думаю смысла нет, однако следует отметить, что в параметре ELASTICSEARCH_URL секции common_config мы указываем наш виртуальный ip адрес и порт, который слушает наш Haproxy. У меня получилось примерно вот так:
ELASTICSEARCH_URL: 'http://192.168.0.161:80'
Создаем в системе какие-нибудь документы, если они были не созданы и/или проводим первоначальное индексирование:
./do.sh initialindexing run --command="-d"
Если мы понимаем, что размер наших индексов будет достаточно большой, мы можем настроить шарды и количество реплик по инструкции Directum "Администрирование (Linux) > Общесистемные настройки > Настройка полнотекстового поиска". Однако у меня реализовать этот функционал не получилось. С чем связано, не знаю.. либо у меня руки кривые, либо еще что... Если у вас был положительный опыт в этом направлении, жду обратную связь. А пока идем дальше...
После проведения первоначального индексирования мы возвращаемся к нашему кластеру Elasticsearch и смотрим что получилось:
curl -k http://localhost:9200/_cat/indices?v
health status index                       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   rxsearch_document_test_test fitUwqoAQ9msz-ugTLVweQ   1   0         85            0    459.8kb        459.8kb
В данном выводе мы видим, что у нас создался 1 индекс и находится в статусе green. Он также имеет 1 шард и 0 реплик (значения по умолчанию).
Посмотрим, что у нас с шардами происходит:
index                                                         shard prirep state   docs   store ip            node
.ds-ilm-history-5-2024.10.30-000001                           0     r      STARTED              192.168.0.157 node-2
.ds-ilm-history-5-2024.10.30-000001                           0     p      STARTED              192.168.0.102 node-1
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     r      STARTED              192.168.0.157 node-2
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     p      STARTED              192.168.0.156 node-3
rxsearch_document_test_test                                   0     p      STARTED   85 459.8kb 192.168.0.156 node-3
Здесь мы видим, что есть 1 шард, без реплик и заодно видим, на какой ноде находится.
А тут возникает вопрос: а зачем мы создавали еще 2 ноды, если шард один, а реплик нет вообще? Давайте создадим реплики!
Вбиваем команду:
curl -X PUT -k http://localhost:9200/rxsearch_document_test_test/_settings -H 'Content-Type: application/json' -d '{"index" : { "number_of_replicas": 2}}'
После указания порта вписываем имя индекса, а в параметре number_of_replicas вбиваем количество реплик. Я задам 2 реплики.
Проверяем:
index                                                         shard prirep state   docs   store ip            node
.ds-ilm-history-5-2024.10.30-000001                           0     r      STARTED              192.168.0.157 node-2
.ds-ilm-history-5-2024.10.30-000001                           0     p      STARTED              192.168.0.102 node-1
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     r      STARTED              192.168.0.157 node-2
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     p      STARTED              192.168.0.156 node-3
rxsearch_document_test_test                                   0     r      STARTED   85 459.8kb 192.168.0.157 node-2
rxsearch_document_test_test                                   0     p      STARTED   85 459.8kb 192.168.0.156 node-3
rxsearch_document_test_test                                   0     r      STARTED   85 459.8kb 192.168.0.102 node-1
Наши реплики распространились по двум другим нодам кластера. Этого мы и добивались.
Теперь создадим документ в DirectumRX с кодовым словом Опоки и проверим, проиндексировался ли он.
Проверяем работу полнотекстового поиска:
Вот он наш документ. Пока все нормально, идем дальше.
Смотрим, что происходит на сервере с Elasticsearch:
# Проверка до создания документа
root@el02:/home/user# curl -k http://localhost:9200/_cat/shards?v
index                                                         shard prirep state   docs   store ip            node
.ds-ilm-history-5-2024.10.30-000001                           0     r      STARTED              192.168.0.157 node-2
.ds-ilm-history-5-2024.10.30-000001                           0     p      STARTED              192.168.0.102 node-1
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     r      STARTED              192.168.0.157 node-2
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     p      STARTED              192.168.0.156 node-3
rxsearch_document_test_test                                   0     r      STARTED   85 459.8kb 192.168.0.157 node-2
rxsearch_document_test_test                                   0     p      STARTED   85 459.8kb 192.168.0.156 node-3
rxsearch_document_test_test                                   0     r      STARTED   85 459.8kb 192.168.0.102 node-1
# Проверка после создания документа
root@el02:/home/user# curl -k http://localhost:9200/_cat/shards?v
index                                                         shard prirep state   docs   store ip            node
.ds-ilm-history-5-2024.10.30-000001                           0     r      STARTED              192.168.0.157 node-2
.ds-ilm-history-5-2024.10.30-000001                           0     p      STARTED              192.168.0.102 node-1
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     r      STARTED              192.168.0.157 node-2
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     p      STARTED              192.168.0.156 node-3
rxsearch_document_test_test                                   0     r      STARTED   86 468.4kb 192.168.0.157 node-2
rxsearch_document_test_test                                   0     p      STARTED   85 459.8kb 192.168.0.156 node-3
rxsearch_document_test_test                                   0     r      STARTED   85 459.8kb 192.168.0.102 node-1
Здесь мы видим, что документ был проиндексирован и, судя по выводу, он находится на 2 ноде. Данные будут синхронизированы через какое-то время. Я жду еще 5 секунд, и проверяю:
   index                                                         shard prirep state   docs   store ip            node
.ds-ilm-history-5-2024.10.30-000001                           0     r      STARTED              192.168.0.157 node-2
.ds-ilm-history-5-2024.10.30-000001                           0     p      STARTED              192.168.0.102 node-1
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     r      STARTED              192.168.0.157 node-2
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     p      STARTED              192.168.0.156 node-3
rxsearch_document_test_test                                   0     r      STARTED   86 468.5kb 192.168.0.157 node-2
rxsearch_document_test_test                                   0     p      STARTED   86 468.5kb 192.168.0.156 node-3
rxsearch_document_test_test                                   0     r      STARTED   86 468.5kb 192.168.0.102 node-1
Все круто! Данные синхронизированы, все работает корректно.
А что будет, если отключить 1 из нод? Например ту, где находится наш шард. В данный момент, наш шард лежит на 3 ноде. Выключаем ее и проверяем, что у нас произойдет:
ip            heap.percent ram.percent cpu load_1m load_5m load_15m node.role   master name
192.168.0.102           63          96   0    0.19    0.06     0.01 cdfhilmrstw -      node-1
192.168.0.157           40          97   3    0.19    0.07     0.02 cdfhilmrstw *      node-2
Количество нод - 2, ожидаемо.
Проверим статус кластера:
epoch      timestamp cluster          status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1730301561 15:19:21  my-application   yellow          2         2      6   3    0    0        1             0                  -                 85.7%
Статус кластера yellow. Пока он функционирует нормально, но если вывести из строя еще одну ноду, кластер разрушится.
Проверим статус индекса:
health status index                       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   rxsearch_document_test_test fitUwqoAQ9msz-ugTLVweQ   1   2         86            0    937.1kb        468.5kb
Статус индекса yellow. В данный момент это связано с тем, что он не может разместить вторую реплику в данном кластере.
Убедимся в этом:
index                                                         shard prirep state      docs   store ip            node
rxsearch_document_test_test                                   0     p      STARTED      86 468.5kb 192.168.0.157 node-2
rxsearch_document_test_test                                   0     r      STARTED      86 468.5kb 192.168.0.102 node-1
rxsearch_document_test_test                                   0     r      UNASSIGNED
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     p      STARTED                 192.168.0.157 node-2
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     r      STARTED                 192.168.0.102 node-1
.ds-ilm-history-5-2024.10.30-000001                           0     r      STARTED                 192.168.0.157 node-2
.ds-ilm-history-5-2024.10.30-000001                           0     p      STARTED                 192.168.0.102 node-1
Видим, что одна реплика перешла в положение UNASSIGNED. И обратите внимание, что шард переехал на 2 ноду.
Проверим работоспособность кластера из системы Directum RX:
Успех! Документ найден, и все работает корректно.
Теперь добавим новый документ и проверим, добавится ли он в кластер. Для этого создадим документ из того же файла, только назовем его test2.
Документ проиндексировался, все нормально.
Включаем 3 ноду и проверяем, что документ синхронизировался в кластере:
index                                                         shard prirep state   docs   store ip            node
rxsearch_document_test_test                                   0     p      STARTED   87 477.2kb 192.168.0.157 node-2
rxsearch_document_test_test                                   0     r      STARTED   87 477.2kb 192.168.0.102 node-1
rxsearch_document_test_test                                   0     r      STARTED   87 477.3kb 192.168.0.156 node-3
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     p      STARTED              192.168.0.157 node-2
.ds-.logs-deprecation.elasticsearch-default-2024.10.30-000001 0     r      STARTED              192.168.0.156 node-3
.ds-ilm-history-5-2024.10.30-000001                           0     r      STARTED              192.168.0.157 node-2
.ds-ilm-history-5-2024.10.30-000001                           0     p      STARTED              192.168.0.102 node-1
Видим, что реплика снова добавлена и система работает стабильно. А также видим, что счетчик документов обновился:
root@el02:/home/user# curl -k http://localhost:9200/_cat/indices?v
health status index                       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   rxsearch_document_test_test fitUwqoAQ9msz-ugTLVweQ   1   2         87            0      1.3mb        477.2kb
root@el02:/home/user# curl -k http://localhost:9200/_cat/health?v
epoch      timestamp cluster          status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1730302325 15:32:05  my-application   green           3         3      7   3    0    0        0             0                  -                100.0%
Данное решение выглядит немного костыльным и работает не совсем так, как мы привыкли ожидать от кластера Elasticsearch. Однако следует отметить, что если стоит задача обеспечить отказоустойчивый кластер полнотекстового поиска, то данный подход можно смело использовать в проектах.
Авторизуйтесь, чтобы написать комментарий