diff --git a/_posts/2012-08-21-au-coeur-d-elasticsearch.markdown b/_posts/2012-08-21-au-coeur-d-elasticsearch.markdown index 38e5acd..bf4cc9d 100644 --- a/_posts/2012-08-21-au-coeur-d-elasticsearch.markdown +++ b/_posts/2012-08-21-au-coeur-d-elasticsearch.markdown @@ -4,7 +4,13 @@ title: Au coeur d'ElasticSearch author: filirom1 tags: [index, elasticsearch, lucene] --- -Au cœur d'[ElasticSearch](http://www.elasticsearch.org/) il y a le moteur d'indexation [Lucene](http://lucene.apache.org/), et autour de Lucene il y a plusieurs mécanismes afin de rendre le système scalable et tolérant aux pannes. Commençons par comprendre comment Lucene fonctionne, et nous finirons par les mécanismes de distribution et de tolérance aux pannes mis en place dans ElasticSearch: +Au cœur d'[ElasticSearch](http://www.elasticsearch.org/) il y a le moteur d'indexation [Lucene](http://lucene.apache.org/), +et autour de Lucene il y a plusieurs mécanismes afin de rendre le système scalable et tolérant aux pannes. +Ce sont ces deux parties qui m'ont intéressé pour cet article. + +Je ne suis pas contributeur sur le projet, ma vision est donc limitée à ce que j'ai compris en utilisant ElasticSearch, +ou simplement en lisant [la mailing list](https://groups.google.com/forum/?fromgroups#!forum/elasticsearch), le [site officiel](http://www.elasticsearch.org/) ou des articles de blog. +Vous trouverez dans cet article un certain nombre de lien pointant sur les ressources m'ayant éclairée.
@@ -48,7 +54,7 @@ Une fois le texte analysé et transformé, il faut maintenant le stocker dans un
Le contenu de l'index inversé ressemblera à ça:
-Inverted Index:
+Index Inversé:
"road" : {Doc1}
"distributed" : {Doc1}
@@ -61,7 +67,7 @@ Maintenant opérons de même pour la phrase suivante : Doc2 = 'ElasticSearch a d
L'index inversé ressemble maintenant à ça:
-Inverted Index:
+Index Inversé:
"road" : {Doc1}
"distributed" : {Doc1, Doc2}
@@ -77,7 +83,7 @@ Un index inversé peut être vu comme une base [clé: multiples valeurs](http://
Maintenant que nous avons une base clé - multiple valeurs, il est assez facile de faire une recherche sur un terme:
- Get from index: "engine" => {Doc1,Doc2}
+ Récupérer dans l'index: "engine" => {Doc1,Doc2}
Les IDs des documents nous sont retournés.
@@ -85,18 +91,17 @@ Les IDs des documents nous sont retournés.
Si nous souhaitons que ce soit le document et non l'ID qui soit retourné, il faut stocker le document à côté.
-Storage:
+Stockage:
"Doc1":"Road to a Distributed Search Engine"
"Doc2":"ElasticSearch a distributed, RESTful Search Engine"
Il faut donc interroger les deux bases : l'index inversé puis la base clé-valeur contenant les documents.
- Get from index: "engine" => {Doc1,Doc2}
- Get from storage: Doc1 AND Doc2 => ["Road to a Distributed Search Engine", "ElasticSearch a distributed, RESTful Search Engine"]
-
+ Récupérer dans l'index: "engine" => {Doc1,Doc2}
+ Récupérer dans la base de stockage: Doc1 ET Doc2 => ["Road to a Distributed Search Engine", "ElasticSearch a distributed, RESTful Search Engine"]
-Mais le fait de stocker le document en plus de l'index est couteux en mémoire. Nous pouvons donc imaginer fonctionner sans stockage de documents : [ElasticSearch-source-field](http://www.elasticsearch.org/guide/reference/mapping/source-field.html), [Lucene-store-field](http://lucene.apache.org/core/3_6_0/api/all/org/apache/lucene/document/Field.Store.html)
+Par défaut ElasticSearch [index et stocke](http://www.elasticsearch.org/guide/reference/mapping/source-field.html) la donnée de manière completement transparente pour l'utilisateur, mais ceci est [configurable](https://groups.google.com/d/msg/elasticsearch/k_YgO8xspXE/eqY_SHEwgCMJ).
## Requêtes et Analysers
@@ -105,15 +110,15 @@ Lors de l'indexation du premier document : 'Road to a Distributed Search Engine'
Si nous recherchons les mots initiaux dans l'index inversé, nous n'obtiendrons aucun résultat:
- Get from index: "Road" => {}
- Get from index: "Distributed" => {}
+ Récupérer dans l'index: "Road" => {}
+ Récupérer dans l'index: "Distributed" => {}
Les mots avaient été indexés en minuscule.
Il est donc important d'appliquer les mêmes Analysers pour l'indexation et la recherche. C'est le comportement par défaut dans ElasticSearch.
- Search: "Road" => {}
- Get from index: "road => {Doc1}
+ Rechercher: "Road" => {}
+ Récupérer dans l'index: "road => {Doc1}
## Syntaxe de requête
@@ -121,7 +126,7 @@ Il est donc important d'appliquer les mêmes Analysers pour l'indexation et la r
Et si nous cherchions "(road OR path) AND search"
-Inverted Index:
+Index Inversé:
"road" : {Doc1}
"distributed" : {Doc1, Doc2}
@@ -132,12 +137,12 @@ Inverted Index:
Query:
- Get from index: "road => {Doc1}
- Get from index: "path => {}
- Evaluate: (road OR path) => {Doc1}
- Get from index: "search => {Doc1, Doc2}
- Evaluate: (road OR path) AND search => {Doc1}
- Return => {Doc1}
+ Récupérer dans l'index: "road => {Doc1}
+ Récupérer dans l'index: "path => {}
+ Evaluer: (road OU path) => {Doc1}
+ Récupérer dans l'index: "search => {Doc1, Doc2}
+ Evaluer: (road OU path) ET search => {Doc1}
+ Retourner => {Doc1}
A partir d'un index inversé nous pouvons commencer à construire des requêtes complexes
[Syntaxe des requêtes Lucene](http://lucene.apache.org/core/3_6_1/queryparsersyntax.html).
@@ -169,12 +174,12 @@ Mais en réalité Lucene permet d'indexer des objets complexes, et faire des rec
}
Lucene permet d'indexer du texte mais pas seulement; il permet aussi d'indexer des nombres, des tableaux, des objets de géo-distances, ...
-Voici la liste des [types primitifs](http://lucene.apache.org/core/3_6_1/fileformats.html#Primitive Types) indexables dans Lucene.
+Voici la liste des [types primitifs](http://lucene.apache.org/core/3_6_1/fileformats.html#Primitive_Types) indexables dans Lucene.
### Structuration des fichiers Lucene
-Une base Lucene est constituée d'un certain nombre de [fichiers](http://lucene.apache.org/core/3_6_1/fileformats.html#file-names):
+[Une base Lucene est constituée d'un certain nombre de fichiers](http://lucene.apache.org/core/3_6_1/fileformats.html#file-names):
$ cd /DATA/smartdata/search-bench/nodes/0/indices/4e60bb2aeea3ef8c39000001/0/index
$ ls -lh _2u*
@@ -191,7 +196,7 @@ Une base Lucene est constituée d'un certain nombre de [fichiers](http://lucene.
* .fdx : Index permettant de retrouver les champs dans le fichier .fdt
* .fnm : Contient le nom des champs
* .frq : Index inversé qui contient également la fréquence d'occurrence de chaque terme
- * .nrm : Normalise l'importance de chaque terme relativement à la longueur du texte, ou via un facteur de [boost](http://lucene.apache.org/core/3_6_1/queryparsersyntax.html#Boosting%20a%20Term)
+ * .nrm : Normalise l'importance de chaque terme relativement à la longueur du texte, ou via un [facteur de boost](http://lucene.apache.org/core/3_6_1/queryparsersyntax.html#Boosting%20a%20Term)
* .prx : Stocke la position des termes dans le texte initiale
* .tii : Fichier complètement chargé en mémoire qui permettra de lire le fichier .tis
* .tis : Dictionnaire des termes
@@ -214,7 +219,7 @@ Ces fichiers qui constituent [un segment](http://lucene.apache.org/core/3_6_0/fi
Tout ajout de données sera fait dans un nouveau segment.
-Le premier segment s'appelle _1.extention, puis ensuite _2.extension, ..., _a.extension, ..., _z.extension, _11.extension, ... suivant une [base 36](http://en.wikipedia.org/wiki/Base_36).
+Le premier segment s'appelle \_1.extention, puis ensuite \_2.extension, ..., \_a.extension, ..., \_z.extension, \_11.extension, ... suivant une [base 36](http://en.wikipedia.org/wiki/Base_36).
Lorsque le nombre de segments devient trop important, il devient nécessaire de merger plusieurs segments.
@@ -279,7 +284,7 @@ La donnée est d'abord écrite dans un fichier de log avant d'être indexée en
Ainsi, si une coupure de courant a lieu lorsque des données sont en RAM, au redémarrage, ElasticSearch charge en RAM le contenu du Translog. Ainsi, le nœud se retrouve dans le même état qu'avant.
-ElasticSearch a des [options](http://www.elasticsearch.org/guide/reference/index-modules/Translog.html) pour configurer la fréquence des commits en fonction de l'état du Translog.
+ElasticSearch a des [options pour configurer la fréquence des commits](http://www.elasticsearch.org/guide/reference/index-modules/Translog.html) en fonction de l'état du Translog.
Par défaut le [Translog ne fsync pas à chaque opération mais toute les 5s](https://github.com/elasticsearch/elasticsearch/blob/master/src/main/java/org/elasticsearch/index/gateway/local/LocalIndexShardGateway.java#L75). Mais ceci est [réglable](http://markmail.org/thread/lg2rdevj75fh77sy#query:+page:1+mid:pxda5eqquae2ylfm+state:results).
@@ -311,7 +316,7 @@ Avoir beaucoup de shards implique interroger beaucoup de serveurs à chaque requ
Lorsque l'on indexe une nouvelle donnée dans ElasticSearch, on lui [spécifie un index, un type, et un ID](http://www.elasticsearch.org/guide/reference/api/index_.html).
C'est à partir d'un hash sur le type et sur l'ID que l'on va définir quel shard lui sera attribué (shard = HASH(type, id) MOD nodes ). L'ID étant unique la répartition sur les shards est relativement uniforme.
-Il est également possible de forcer l'emplacement de la donnée sur un nœud en fonction de [plusieurs](http://www.elasticsearch.org/guide/reference/modules/cluster.html) [critère](http://www.elasticsearch.org/guide/reference/api/index_.html#Parents & Children)[s](http://www.elasticsearch.org/guide/reference/api/index_.html#Routing).
+Il est également possible de forcer l'emplacement de la donnée sur un nœud en fonction de [plusieurs](http://www.elasticsearch.org/guide/reference/modules/cluster.html) [critère](http://www.elasticsearch.org/guide/reference/api/index_.html#Parents_&_Children)[s](http://www.elasticsearch.org/guide/reference/api/index_.html#Routing).