Зачем все это нужно
Все кто использовал Elasticsearch каластер для своих нужд (особенно для логирования и как основную базу данных) на больших нагрузках сталкивался с проблемами консистентности и масштабируемости. Когда требуется распараллелить нагрузку на Elasticsearch обычно применялись статические решения то типу NGINX+Elasticsearch. Это позволяет распараллелить нагрузку, но выглядит не слишком гибко. Особенно если учесть что ноды могут сами выпадать из кластера и простой хелсчек покажет что все отлично, а на самом деле нода перегружена, исключена из кластера. В любом случае хотелось бы иметь данные о состоянии кластера из первых рук, а не довольствоваться простыми проверками.
Итак, приступим к построению балансировки .
Как мы будем это делать
В данном случае мы будем использовать CAT node API, которое является частъю мощнейшего CAT API, который является инструментом поиска заголовков по Elasticsearch клстреру.
Мы будем использовать только Gobetween и встроенные механизмы Elasticsearch для балансировки записи /чтения СRUD (DATA) нод при произвольном количестве/статусе нод в кластере.
Предварительные настройки
Нам потребуются:
Elasticsearch client node :
Нужна специально для gobetween т.к. при мультимастер конфигурации она сама будет перенаправлять запрос на правильную мастер ноду(активный мастер), и таким образом будет нашим роутером внутри кластера для корректной работы нашего Data Node discovery.
В elasticsearch.conf на client ноде прописываем:
 node.master: false
 node.data: false и остальные настройки идентичные настройкам нод в вашем кластере.
Скрипт для дискавери:
Теперь создадим скрипт который будет запрашивать API и возвращать нам список нод.
назовем его discovery_elasticsearch.sh :
#!/bin/bash
 curl -sS -XGET 'http://PI_OF_YOUR_CLIENT_NODE:9200/_cat/nodes?v&h=ip,r=d' |sed '1d'|tr -d ' '|sed 's/$/:9200/'вывод скрипта будет примерно таким :
 10.0.0.51:9200
 10.0.0.55:9200
 10.0.0.53:9200
 10.0.0.52:9200
 10.0.0.54:9200
 итд...В данном случае скрипт на возвращает вес каждой ноды, тогда вес проставляется балансировщиком автоматически одинаковый — "1".
Теперь все готово, и можно начинать настраивать непосредственно сам балансер.
Настройка балансировщика
После установки настало время настроить балансировку используя EXEC discovery и round robin алгоритм балансировки.
Данный пример довольно простой и служит для описания возможностей данного типа балансировки. Можно расширить скрипт для динамической генерации весов для каждой ноды по их загрузке (cpu,io и т.д.).
конфиг нашего балансера будет выглядеть :
[logging]
level = "warn"    # "debug" | "info" | "warn" | "error"
output = "stdout" # "stdout" | "stderr" | "/path/to/gobetween.log"
[defaults] 
max_connections = 0
client_idle_timeout = "0"
backend_idle_timeout = "0"
backend_connection_timeout = "0"
[servers.sample3]
 bind = "100.100.1.5:9200"
 protocol = "tcp"
 balance = "weight"
 [servers.sample3.discovery]
 kind = "exec"
 exec_command = ["/etc/gobetween/discovery_elasticsearch.sh"] 
 interval="1m"
 timeout = "10s"                            
 [servers.sample3.healthcheck]
kind = "ping"
 interval = "20s"
 timeout = "2s"
 fails = 3
 passes = 3Итак, мы имеем "рыбу" решения для построения гибкой балансировки в elasticsearch кластере.
В "боевых" условиях у нас работет более сложная конфигурация с динамическим определением весов.
Так же в нашем продакшне мы используем сложный скрипт хелсчека тоже завязанного на API мониторинга и самого Elasticsearch.
- первая обзорная статъя
 - DRAFT Rest API
 - Проект на Github
 - Вики на Github
 - тесты производительности
 - Установка под Windows
 
В Следующих статьях — json discovery, windocker service discovery и балансировка, Windows swarm service discovery и балансировка, Балансировка (Windows+linux) Doсker окружений.