SolrCloud setup, quelques notions importantes pour débuter

Solr (prononcé comme le mot solar en anglais) est un moteur de recherche s’appuyant sur la bibliothèque de recherche Lucene, créée par la Fondation Apache et distribuée et conçue sous licence libre. Je vous présente dans cet article quelques notions de la version SolrCloud, annoncée fault tolerant and high availability.

Solr Standalone

Dans sa version standard standalone, on définit un solr_node « master » et n solr_nodes « slave ». A l’aide d’une configuration dans solrconfig.xml, on déclare le master, les slaves et la stratégie de réplication. C’est alors Solr qui prendra en charge lui-même la synchronisation.

Sur le master

<requestHandler name="/replication" class="solr.ReplicationHandler">
  <lst name="master">
    <str name="replicateAfter">optimize</str>
    <str name="backupAfter">optimize</str>
    <str name="confFiles">schema.xml,stopwords.txt,elevate.xml</str>
    <str name="commitReserveDuration">00:00:10</str>
  </lst>
  <int name="maxNumberOfBackups">2</int>
  <lst name="invariants">
    <str name="maxWriteMBPerSec">16</str>
  </lst>
</requestHandler>

Sur les slaves

<requestHandler name="/replication" class="solr.ReplicationHandler">
  <lst name="slave">
    <str name="masterUrl">http://remote_host:port/solr/core_name/replication</str>
    <str name="pollInterval">00:00:20</str>
    <str name="compression">internal</str>
    <str name="httpConnTimeout">5000</str>
    <str name="httpReadTimeout">10000</str>
    <str name="httpBasicAuthUser">username</str>
    <str name="httpBasicAuthPassword">password</str>
  </lst>
</requestHandler>

Plus de détails ici : https://lucene.apache.org/solr/guide/6_6/index-replication.html#IndexReplication-SettingUpaRepeaterwiththeReplicationHandler

Avantages / Inconvénients

  • Solution native simple à mettre en place
  • Les slaves se synchronisent eux-mêmes en réplicant le master.
  • Avec les écritures sur le master et un load-balancer sur les slaves, on obtient une haute-disponibilité en lecture tant qu’il reste au-moins un slave en fonctionnement.
  • En revanche, pas de haute-dispo pour l’écriture.
  • Si un slave down est remis en service, il sera en retard par rapport au master et aux autres slaves. Il faudra alors le mettre à jour manuellement.

SolrCloud

Avec SolrCloud, on change de stratégie pour viser la haute-dispo en lecture et en écriture. SolrCloud est disponible nativement dans une installation standard Solr. Un nouveau composant, Zookeeper, entre en jeu. Nous en parlerons plus en détails dans un autre article.

Quelques concepts à définir

  • cluster : c’est le groupe de serveurs (nodes) sur lequel tourne le service SolrCloud
  • node : un node est un serveur qui héberge le service Solr. Un groupe de nodes composent un cluster.
  • collection : elle représente un index logique dans son intégralité, fourni par le cluster SolrCloud
  • shard : c’est une subdivision de la collection
  • replica : c’est un index physique détenu par un node du cluster

Exemple 1 : SolrCloud avec 3 shards

  • 1 cluster de 3 nodes
  • 1 collection
  • 3 shards (on découpe l’index en 3 parties)
  • 2 replicas (= 2 cores par node)

Dans cette configuration, l’index (la collection) découpé en 3 parties (les shards) sera répliqué 1 fois (2 replicas). En conséquence, on obtient la répartition ci-dessous :

  • solr_node_1
    • shard1_replica1
    • shard3_replica2
  • solr_node_2
    • shard2_replica2
    • shard3_replica1
  • solr_node_3
    • shard1_replica2
    • shard2_replica1

Pour finir d’illustrer la mécanique de répartition de SolrCloud, si on déploie une telle configuration sur un seul solr_node, il détiendra alors les 6 replicas dans 6 cores.

Avantages / Inconvénients

  • Une telle configuration est haute-disponibilité en lecture et en écriture. Si on perd un solr_node, les 2 autres possèdent encore la totalité de l’index (shards 1 2 3).
  • Elle assure aussi une répartition de charge car chaque solr_node a la responsabilité de seulement 1/3 de l’index, en lecture (requêtes) et en écriture (indexation).
  • Il n’y a plus ni master ni slave. Tous les solr_nodes ont le même rôle et c’est Zookeeper qui se charge de gérer le cluster en fonction de l’état des solr_nodes (leader, active, down, recovering…).
  • Complexité de mise en œuvre et de compréhension
  • Nécessite au-moins 3 nodes

Exemple 2 : SolrCloud avec 1 shard

Avec SolrCloud, on peut mettre en place une architecture sur 2 solr_nodes, comme en mode standalone, mais avec les bénéfices de la haute-dispo en écriture.

  • 1 cluster de 2 nodes
  • 1 collection
  • 1 shard (l’index n’est pas découpé)
  • 2 replicas (= 1 core par node)

Dans cette configuration, on obtient la répartition ci-dessous :

  • solr_node_1
    • shard1_replica1
  • solr_node_2
    • shard1_replica2

Avantages / Inconvénients

  • Haute-disponibilité en lecture et en écriture. Si on perd un solr_node, l’autre possède encore la totalité de l’index.
  • Plus « standard » et plus facile à appréhender que la version 3 nodes / 3 shards
  • Il n’y a plus ni master ni slave. Tous les solr_nodes ont le même rôle et c’est Zookeeper qui se charge de gérer le cluster en fonction de l’état des solr_nodes (leader, active, down, recovering…).
  • On peut sécuriser d’avantage cette installation en ajoutant des nodes.
  • Pas de répartition de la charge (un seul leader). L’unique core leader doit gérer la totalité de l’index (requête + indexation).

Conclusion

SolrCloud offre un niveau de service supérieur à un Solr standalone master/slave. Si votre application en dépend fortement, SolrCloud est clairement à privilégier. De plus, si la version 3 nodes / 3 shards vous paraît complexe à mettre en œuvre, vous pouvez vous reposer sur la version avec 1 seul shard, plus simple. Vous pouvez tester SolrCloud facilement avec les images Docker officielles : https://github.com/docker-solr. Je vous parlerai de Zookeeper dans un futur article.

Sources

https://github.com/docker-solr
https://stackoverflow.com/a/31773632/243996
https://lucene.apache.org/solr/guide/8_8/
https://lucene.apache.org/solr/guide/8_8/solrcloud.html

Vérifier l’ouverture d’un flux réseau entre 2 machines

Premier article de ma nouvelle série « Kit de survie en DSI », mes astuces pour s’en sortir au sein d’une DSI quand les équipes collaborent plus ou moins bien.

Deux VMs vous ont été livrées mais il vous semble qu’elles ne sont pas en mesure de dialoguer. Pour en avoir le cœur net, nous allons tester le flux. Prenons un exemple : la machine FRONT1 doit requêter la machine BDD sur le port 3306.

Sur la machine BDD, lancer :

tcpdump -ni any port 3306

Sur la machine FRONT1, exécuter :

telnet BDD 3306

Si le flux est ouvert, vous devriez voir arriver des paquets sur BDD :

12:01:22.514085 IP xxx.xxx.xxx.4.33747 &gt; xxx.xxx.xxx.47.mysql: Flags [S], seq 1162048942, win 14600, options [mss 1460,sackOK,TS val 254014943 ecr 0,nop,wscale 7], length 0
12:01:22.514171 IP xxx.xxx.xxx.47.mysql &gt; xxx.xxx.xxx.4.33747: Flags [S.], seq 3654184421, ack 1162048943, win 14480, options [mss 1460,sackOK,TS val 254020172 ecr 254014943,nop,wscale 7], length 0
12:01:22.514531 IP xxx.xxx.xxx.4.33747 &gt; xxx.xxx.xxx.47.mysql: Flags [.], ack 1, win 115, options [nop,nop,TS val 254014944 ecr 254020172], length 0
12:01:22.523118 IP xxx.xxx.xxx.47.mysql &gt; xxx.xxx.xxx.4.33747: Flags [P.], seq 1:86, ack 1, win 114, options [nop,nop,TS val 254020181 ecr 254014944], length 85
12:01:22.523209 IP xxx.xxx.xxx.47.mysql &gt; xxx.xxx.xxx.4.33747: Flags [F.], seq 86, ack 1, win 114, options [nop,nop,TS val 254020181 ecr 254014944], length 0
12:01:22.523489 IP xxx.xxx.xxx.4.33747 &gt; xxx.xxx.xxx.47.mysql: Flags [.], ack 86, win 115, options [nop,nop,TS val 254014953 ecr 254020181], length 0
12:01:22.523572 IP xxx.xxx.xxx.4.33747 &gt; xxx.xxx.xxx.47.mysql: Flags [F.], seq 1, ack 87, win 115, options [nop,nop,TS val 254014953 ecr 254020181], length 0
12:01:22.523582 IP xxx.xxx.xxx.47.mysql &gt; xxx.xxx.xxx.4.33747: Flags [.], ack 2, win 114, options [nop,nop,TS val 254020182 ecr 254014953], length 0

Si vous ne voyez aucun paquet tcp arriver, contactez votre équipe infrastructure/réseau afin de faire ouvrir le flux.

Warmup : préparez les caches de votre site

Une commande toute simple pour préparer les caches de votre site avant son ouverture en production :

wget -r -np -p -k [URL]

Détail des options

  • -r : suivre récursivement tous les liens de chaque page
  • -np : empêcher le robot de remonter l’arborescence du site
  • -p : télécharger toutes les ressources de la page (css, images, Javascript…)
  • -k : convertir les liens des pages pour utiliser les ressources locales téléchargées

Ajax et XSS : autoriser les requêtes grâce au CORS

Lorsqu’on développe une application RESTful exploitant des webservices disponibles sur un autre domaine, on est rapidement confronté à des questions de sécurité, notamment le cross-site scripting (XSS).

Le problème

Le cas typique dans lequel on rencontre cette problématique est celui d’un site mobile « m.domaine.com » qui récupère des données sur le site desktop « domaine.com ». Toutes les requêtes Ajax partant de « m.domaine.com » vers « domaine.com » seront bloquées par la règle de sécurité Same Origin Policy.

La solution

La solution à cette problématique est le mécanisme du Cross-origin resource sharing (CORS) spécifié par le W3C et utilisable dans Apache et dans la plupart des navigateurs modernes.

La configuration Apache

Le vhost du domaine cible des requêtes (« domaine.com » dans notre exemple) doit spécifier des directives « Access-Control-Allow » :

<VirtualHost *:80> 
    ServerName domaine.com

    Header set Access-Control-Allow-Origin "http://m.domaine.com"
    Header set Access-Control-Allow-Credentials true
    Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
    Header set Access-Control-Allow-Headers "content-type, accept, set-cookie"
</VirtualHost>

Astuce

Grâce à la directive « Access-Control-Allow-Headers », on peut indiquer quels entêtes HTTP seront transmis. En autorisant « set-cookie », on peut récupérer, sur « m.domaine.com », le cookie d’une session ouverte sur « domaine.com ». Ainsi, on réalise facilement un petit SSO maison !

Les requêtes Ajax

Avec jQuery, la requête Ajax devra contenir le flag withCredentials à true dans les paramètres xhrFields (voir également la doc de XMLHttpRequest pour les autres implémentations).

$.ajax({
    url: 'http://domaine.com',
    xhrFields: {
        withCredentials: true
    }
});

Attention à la subtilité !

On trouve très souvent la syntaxe ci-dessous :

Header set Access-Control-Allow-Origin "*"

Cette directive ne fonctionne pas lorsqu’on passe le flag withCredentials à true dans les paramètres xhrFields de la requête Ajax. Dans ce cas, il faut préciser explicitement le domaine autorisé :

Header set Access-Control-Allow-Origin "http://m.domaine.com"

Nemo : rétablir la gestion des archives dans le menu contextuel

Nemo est le gestionnaire de fichier de l’environnement de bureau Cinnamon. Pour information, c’est un fork de Nautilus.

Il m’est arrivé de perdre les actions de gestion des fichiers d’archives dans le menu contextuel (affiché au clic droit) en désinstallant Nautilus. Ces actions sont quand même bien pratiques pour extraire ou créer des archives rapidement. Voici comment les remettre en service.

1 – Vérifiez que vous avez installé les paquets « File Roller » et « Nemo File Roller » :

sudo apt-get install file-roller
sudo apt-get install nemo-fileroller

2 – Rendez-vous dans le dossier « ~/.local/share/nemo/actions/ » :

cd ~/.local/share/nemo/actions/

3 – Créez le fichier « compress.nemo_action », collez-lui le contenu ci-dessous puis sauvegardez-le :

[Nemo Action]
Active=true
Name=Compress...
Comment=compress %N
Exec=file-roller -d %F
Icon-Name=gnome-mime-application-x-compress
Selection=Any
Extensions=any;
Quote=double

4 – Créez le fichier « extracthere.nemo_action », collez-lui le contenu ci-dessous puis sauvegardez-le :

[Nemo Action]
Active=true
Name=Extract here
Comment=Extract here
Exec=file-roller -h %F
Icon-Name=gnome-mime-application-x-compress
Selection=Any
Extensions=zip;7z;ar;cbz;cpio;exe;iso;jar;tar;tar;7z;tar.Z;tar.bz2;tar.gz;tar.lz;tar.lzma;tar.xz;tgz;
Quote=double

5 – Créez le fichier « extractto.nemo_action », collez-lui le contenu ci-dessous puis sauvegardez-le :

[Nemo Action]
Active=true
Name=Extract to...
Comment=Extract to...
Exec=file-roller -f %F
Icon-Name=gnome-mime-application-x-compress
Selection=any
Extensions=zip;7z;ar;cbz;cpio;exe;iso;jar;tar;tar;7z;tar.Z;tar.bz2;tar.gz;tar.lz;tar.lzma;tar.xz;tgz;
Quote=double

C’est fini ! Vous devriez avoir 3 nouvelles actions dans le menu contextuel de Nemo. Si ce n’est pas le cas, redémarrez votre session.

Sources