Intégrer Magento à Cloud Spanner

1. Introduction

424db48d9db91638.png

Intégrer Magento à un backend Cloud Spanner

Magento est une plate-forme d'e-commerce Open Source basée sur PHP très populaire qui stocke les données dans MySQL.

Cet atelier de programmation est une preuve de concept visant à exploiter Cloud Spanner au lieu de MySQL pour le module de catalogue. Il est utile pour toute personne souhaitant intégrer, tester et déployer Magento ou d'autres applications PHP avec Spanner.

Spanner est la base de données entièrement gérée, pensée pour les entreprises, distribuée et cohérente de Google Cloud, qui associe les avantages du modèle de base de données relationnelle à une évolutivité horizontale non relationnelle. Il est conçu pour prendre en charge les déploiements de traitement des transactions en ligne à l'échelle mondiale, la sémantique SQL, l'évolutivité horizontale à disponibilité élevée et la cohérence transactionnelle. Spanner est capable de gérer de grands volumes de données. Son utilisation n'est pas limitée aux applications de grande taille, mais elle permet de standardiser un seul moteur de base de données pour toutes les charges de travail nécessitant un SGBDR. Spanner fait disparaître les temps d'arrêt pour les opérations de maintenance planifiées ou les défaillances de région, il est associé à un contrat de niveau de service garantissant une disponibilité de 99,999 %. Il prend en charge les applications modernes grâce à une haute disponibilité et une évolutivité.

Points abordés

  • Installer Magento sur GCE
  • Configurer l'émulateur Spanner
  • Migrer un schéma MySQL existant vers Spanner à l'aide de HarbourBridge
  • Que devez-vous modifier pour intégrer des applications PHP telles que Magento qui utilisent MySQL pour que le backend de la base de données fonctionne avec Spanner ?

Ce que vous allez faire

Cet atelier de programmation est consacré à l'intégration de Magento à Spanner. Les blocs de code et les instructions de configuration vous sont fournis afin que vous puissiez les copier et les coller, mais ils ne sont pas abordés en détail.

Dans cet atelier de programmation, vous allez commencer à intégrer Magento à Spanner. Vous découvrirez comment :

  • Configurer une instance GCE avec Magento installé
  • Installer l'émulateur Spanner
  • Installez l'outil HarbourBridge pour migrer les données de MySQL vers Spanner.
  • Modifier les collections Magento pour charger le catalogue de produits à partir de Spanner

Prérequis

  • Un projet Google Cloud associé à un compte de facturation
  • La connaissance de la configuration de PHP, Linux et Apache est un plus.
  • L'expérience Magento sera utile, mais ce n'est pas obligatoire.

2. Préparer l'instance GCE

Créer l'instance GCE

Créez une instance Compute Engine dans Google Cloud Platform en suivant ces étapes.

Lorsque vous créez l'instance GCE, définissez le type d'instance sur e2-standard-2 et la taille du disque de démarrage sur 20 Go. Vous pouvez laisser tout tel quel, mais veillez à sélectionner "Allow HTTP traffic" (Autoriser le trafic HTTP) et "Allow HTTPs traffic" (Autoriser le trafic HTTPs), car nous allons utiliser l'interface Web de Magento.

Il en résulte un type de machine e2-standard-2 qui n'est pas une instance à cœur partagé et dispose de 2 processeurs virtuels, 8 Go de RAM et 20 Go d'espace disque.

Le système d’exploitation est Debian 10. La création de l'instance peut prendre une minute ou deux.

Une fois le projet créé, connectez-vous en cliquant sur "SSH" dans la console Cloud:

4bf915ef8d37c942.png

Une nouvelle fenêtre de navigateur s'ouvre et vous êtes redirigé vers un terminal.

Installer le logiciel prérequis

Pour pouvoir exécuter Magento, vous devez installer un logiciel préalable. Plus précisément, vous allez installer PHP, Elastic, MySQL et Apache, comme indiqué ci-dessous.

  1. Installez certains packages requis.
sudo apt update

sudo apt -y install lsb-release apt-transport-https ca-certificates wget git screen composer google-cloud-sdk-spanner-emulator gcc
  1. Installez les modules PHP requis pour Magento.
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg

echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list

sudo apt update

sudo apt -y install php7.4-fpm php7.4-common php7.4-mysql php7.4-gmp php7.4-curl php7.4-intl php7.4-mbstring php7.4-xmlrpc php7.4-gd php7.4-xml php7.4-cli php7.4-zip php7.4-bcmath php7.4-soap php7.4-grpc
  1. Installer Elasticsearch et démarrer le service
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list

sudo apt update && sudo apt -y install elasticsearch

echo "-Xms1g
-Xmx1g" | sudo tee /etc/elasticsearch/jvm.options.d/jvm.options

sudo systemctl start elasticsearch.service
  1. Installer MySQL

Vous installez MySQL pour installer le schéma Magento par défaut. Plus tard, vous migrerez le schéma vers Spanner à l'aide de HarbourBridge.

wget https://dev.mysql.com/get/mysql-apt-config_0.8.13-1_all.deb

sudo dpkg -i mysql-apt-config*

La commande dpkg ci-dessus affiche une invite interactive pour installer le serveur MySQL 5.7. Sélectionnez les options :

  • Serveur et cluster MySQL
  • mysql-5.7
  • OK

a018bfc2ee00bdf5.png 1a126e452ca7312e.png ae39c6f4bbe3be74.png

sudo apt update && sudo apt -y install mysql-server
# You will be prompted to enter a root password
  1. Installer Apache2
sudo apt -y install apache2

sudo a2enmod proxy_fcgi rewrite

Installer et configurer Magento2

Le projet Magento Commerce Cloud inclut un schéma de base de données et des services permettant d'accéder pleinement au site et à la boutique Magento.

Le moyen le plus simple d'installer et d'exécuter cette fonctionnalité consiste à suivre les instructions d'installation de Magento à l'aide de Composer :

  1. Installez la version 2.4.2 de Magento à l'aide de Composer. Magento 2 nécessite la version 1.x de Composer. Des avertissements peuvent s'afficher concernant l'abandon de cette version.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
  1. Définir des autorisations pour les dossiers
cd magento2

find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +

find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +
  1. Configurez l'hôte virtuel Magento en créant /etc/apache2/sites-available/magento.conf avec le contenu ci-dessous.
sudo nano /etc/apache2/sites-available/magento.conf

<VirtualHost *:80>
        ServerAdmin admin@local-magento.com
        DocumentRoot /var/www/html/magento/

        <Directory /var/www/html/magento/>
                Options Indexes FollowSymlinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        <FilesMatch \.php$>
               SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"
        </FilesMatch>

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
  1. Créez les liens symboliques et redémarrez apache2.
cd ~/magento2
sudo ln -s $(pwd) /var/www/html/magento 
sudo ln -s /etc/apache2/sites-available/magento.conf  /etc/apache2/sites-enabled/magento.conf
sudo rm /etc/apache2/sites-enabled/000-default.conf

sudo systemctl restart apache2
  1. Créer la base de données et l'utilisateur pour Magento dans MySQL
export ROOT_PASSWORD="<root password from installation>"
export GCE_INSTANCE_IP="<GCE instance IP>"
mysql -uroot -p$ROOT_PASSWORD -e "create database magento"

bin/magento sampledata:deploy

bin/magento setup:install --base-url=http://$GCE_INSTANCE_IP/ --db-host=localhost \
--db-name=magento --db-user=root --db-password=$ROOT_PASSWORD --admin-firstname=admin \
--admin-lastname=demo --admin-email=good@example.com --admin-user=admin \
--admin-password=magento123 --language=en_US --currency=USD --timezone=America/Chicago \
--use-rewrites=1

sudo chown -R :www-data ~/magento2/. 
  1. Vérifiez votre espace de travail local. Pour vérifier que l'environnement local héberge le serveur, accédez au store à l'aide de l'URL de base que vous avez transmise dans la commande d'installation. Dans cet exemple, vous pouvez accéder à la boutique locale Magento à l'aide des formats d'URL suivants:
  • http://<GCEexternalIP>/
  • http://&lt;GCEexternalIP&gt;/&lt;adminuri&gt;

Vous trouverez l'adresse IP GCEexternalIP dans la console Cloud:

3947f1164e1d5409.png

Pour modifier l'URI du panneau d'administration, utilisez la commande suivante pour le localiser :

php bin/magento info:adminuri
  1. Désactiver le cache de la page complète À des fins de développement, vous pouvez désactiver le cache de la page complète de Magento 2. Vous pourrez ainsi modifier les données dans Spanner et les refléter sur le site Web sans être affecté par les valeurs mises en cache.
php bin/magento cache:disable full_page

Configurer Spanner

Installer l'émulateur Spanner

Cloud SDK fournit un émulateur local en mémoire qui vous permet de développer et de tester vos applications sans frais, sans créer de projet GCP ni de compte de facturation. Étant donné que l'émulateur ne stocke les données que dans la mémoire, tous les états, y compris les données, le schéma et les configurations, sont perdus au redémarrage. L'émulateur propose les mêmes API que le service de production Spanner. Il est destiné au développement et aux tests en local, et non aux déploiements en production.

Veuillez cliquer sur le lien ci-dessous pour en savoir plus sur l'installation, l'utilisation et le déploiement de l'émulateur:

Utiliser l'émulateur Spanner

# Set up a new configuration to use the emulator
gcloud config configurations create emulator
gcloud config set auth/disable_credentials true
gcloud config set project magento
gcloud config set api_endpoint_overrides/spanner http://localhost:9020/

# Start emulator in a screen session
screen -S magento
gcloud emulators spanner start &
gcloud spanner instances create magento-instance --config=emulator-config --description='Magento Instance' --nodes=1

# Detach from screen 
ctrl+a+d

export SPANNER_EMULATOR_HOST=localhost:9010

Migrer Magento MySQL vers Spanner

Avant de nous plonger dans l'intégration de Spanner, nous allons utiliser un outil appelé HarbourBridge pour convertir en Spanner la base de données MySQL créée dans le cadre de l'installation de Magento ci-dessus.

À la base, HarbourBridge fournit un workflow automatisé permettant de charger le contenu d'une base de données MySQL ou PostgreSQL existante dans Spanner. Il ne nécessite aucune configuration, et aucun fichier manifeste ni mappage de données à écrire. Au lieu de cela, il importe la base de données source, crée un schéma Spanner, crée une nouvelle base de données Spanner remplie de données de la base de données source et génère un rapport d'évaluation détaillé. HarbourBridge est destiné à charger des bases de données jusqu'à quelques dizaines de Go à des fins d'évaluation, et non pour les migrations à grande échelle.

HarbourBridge lance la migration en amont vers Spanner à l'aide d'une base de données source MySQL ou PostgreSQL existante pour vous permettre d'être rapidement opérationnel sur Spanner. Il génère un rapport d'évaluation contenant un score global d'adéquation à la migration pour Spanner, une analyse table par table des mappages de types et une liste des fonctionnalités utilisées dans la base de données source qui ne sont pas compatibles avec Spanner.

HarbourBridge peut être utilisé avec l'émulateur Spanner ou directement avec une instance Spanner.

Le README HarbourBridge contient un guide de démarrage rapide détaillé pour utiliser l'outil avec une instance Spanner.

Installer HarbourBridge

Téléchargez l'outil sur votre ordinateur et installez-le. Vous devez installer golang pour que cela fonctionne. L'installation de tous les modules requis sur une nouvelle instance sans Go configuré précédemment peut prendre un certain temps.

# Install golang
cd ~
wget https://golang.org/dl/go1.17.2.linux-amd64.tar.gz
sudo tar -zxvf go1.17.2.linux-amd64.tar.gz -C /usr/local
rm go1.17.2.linux-amd64.tar.gz

echo 'export GOROOT=/usr/local/go' | sudo tee -a /etc/profile
echo 'export PATH=/usr/local/go/bin:$HOME/go/bin:$PATH' | sudo tee -a /etc/profile
source /etc/profile

# Install harbourbridge
git clone https://github.com/cloudspannerecosystem/harbourbridge
cd harbourbridge
go run github.com/cloudspannerecosystem/harbourbridge help

Migrer les données

Exécutez la commande suivante pour migrer la base de données Magento vers Spanner:

mysqldump --user='root' --password=$ROOT_PASSWORD magento | go run github.com/cloudspannerecosystem/harbourbridge -driver=mysqldump -dbname=magento

Configurer l'outil spanner-cli

go install github.com/cloudspannerecosystem/spanner-cli@latest

3. Convertir Magento pour utiliser Spanner

Maintenant que Magento est en cours d'exécution et que l'instance Spanner créée avec la base de données Magento a été migrée, nous allons modifier Magento pour qu'il utilise les données stockées dans Spanner.

Pour convertir l'installation de Magento, procédez comme suit:

  • Clonez le projet magento-spanner-port.
  • Modifier la connexion à Spanner
  • Vérifier que les informations du catalogue sont renseignées à partir de Spanner

Cloner la copie du projet Magento

Clonez le code d'application PHP pour Magento qui contient les modifications apportées aux modules "Catalog", "Washlist" et "Panier" à partir de l'URL Git mentionnée ci-dessous.

cd ~
git clone https://github.com/searceinc/magento-spanner-port

Votre répertoire d'accueil doit se présenter comme suit:

$ ls
go  harbourbridge  magento-spanner-port  magento2

magento2 est le codebase que nous allons modifier, à l'aide du code de magento-spanner-port.

Modifier la connexion à Spanner

Pour vérifier si les modifications de code sont reflétées dans l'UI, nous pouvons suivre les étapes ci-dessous :

Reportez-vous au lien GitHub https://github.com/searceinc/magento-spanner-port pour obtenir un exemple d'implémentation.

  • Exiger la bibliothèque cliente PHP google/cloud-spanner
  • Ajout d'un adaptateur Spanner pour créer une connexion à Spanner.
  • Configurez les informations sur l'instance et le serveur Spanner.
  • Ajoutez SpannerInterface et Spanner dans l'adaptateur pour implémenter la connexion à Spanner.

Tout d'abord, nous devons installer la bibliothèque PHP cloud-spanner à l'aide de Composer. Dans le répertoire magento2, exécutez la commande suivante :

cd ~/magento2
composer require google/cloud-spanner

Nous ajoutons ensuite les fichiers de l'adaptateur Spanner du port magento-spanner-port à notre codebase magento2:

~/magento2$ cp -r ../magento-spanner-port/lib/internal/Magento/Framework/DB/Adapter/Spanner vendor/magento/framework/DB/Adapter/.
~/magento2$ ls -l vendor/magento/framework/DB/Adapter/Spanner
total 16
-rw-r--r-- 1 derekdowney derekdowney 10378 Nov  9 21:03 Spanner.php
-rw-r--r-- 1 derekdowney derekdowney  2948 Nov  9 21:03 SpannerInterface.php

À présent, modifiez le fichier DB/Adapter/Spanner/Spanner.php afin de saisir les informations de connectivité de Spanner pour $project_id, $instance et $database:

$ nano vendor/magento/framework/DB/Adapter/Spanner/Spanner.php

class Spanner implements SpannerInterface
{
    /**
     * Google cloud project id
     * @var string
     */
    private $project_id = 'magento';

    /**
     * Google cloud instance name
     * @var string
     */
    private $instance  = 'magento-instance';

    /**
     * Cloud Spanner database name
     * @var string
     */
    private $database  = 'magento';

    /**
     * Is Cloud Spanner emulator
     * @var bool
     */
    private $is_emulator = true;
...
   /**
    * Set database connection adapter
    *
    * @param \Magento\Framework\DB\Adapter\AdapterInterface $conn
    * @return $this
    * @throws \Magento\Framework\Exception\LocalizedException
    */
   public function setConnection(\Magento\Framework\DB\Adapter\AdapterInterface $conn)
   {
       $this->_conn = $conn;
       $this->_select = $this->_conn->select();
       $this->_isOrdersRendered = false;
       return $this;
   }


   /**
     * Set Cloud Spanner database connection adapter
     *
     * @return void
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    private function setSpannerConnection()
    {
        $this->_spanner_conn = new Spanner();
    }

Modifiez la classe AbstractDB dans Magento pour vous connecter à Spanner à l'aide de la fonction Connection créée dans l'adaptateur Spanner. Ajoutez les lignes vertes après les lignes blanches dans le fichier. Consultez vendor/magento/framework/Data/Collection/AbstractDb.php.

$ nano vendor/magento/framework/Data/Collection/AbstractDb.php
...
use Psr\Log\LoggerInterface as Logger;
use Magento\Framework\DB\Adapter\Spanner\Spanner;
...
    protected $_conn;

    /**
     * Cloud Spanner connection
     *
     * @var \Magento\Framework\DB\Adapter\Spanner\SpannerAdapterInterface
     */
    protected $_spanner_conn;
...
       if ($connection !== null) {
            $this->setConnection($connection);
        }
        $this->setSpannerConnection();
        $this->_logger = $logger;
...
   /**
     * Retrieve connection object
     *
     * @return AdapterInterface
     */
    public function getConnection()
    {
        return $this->_conn;
    }

   /**
     * Retrieve connection object
     *
     * @return SpannerAdapterInterface
     */
    public function getSpannerConnection()
    {
        return $this->_spanner_conn;
    }
...

Une fois la connexion établie, nous devons modifier la méthode de récupération des données de l'adaptateur MySQL vers l'adaptateur Spanner. Modifiez la méthode _loadAttributes dans AbstractCollection pour vous connecter à Spanner et extraire les données de Spanner. Remplacez la ligne rouge par les lignes en vert.

Reportez-vous à /app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php.

$ nano ./vendor/magento/module-eav/Model/Entity/Collection/AbstractCollection.php

use Magento\Framework\Exception\LocalizedException;
use Google\Cloud\Spanner\SpannerClient;

...
               try {
                    if (is_array($selects)) {
                        $select = implode(' UNION ALL ', $selects);
                    } else {
                        $select = $selects;
                    }
                   $values = $this->getConnection()->fetchAll($select);
                   $con = $this->getSpannerConnection();

                    /**
                     * Cloud Spanner follows strict type so cast the columns in common type
                     */
                    $select = $con->addCast($select, "`t_d`.`value`", 'string');
                    $select = $con->addCast($select, "`t_s`.`value`", 'string');
                    $select = $con->addCast($select, "IF(t_s.value_id IS NULL, t_d.value, t_s.value)", 'string');
                    
                    $values = $con->fetchAll($select);

...

Vérifier que les informations du catalogue sont renseignées à partir de Spanner

Et voilà ! Vous pouvez maintenant accéder à votre installation Magento dans le navigateur et vérifier que les données sont en cours de chargement.

Par exemple, voici les entrées du catalogue pour des montres:

13b54ba4482408fc.png

Modifier les données Spanner via le terminal pour l'un des produits et interroger les données via le terminal pour confirmer la modification dans Spanner

$ spanner-cli -pmagento -i magento-instance -d magento
spanner> SELECT * FROM catalog_product_entity_varchar WHERE value LIKE "Aim Analog%";
+----------+--------------+----------+-----------+--------------------+
| value_id | attribute_id | store_id | entity_id | value              |
+----------+--------------+----------+-----------+--------------------+
| 390      | 73           | 0        | 36        | Aim Analog Watch |
+----------+--------------+----------+-----------+--------------------+
1 rows in set (80.711542ms)

spanner> UPDATE catalog_product_entity_varchar SET value = "Aim Analog Spanner" WHERE value_id=390;
Query OK, 1 rows affected (0.19 sec)

spanner> SELECT * FROM catalog_product_entity_varchar WHERE value_id=390;
+----------+--------------+----------+-----------+--------------------+
| value_id | attribute_id | store_id | entity_id | value              |
+----------+--------------+----------+-----------+--------------------+
| 390      | 73           | 0        | 36        | Aim Analog Spanner |
+----------+--------------+----------+-----------+--------------------+
1 rows in set (80.711542ms)

Actualisez maintenant l'écran pour vérifier que le nom de la montre est maintenant "Aim Analog Spanner", comme indiqué dans le terminal Spanner.

63a9c7b065c7051f.png

4. Félicitations

Félicitations, vous avez correctement associé le module de catalogue de Magento à Spanner. Il ne s'agit pas d'une intégration complète, mais vous savez maintenant comment connecter une application PHP telle que Magento à une instance Spanner.

Nettoyer

Une fois la configuration et la validation du POC terminées, vous pouvez supprimer les ressources GCP créées au cours du processus. Cela inclut la machine virtuelle Compute Engine, ainsi qu'une instance Cloud Spanner si vous décidez d'en utiliser une à la place de l'émulateur.

Étape suivante

Il ne s'agit que d'un prototype de modèle de démonstration de faisabilité pour Spanner.

Si vous souhaitez en savoir plus sur l'utilisation de Spanner et sur les technologies que nous avons exploitées dans cet atelier de programmation, voici quelques ressources supplémentaires: