From d1c6d18affad7aaa90410f229da758b7240878a2 Mon Sep 17 00:00:00 2001 From: gcolpart Date: Sun, 6 Nov 2016 18:25:17 +0100 Subject: [PATCH] =?UTF-8?q?am=C3=A9lioration=20du=20mode=20cluster,=20ajou?= =?UTF-8?q?t=20d'infos,=20gestion=20d'instances=20sur=20un=20m=C3=AAme=20m?= =?UTF-8?q?achine,=20etc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HowtoElasticsearch.md | 199 ++++++++++++++++++++++++++---------------- 1 file changed, 124 insertions(+), 75 deletions(-) diff --git a/HowtoElasticsearch.md b/HowtoElasticsearch.md index b8fa7245..2bbdc2d3 100644 --- a/HowtoElasticsearch.md +++ b/HowtoElasticsearch.md @@ -41,7 +41,7 @@ Created symlink from /etc/systemd/system/multi-user.target.wants/elasticsearch.s ## Configuration de base Les paramètres système (répertoires utilisés, configuration JVM) se trouvent dans le fichier `/etc/default/elasticsearch`, -les options applicatives (mémoire, réseau, cluster) se trouvent dans le fichier `/etc/elasticsearch/elasticsearch.yml`. +les options applicatives (nom du cluster, nom du nœud, mémoire, réseau) se trouvent dans le fichier `/etc/elasticsearch/elasticsearch.yml`. Il faut activer le redémarrage automatique en cas de mise à jour (classique sous Debian). On peut aussi définir un *tmpdir* spécifique (utile quand `/tmp` est en _noexec_) dans `/etc/default/elasticsearch` : @@ -116,87 +116,24 @@ L'interface **Kopf** est ainsi disponible sur http://127.0.0.1:9200/_plugin/kopf L'interface **Head** est ainsi disponible sur http://127.0.0.1:9200/_plugin/head/ -## Mode cluster +## Configuration avancée -_Paragraphe à revoir car l'auto-découverte et le multicast ont changé._ - -Exemples avec 3 instances nommés **elastic1**, **elastic2** et **elastic3**. - -Spécifier un nom de cluster commun dans `elasticsearch.yml` sur chaque machine. +* Si on veut lancer Elasticsearch avec une JVM différente que celle par défaut sur le système, on peut définir JAVA_HOME dans `/etc/default/elasticsearch` : ~~~ -cluster.name: mycluster +JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre/ ~~~ -On donnera un nom aux nœuds avec la directive suivante : +Le wrapper qui lance Elasticsearch est `/usr/share/elasticsearch/bin/elasticsearch` voici les options possibles : -~~~ -node.name: "elastic1" -~~~ +* `-Edefault.path.XXX=/foo/` : répertoire à utiliser (XXX peut être *conf*, *data*, *logs* etc.) +* `-d` : lancer en mode daemon +* `-p /var/run/elasticsearch/elasticsearch.pid` : chemin du fichier PID +* `--quiet` : mode silencieux -En analysant les logs de **elastic2** on verra ceci : +## Monitoring -~~~ -/var/log/elasticsearch/mycluster.log: -[2013-10-03 15:52:59,863][INFO ][transport ] [elastic2] bound_add -ress {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/192.168.4.205:9300]} -[2013-10-03 15:53:03,247][INFO ][cluster.service ] [elastic2] detected_ -master [elastic1][3tn7uHSHR8-donXO6JXFRA][inet[/192.168.4.201:9300]], added {[el -astic1][3tn7uHSHR8-donXO6JXFRA][inet[/192.168.4.201:9300]],}, reason: zen-disco- -receive(from master [[elastic1][3tn7uHSHR8-donXO6JXFRA][inet[/192.168.4.201:9300 -]]]) -[2013-10-03 15:53:03,338][INFO ][discovery ] [elastic2] mycluster -/aFsNsA7pRa2_injvAU5Hwg -[2013-10-03 15:53:03,362][INFO ][http ] [elastic2] bound_add -ress {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/192.168.4.205:9200]} -[2013-10-03 15:53:03,362][INFO ][node ] [elastic2] started -~~~ - -Indiquant que le master a été détecté. - -Et sur **elastic1**, le master : - -~~~ -[2013-10-03 15:53:03,176][INFO ][cluster.service ] [elastic1] added {[e -lastic2][aFsNsA7pRa2_injvAU5Hwg][inet[/192.168.4.205:9300]],}, reason: zen-disco --receive(join from node[[elastic2][aFsNsA7pRa2_injvAU5Hwg][inet[/192.168.4.205:9 -300]]]) -[2013-10-03 15:54:37,112][INFO ][cluster.service ] [elastic1] added {[e -lastic3][CLCB_hU5TeGXLziFcLjY8w][inet[/192.168.4.204:9300]],}, reason: zen-disco --receive(join from node[[elastic3][CLCB_hU5TeGXLziFcLjY8w][inet[/192.168.4.204:9 -300]]]) -~~~ - -Indique que les deux slaves ont été ajoutés. - -On peut consulter le *status* en faisant des requêtes de types RESTFul. : - -~~~{.bash} -$ curl 'http://localhost:9200/_nodes?pretty=true' -~~~ - -Si le master passe en DOWN, un autre est élu. - -~~~ -[2013-10-03 16:15:53,892][INFO ][discovery.zen ] [elastic2] master_le -ft [[elastic1][3tn7uHSHR8-donXO6JXFRA][inet[/192.168.4.201:9300]]], reason [shut -_down] - -[2013-10-03 16:15:53,920][INFO ][cluster.service ] [elastic2] master {n -ew [elastic3][CLCB_hU5TeGXLziFcLjY8w][inet[/192.168.4.204:9300]], previous [elas -tic1][3tn7uHSHR8-donXO6JXFRA][inet[/192.168.4.201:9300]]}, removed {[elastic1][3 -tn7uHSHR8-donXO6JXFRA][inet[/192.168.4.201:9300]],}, reason: zen-disco-receive(f -rom master [[elastic3][CLCB_hU5TeGXLziFcLjY8w][inet[/192.168.4.204:9300]]]) -~~~ - -Pour éviter de faire des requêtes multicast (mode auto-découverte). On spécifiera la liste des nœuds dans la configuration des instances. - -~~~ -discovery.zen.ping.multicast.enabled: false -discovery.zen.ping.unicast.hosts: ["elastic2", "elastic3"] -~~~ - -## Check Nagios +### Nagios On check sur la page `/_cat/health` si le status n'est pas en **red**. @@ -345,7 +282,63 @@ $ for i in $(ls -1d snapshot-* | head -n -10 | sed s'/snapshot-snapshot_//g'); d hot_${i}"; done ~~~ -## Principe de fonctionnement +## cluster + + + +Si l'on compare à d'autres services (MySQL, PostgreSQL, MongoDB..) la gestion d'un cluster Elasticsearch est vraiment simple. +Il faut lancer plusieurs instances Elasticsearch sur un réseau avec le même **cluster.name** et un **node.name** différent, et il suffitd'indiquer une (ou plusieurs) adresse(s) IP qui va permettre à l'instance de communiquer avec un (ou plusieurs) autre(s) nœud(s) : + +~~~ +cluster.name: foo +node.name: bar0 +node.master: true +node.data: true +discovery.zen.ping.unicast.hosts: ["192.0.2.42"] +~~~ + +En démarrant un 2ème nœud **bar1** on verra ainsi dans les logs de l'instance master bar0 que le cluster passe de YELLOW à GREEN : + +~~~ +[INFO ][o.e.c.s.ClusterService ] [bar0] added {{bar1}{_jwXmQsAQEyseSOc4pG2IA}{PTpsbMBAQEKTs_OFgW_RYw}{192.0.2.42}{192.0.2.42:9301},}, reason: zen-disco-node-join[{bar1}{_jwXmQsAQEyseSOc4pG2IA}{PTpsbMBAQEKTs_OFgW_RYw}{192.0.2.42}{192.0.2.42:9301}] +[WARN ][o.e.d.z.ElectMasterService] [bar0] value for setting "discovery.zen.minimum_master_nodes" is too low. This can result in data loss! Please set it to at least a quorum of master-eligible nodes (current value: [-1], total number of master-eligible nodes used for publishing in this round: [2]) +[INFO ][o.e.c.r.a.AllocationService] [bar0] Cluster health status changed from [YELLOW] to [GREEN] (reason: [shards started [[.monitoring-data-2][0]] ...]). +~~~ + + +On peut consulter le statut du cluster via la requête : + +~~~ +$ curl 'http://localhost:9200/_nodes?pretty=true' + +{ + "_nodes" : { + "total" : 3, + "successful" : 3, + "failed" : 0 + }, + "cluster_name" : "foo", + "nodes" : { + "4Tt8FlV4TG2Hf_1T4EayQg" : { + "name" : "bar0", +[...] +~~~ + +On voit ainsi qu'il y a 3 nœuds dans le cluster. + +Si l'on coupe le master, un autre est élu : + +~~~ +[INFO ][o.e.d.z.ZenDiscovery ] [bar2] master_left [{bar0}{4Tt8FlV4TG2Hf_1T4EayQg}{5nbXw3F5RWCWjUSiRzv9DA}{192.0.2.42}{192.0.2.42:9300}], reason [shut_down] +[WARN ][o.e.d.z.ZenDiscovery ] [bar2] master left (reason = shut_down), current nodes: {{bar2}{5wUhAI79SsyY-DKv4va26Q}{_VQTiZXxTCi2KIsijyQBpg}{192.0.2.42}{192.0.2.42:9302},{bar1}{_jwXmQsAQEyseSOc4pG2IA}{_pQMtkFLSTe3p-eDHMkalw}{192.0.2.42}{192.0.2.42:9301},} +[INFO ][o.e.c.s.ClusterService ] [bar2] removed {{bar0}{4Tt8FlV4TG2Hf_1T4EayQg}{5nbXw3F5RWCWjUSiRzv9DA}{192.168.0.133}{192.168.0.133:9300},}, reason: master_failed ({bar0}{4Tt8FlV4TG2Hf_1T4EayQg}{5nbXw3F5RWCWjUSiRzv9DA}{192.0.2.42}{192.0.2.42:9300}) +[INFO ][o.e.c.r.a.AllocationService] [bar2] Cluster health status changed from [GREEN] to [YELLOW] (reason: [removed dead nodes on election]). +[INFO ][o.e.c.s.ClusterService ] [bar2] new_master {bar2}{5wUhAI79SsyY-DKv4va26Q}{_VQTiZXxTCi2KIsijyQBpg}{192.168.0.133}{192.168.0.133:9302}, reason: zen-disco-elected-as-master ([0] nodes joined) +[INFO ][o.e.c.r.DelayedAllocationService] [bar2] scheduling reroute for delayed shards in [59.8s] (2 delayed shards) +[INFO ][o.e.c.r.a.AllocationService] [bar2] Cluster health status changed from [YELLOW] to [GREEN] (reason: [shards started [[.monitoring-es-2-2016.11.06][0]] ...]). +~~~ + +## Principe de fonctionnement d'Elasticsearch _Basé sur le livre _ @@ -378,6 +371,7 @@ Créer un index (équivalent d'une base de données) nommé *planet* : ~~~{.bash} $ curl -X PUT localhost:9200/planet +{"acknowledged":true,"shards_acknowledged":true} ~~~ Créer un type de donnée nommé « hacker » : @@ -403,24 +397,38 @@ Créer un document de type hacker avec l'ID 1 : ~~~{.bash} $ curl -X PUT localhost:9200/planet/hacker/1 -d '{"handle": "jean-michel", "age": 18}' +{"_index":"planet","_type":"hacker","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"created":true ~~~ Voir son contenu : ~~~{.bash} $ curl localhost:9200/planet/hacker/1?pretty=true +{ + "_index" : "planet", + "_type" : "hacker", + "_id" : "1", + "_version" : 1, + "found" : true, + "_source" : { + "handle" : "jean-michel", + "age" : 18 + } +} ~~~ Mise à jour du champ âge : ~~~{.bash} $ curl -X POST localhost:9200/planet/hacker/1/_update -d '{"doc": {"age": 19}}' +{"_index":"planet","_type":"hacker","_id":"1","_version":2,"result":"updated","_shards":{"total":2,"successful":1,"failed":0}} ~~~ Suppression du document : ~~~{.bash} $ curl -X DELETE localhost:9200/planet/hacker/1 +{"found":true,"_index":"planet","_type":"hacker","_id":"1","_version":3,"result":"deleted","_shards":{"total":2,"successful":1,"failed":0}} ~~~ #### Recherche basique @@ -429,6 +437,7 @@ Recréons un index de test : ~~~ $ curl -X DELETE localhost:9200/planet +{"acknowledged":true} $ curl -X PUT localhost:9200/planet -d ' { "mappings": { @@ -504,3 +513,43 @@ to map segment from shared object: Operation not permitted ~~~ C'est peut-être que vous avez votre partition `/tmp` en _noexec_, il faut alors changer le chemin comme indiqué sur [#configuration-de-base]() + +### Lancer plusieurs instances sur un même système pour du test + +Il faut définir 3 paramètres minimum pour lancer une instance Elasticsearch : +* default.path.conf (répertoire de configuration) +* default.path.data (répertoire pour les données) +* default.path.logs (répertoire pour les logs) + +~~~ +# cp -pr /etc/elasticsearch /usr/local/etc/elasticsearch0 +# mkdir -p /srv/es-data/bar0 /srv/es-log/bar0 +# chown elasticsearch: /srv/es-data/bar0 /srv/es-log/bar0 +~~~ + +Configuration via `/usr/local/etc/elasticsearch0/elasticsearch.yml` : + +~~~ +cluster.name: foo +node.name: bar0 +node.master: true +node.data: true +~~~ + +On peut ensuite lancer cette nouelle instance en ligne de commande : + +~~~ +# su -s /bin/sh elasticsearch +$ /usr/share/elasticsearch/bin/elasticsearch -Edefault.path.conf=/usr/local/etc/elasticsearch0 \ + -Edefault.path.data=/srv/es-data/bar0 -Edefault.path.logs=/srv/es-log/bar0 +~~~ + +Note : si Elasticsearch nécessite une version de Java différent (Java 8 pour Elasticsearch 5.0), il suffit d'ajouter la variable JAVA_HOME en début de ligne de commande : + +~~~ +$ JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre/ /usr/share/elasticsearch/bin/elasticsearch [...] +~~~ + +### Erreur "missing authentication token for REST request" + +Si vous obtenez une erreur HTTP *401 Unauthorized* avec le détail "missing authentication token for REST request...", c'est probablement que le plugin [shield](https://www.elastic.co/guide/en/shield/current/installing-shield.html) est activé.