Elasticsearch, suppression de SPOF

Posted on mar. 31 octobre 2017 in Elasticsearch

Note : Pour plus de détails sur Elasticsearch, voyez ma série sur ce thème.

Il était une fois Bitbucket

Contexte

Qu'est-ce ?

L'entreprise pour laquelle je travaille en ce moment utilise Bitbucket pour stocker tout son code source. Il s'agit d'un concurrent de Github, Gitlab ou Gitea que les entreprises peuvent héberger en interne.
Tout le monde connait Github, tout au moins tout informaticien sorti de sa grotte il y a moins de 5 ans. Il est surtout connu pour son instance gratuite qu'utilise le monde de l'open source.
Et, pour mon usage personnel, j'utilise Gitea dont je suis très content.

Le pourquoi

La version 4.6 de Bitbucket imposait l'utilisation d'un serveur Elasticsearch pour fonctionner.
La raison était la recherche de code.
Avant, Bitbucket ne permettait de faire des recherches que sur le nom des projets ou des dépôts git.
A partir de cette version, on pouvait enfin chercher dans le code. On pouvait chercher une fonction, une variable, ce que l'on veut dans tout le code source stocké.
Et c'est à cela que va servir Elasticsearch.

Absurdités

Malheureusement, Atlassian (l'éditeur de ce logiciel) ne sait pas comment fonctionne Elasticsearch, ni quelles sont ses capacités. Cela l'a poussé a divers absurdités :

Prenez "recommander" dans le sens "si le client fait autrement, et que des merdes lui arrivent, même si elles sont causées parce qu'on ne sait pas coder, il se débrouille tout seul, même s'il paye un contrat de support d'1 million d'euros par an."

Je ne parlerais pas du "il faut sécuriser votre elasticsearch avec notre propre plugin qui n'est compatible qu'avec telle version d'elasticsearch. Et sinon, y'a aussi le truc officiel, mais on est pas sûr que ça marchera et de tout façon, on le supporte pas".

Voyons un peu plus les détails.

Architecture du service Bitbucket

Commençons par le début, comment ça marchait Bitbucket, avant.

Sans Elasticsearch

Dans le cadre d'une petite équipe, ou d'une petite entreprise, l'architecture du service Bitbucket, ressemblait à toute autre :

Architecture normal de Bitbucket

Avec Elasticsearch

Avec l'ajout de la dépendance obligatoire Elasticsearch, ça donne ça :

Architecture normal de Bitbucket avec Elasticsearch

Le problème

Le truc, avec mon fournisseur de travail actuel, c'est qu'il est trop gros pour utiliser Bitbucket comme cela.
En effet, plusieurs centaines de développeurs git clonant et git pushant régulièrement tous les jours mettent par terre le service tel quel.

Grosse archi

Bitbucket Datacenter

Ce qu'il s'est passé, c'est que mon $JOB_ACTUEL a travaillé avec Atlassian pour avoir un truc qui scale un peu plus, et Atlassian a sorti une version dite "datacenter". En gros, ça donne ça :

Architecture datacenter de Bitbucket

Et comme il fallait un truc bien robuste pour de la bonne grosse prod, le proxy est redondant en n+2 avec fail-over automatique (c'est bibi qui s'en est occupé de cette partie-là).
Pour la DB, j'imagine que les DBA ont fait la même chose, ainsi que l'équipe d'infra qui nous fourni le stockage.

Bitbucket nouvelle version

Bon, et voilà ce que ça donnerai avec les recommendations d'Atlassian.

Architecture datacenter de Bitbucket avec un nouveau SPOF

Et dans la vraie vie ?

Le problème avec cela, c'est que dans la vraie vie, ça ne tient pas du tout la charge, ou alors à quel prix.
Et surtout, il y a 2 problèmes immédiat :

  • Ca ne scale pas du tout
  • Ca introduit un nouveau SPOF dans notre belle infra critique de prod

Voyons ensemble les contraintes que nous avions.

Les besoins de stockage

Commençons par le stockage. Au moment de l'update, l'infra bitbucket occupait un peu moins d'1To de disque. Autant dire qu'1To réparti dans quelques milliers de dépôt git, c'est pas petit !

Notre équipe qui s'occupe de Bitbucket a procédé à quelques tests, pour savoir ce que cela prendrait comme disque une fois répliqué dans elasticsearch. Et elle a trouvé qu'il y avait un rapport 1.33 entre l'espace occupé brut et l'espace disque dont aura besoin elasticsearch.

Avec un peu de marge, on se retrouve avec un besoin immédiat d'1,5To. Avec une courbe de croissance estimée à environ +60Go/mois

Les contraintes de notre équipe d'infra

Notre équipe d'infra a elle aussi quelques contraintes, avec ses +8000 serveurs gérés :

  • Elle ne fourni que des VM, pas de machine bare-metal.
  • Chaque serveur ne pourra avoir que 500Go de disque attaché, au maximum
  • Le moins on utilise d'espace disque, le mieux c'est

D'un autre côté, quelles sont les possibilités d'Elasticsearch ?

Comme déjà vu ensemble, Elasticsearch est hautement distribué et scalable.
Et il a une fonctionnalité qui nous intéresse aussi, c'est son utilisation en tant que "proxy", avec une configuration "no-data,no-master".

La solution

L'archi actuelle

Architecture datacenter de Bitbucket avec elasticsearch

L'idée principale est de mettre un noeud elasticsearch "proxy" en local sur chaque noeud bitbucket. Ainsi Bitbucket se connecte au cluster elasticsearch sur l'URI http://localhost:9200/.

Avec cette configuration, la perte d'un noeud elasticsearch ou bitbucket, quelqu'il soit n'entraine pas de perturbation.

Ajouté à cela qu'après discussions avec Atlassian, nous avons pu avoir la possitilité de changer le nombre de shard et de replica, via des variables de configuration non-documentées.

Quelques chiffres clefs

  • Nous avons actuellement un cluster de 15 noeuds. Chaque noeud a 400Go de disque, 4vCPUs et 16Go de RAM.
  • Nous avons aujourd'hui de configuré 15 shards et 1 replica
  • 3To de disque utilisés sur les 6To de disponible
  • >160 milliards de documents stockés
  • Temps de réponse moyen d'Elasticsearch <50ms
  • Pas de SPOF : en test, on a perdu 2 noeuds sur les 15 sans aucun impact (pas de perte de data, pas d'interruption de service)
  • Possibilité de scaler pour suivre l'utilisation du service

Note : si c'était à refaire (et c'est ce qui sera fait prochainement), et que nous avions les ressources matérielles que nous voulions, nous aurions pris 45 shards et 2 replica répartis sur 20 VMs. Cela nous aurait permis de mieux scaler et sur plus longtemps. Dans notre cas, nous avons été surpris par un taux de croissance plus important que ce que nous prévoyions qui nous amène à changer nos plans dans peu de temps.