Logo de Béjean Développement

Installer Elasticsearch pour Magento 2

Objectif

Pour fonctionner correctement, Magento 2 a besoin d'un moteur de recherche performant. Auparavant Magento 2 utilisait MySQL pour gérer l'indexation des produits, la recherche... mais ce n'était pas assez performant. C'est pourquoi, Magento 2 utilise Elasticsearch ou OpenSearch depuis quelques versions. Dans ce tutoriel, nous allons voir comment installer Elasticsearch 7.17.11 sur Ubuntu 22.04 LTS.

Elasticsearch sera installé en tant que simple nœud mais il est possible de déployer un cluster si vous souhaitez avoir une haute disponibilité.

Installation des composants indispensables

Pour fonctionner Elasticsearch a besoin de s'exécuter sur une machine virtuelle Java (JVM). Par conséquent, nous devons installer le paquet default-jre ainsi que du paquet default-jdk. Ce dernier est nécessaire pour quelques fonctionnalités spécifiques :

apt install default-jre

Vérifier l'installation en lançant la commande : java --version, le résultat doit être :

openjdk 11.0.19 2023-04-18
OpenJDK Runtime Environment (build 11.0.19+7-post-Ubuntu-0ubuntu122.04.1)
OpenJDK 64-Bit Server VM (build 11.0.19+7-post-Ubuntu-0ubuntu122.04.1, mixed mode, sharing)

Puis, installer le JDK :

apt install default-jdk

Vérifier en lançant la commande : javac --version, le résultat doit être :

javac 11.0.19

Installation de Elasticsearch

Une fois les 2 paquets installés, nous pouvons installer Elasticsearch. Pour cela, il faut ajouter la clé GPG d'Elasticsearch puis ajouter le dépôt :

apt-get install gnupg2 apt-transport-https
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | tee -a /etc/apt/sources.list.d/elastic-7.x.list
apt-get update && apt-get install elasticsearch=7.17.11

J'ai précisé la version d'Elasticsearch car le module de recherche de Magento 2.4.6-p1 ne fonctionne avec la dernière version 7.17.11 d'Elasticsearch. Attention, même si, il est indiqué, par Adobe, que Magento 2.4.6-p1 fonctionne sous Elasticsearch 8.5. Vous rencontrerez des problèmes d'installation avec composer, voir le ticket sur le Github de Magento.

Configuration d'Elasticsearch

Nous allons désormais configurer notre machine virtuelle ainsi qu'Elasticsearch. Commençons par éditer le fichier de configuration d'Elasticsearch :

nano /etc/elasticsearch/elasticsearch.yml

Vous trouverez, ci-dessous, les modifications que j'ai apportées au fichier de configuration :

cluster.name: es7
node.name: es7-1
bootstrap.memory_lock: true
network.host: _eth0_
http.port: 9200
discovery.seed_hosts: ["es7-1"]
cluster.initial_master_nodes: ["es7-1"]

Voici le descriptif des directives présentes dans le fichier de configuration :

  • cluster.name : ce paramètre est également libre, il correspond au nom du cluster. Pour créer un cluster, il faut indiquer un nom de cluster.
  • node.name : ce paramètre est libre, il correspond au nom du nœud. J'ai ajouté un -1 pour préciser que ce serveur correspond au premier nœud Elasticsearch. Cela sera utile si je souhaite créer un cluster.
  • bootstrap.memory_lock : ce paramètre permet de verrouiller en mémoire la partie allouée à la machine virtuelle Java (JVM) au démarrage d'Elastic
  • network.host : il est important de configurer ce paramètre dès l'installation car, par défaut, Elasticsearch écoute seulement sur l'adresse 127.0.0.1. Pour ma part, j'ai choisi d'écouter l'interface réseau. Si vous souhaitez plus d'informations sur la configuration, je vous invite à consulter la documentation, lien vers la documentation.
  • http.port : Ce paramètre permet de modifier le port d'écoute d'Elasticsearch.
  • discovery.seed_hosts : ce paramètre est un tableau d'adresses IP ou de noms d'hôtes. Il est nécessaire pour rejoindre un cluster, car chaque nœud doit connaître tous les nœuds d'un même cluster.
  • cluster.initial_master_nodes : ce dernier paramètre est un tableau qui permet de définir le ou les nœuds master d'un cluster, lien vers la documentation.

Avant d'enregistrer et de fermer le fichier, n'oubliez pas de modifier, si vous le souhaitez, l'URL es7-1 par l'URL de votre serveur Elasticsearch.

Continuons, avec la modification du fichier /etc/security/limits.conf :

nano /etc/security/limits.conf

Ajouter à la fin du fichier les paramètres suivants :

# Source: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/setup-configuration-memory.html#bootstrap-memory_lock
# allow user 'elasticsearch' mlockall
elasticsearch soft memlock 2G
elasticsearch hard memlock 2G
######
# Source : https://www.elastic.co/guide/en/elasticsearch/reference/7.17/setting-system-settings.html#limits.conf
elasticsearch  -  nofile  65535

Voici le descriptif des directives présentes dans le fichier :

  • elasticsearch soft memlock 2G : ce paramètre définit la limite souple (soft limit) pour le verrouillage en mémoire (memlock) pour le processus Elasticsearch. Le verrouillage en mémoire est utilisé pour empêcher le système d'exploitation de déplacer les pages mémoire d'Elasticsearch vers la mémoire virtuelle (swap). En définissant cette limite à "unlimited" (illimité), le processus Elasticsearch est autorisé à verrouiller autant de mémoire que nécessaire. Cela garantit que les performances d'Elasticsearch ne sont pas affectées par les opérations de swapping.
  • elasticsearch hard memlock 2G : ce paramètre définit la limite stricte (hard limit) pour le verrouillage en mémoire (memlock) pour le processus Elasticsearch. La limite stricte est une limite absolue qui ne peut être dépassée par aucun utilisateur ou processus, sauf si des privilèges spéciaux sont accordés. En définissant cette limite à "unlimited" (illimité), le processus Elasticsearch est autorisé à verrouiller autant de mémoire que nécessaire, même si cela dépasse les limites de ressources globales définies pour le système.
  • elasticsearch - nofile 65535 : ce paramètre définit le nombre maximum de descripteurs de fichiers (file descriptors) pour le processus Elasticsearch. Les descripteurs de fichiers sont utilisés pour représenter les fichiers et les connexions réseau ouvertes par un processus. En définissant cette limite à 65535, Elasticsearch est autorisé à ouvrir jusqu'à 65535 descripteurs de fichiers simultanément. Cela peut être nécessaire pour gérer un grand nombre de connexions entrantes ou de fichiers ouverts par Elasticsearch.

Ayant installé Elasticsearch sur une machine virtuelle avec 4Go de RAM, j'ai limité les valeurs à 2Go. Si vous avez plus de RAM, vous pouvez augmenter cette valeur.

Puis, il faut créer le fichier /etc/elasticsearch/jvm.options.d/jvm.options. Vous aurez surement besoin de créer le dossier /etc/elasticsearch/jvm.options.d, avant de créer le fichier, car sur une installation Ubuntu 22.04 LTS de base, le dossier n'existe pas. Ce fichier permet de configurer la mémoire allouée à Elasticsearch :

# Source: https://www.elastic.co/guide/en/elasticsearch/reference/7.11/advanced-configuration.html#set-jvm-heap-size
-Xms2g
-Xmx2g

Ces 2 paramètres dépendent de la quantité de mémoire présente sur votre serveur. Pour ma part, j'ai choisi de limiter la mémoire allouée à Elasticsearch à 2Go car la machine virtuelle dispose de 4Go de RAM. Les valeurs ne doivent pas dépasser 50% du total de la mémoire de votre serveur.

Une fois enregistré, je vous invite à vérifier que le fichier est bien créé pour l'utilisateur root avec les droits 0644.

Pour terminer, nous allons créer le fichier /etc/systemd/system/elasticsearch.service.d/override.conf qui nous permettra de surcharger les paramètres de configuration du service Elasticsearch :

# Source: https://www.elastic.co/guide/en/elasticsearch/reference/7.11/setting-system-settings.html#systemd
[Service]
LimitMEMLOCK=infinity

Ce paramètre est une option de configuration utilisée pour définir la limite de verrouillage en mémoire pour le service Elasticsearch géré par systemd. Ceci permet d'éviter de déplacer les pages de mémoire vers la mémoire virtuelle (swap). Comme pour les autres paramètres, j'ai indiqué infinity pour la limite. Dès lors que ce fichier est modifié, il faut relancer le service systemctl :

systemctl daemon-reload

Nous allons terminer par l'activation du service Elasticsearch afin qu'il démarre automatiquement à chaque fois que le système redémarre. En même temps, nous avons en profiter pour lancer le service Elasticsearch :

systemctl enable elasticsearch.service && systemctl start elasticsearch.service

Vérifier si Elasticsearch est actif en lançant cette commande : systemctl status elasticsearch.service.

Si besoin, vous pouvez relancer le service avec la commande : systemctl restart elasticsearch.service.

Résultat

Pour contrôler que le serveur fonctionne correctement, je vous invite à lancer la commande : curl http://es7-1:9200, en remplaçant es7-1 par l'URL de votre serveur.

Vous devriez avoir le résultat :

{
    "name" : "es7-1",
    "cluster_name" : "es7",
    "cluster_uuid" : "_na_",
    "version" : {
        "number" : "7.17.11",
        "build_flavor" : "default",
        "build_type" : "deb",
        "build_hash" : "...",
        "build_date" : "2023-06-23T05:33:12.261262042Z",
        "build_snapshot" : false,
        "lucene_version" : "8.11.1",
        "minimum_wire_compatibility_version" : "6.8.0",
        "minimum_index_compatibility_version" : "6.0.0-beta1"
    },
    "tagline" : "You Know, for Search"
}

Playbook Ansible

Pour automatiser l'installation d'Elasticsearch, je vous propose un playbook Ansible très simple permettant d'installer la version 7.17.11 d'Elasticsearch pour Ubuntu 22.04 LTS. Ce playbook est disponible sur le dépôt GitLab de Froggit, lien vers le dépôt Froggit du playbook.

Le playbook est composé de 4 fichiers, un premier fichier nommé 00_base.yaml où vous pourrez modifier la machine cible, le nom du cluster, le nom du nœud... Les autres fichiers contiennent l'ensemble des actions à effectuer pour installer Elasticsearch. Ce sont les mêmes actions que nous avons vues précédemment.

- name: "Install Elastic 7"
  hosts: es7-1
  tasks:
      - name: Install components and prerequisites
        include_tasks: 01_install-components.yaml

      - name: Install Elastic
        include_tasks: 02_install-elastic.yaml

      - name: Update Elasticsearch configuration file
        lineinfile:
            path: /etc/elasticsearch/elasticsearch.yml
            regexp: "{{ item.regexp }}"
            line: "{{ item.line }}"
        with_items:
            - { regexp: '^cluster.name:', line: 'cluster.name: es7' }
            - { regexp: '^node.name:', line: 'node.name: es7-1' }
            - { regexp: '^bootstrap.memory_lock:', line: 'bootstrap.memory_lock: true' }
            - { regexp: '^network.host:', line: 'network.host: _eth0_' }
            - { regexp: '^http.port:', line: 'http.port: 9200' }
            - { regexp: '^discovery.seed_hosts:', line: 'discovery.seed_hosts: ["es7-1"]' }
            - { regexp: '^cluster.initial_master_nodes:', line: 'cluster.initial_master_nodes: ["es7-1"]' }

      - name: Configure Elastic
        include_tasks: 03_configure-elastic.yaml

Fichier 01_install-components.yaml

- name: Install JRE
  apt:
      name: default-jre
      state: present

- name: Install JDK
  apt:
      name: default-jdk
      state: present

- name: Install gnupg2
  apt:
      name: gnupg2
      state: present

Fichier 02_install-elastic.yaml

- name: Add Elasticsearch repository key
  apt_key:
    url: "https://artifacts.elastic.co/GPG-KEY-elasticsearch"
    id: "46095ACC8548582C1A2699A9D27D666CD88E42B4"
    state: present

- name: Add elasticsearch repository
  apt_repository:
    repo: "deb https://artifacts.elastic.co/packages/7.x/apt stable main"
    state: present

- name: Update APT
  apt:
    update_cache: yes

- name: Install Elastic
  apt:
    name: elasticsearch=7.17.11

Fichier 03_configure-elastic.yaml

- name: Update Security limits
  blockinfile:
    path: /etc/security/limits.conf
    block: |
      # Source: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/setup-configuration-memory.html#bootstrap-memory_lock
      # allow user 'elasticsearch' mlockall
      elasticsearch soft memlock unlimited
      elasticsearch hard memlock unlimited
      ######
      # Source : https://www.elastic.co/guide/en/elasticsearch/reference/7.17/setting-system-settings.html#limits.conf
      elasticsearch  -  nofile  65535

- name: Check if JVM options file exists
  stat:
    path: /etc/elasticsearch/jvm.options.d/jvm.options
  register: jvm_options_file

- name: Create JVM options file
  file:
    path: /etc/elasticsearch/jvm.options.d/jvm.options
    state: touch
    owner: root
    group: root
    mode: '0644'
    force: yes
  when: not jvm_options_file.stat.exists

- name: Update JVM options file
  blockinfile:
    path: /etc/elasticsearch/jvm.options.d/jvm.options
    block: |
      # Source: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/advanced-configuration.html#set-jvm-heap-size
      -Xms2g
      -Xmx2g

- name: Check if Elasticsearch service override folder exists
  stat:
    path: /etc/systemd/system/elasticsearch.service.d
  register: elastic_service_override_folder

- name: Create Elasticsearch service override folder
  file:
    path: /etc/systemd/system/elasticsearch.service.d
    state: directory
  when: not elastic_service_override_folder.stat.exists

- name: Check if Elasticsearch service override file exists
  stat:
    path: /etc/systemd/system/elasticsearch.service.d/override.conf
  register: elastic_service_override_file

- name: Create Elasticsearch service override file
  file:
    path: /etc/systemd/system/elasticsearch.service.d/override.conf
    state: touch
    owner: root
    group: root
    mode: '0644'
    force: yes
  when: not elastic_service_override_file.stat.exists

- name: Update Elasticsearch service override file
  blockinfile:
    path: /etc/systemd/system/elasticsearch.service.d/override.conf
    block: |
      # Source: https://www.elastic.co/guide/en/elasticsearch/reference/7.11/setting-system-settings.html#systemd
      [Service]
      LimitMEMLOCK=infinity

- name: Reload daemon
  systemd:
    daemon_reload: yes

- name: Enable Elasticsearch service
  systemd:
    name: elasticsearch
    enabled: yes

- name: Start Elasticsearch service
  systemd:
    name: elasticsearch
    state: restarted