Integra Magento en Cloud Spanner

Integra Magento en Cloud Spanner

Acerca de este codelab

subjectÚltima actualización: ene 5, 2022
account_circleEscrito por Derek Downey

1. Introducción

424db48d9db91638.png

Integra Magento en un backend de Cloud Spanner

Magento es una plataforma de comercio electrónico de código abierto basada en PHP muy popular que almacena datos en MySQL.

Este codelab es una prueba de concepto que permite aprovechar Cloud Spanner en lugar de MySQL para el módulo del catálogo. Esto es útil para cualquier persona interesada en integrar, probar e implementar Magento, o bien otras aplicaciones PHP, con Spanner.

Spanner es la base de datos completamente administrada, de nivel empresarial, distribuida y coherente de Google Cloud que combina los beneficios del modelo de base de datos relacional con escalabilidad horizontal no relacional. Está diseñada para admitir implementaciones globales de procesamiento de transacciones en línea, semántica de SQL, escalamiento horizontal con alta disponibilidad y coherencia transaccional. Spanner es capaz de manejar grandes volúmenes de datos. Su uso no se limita a aplicaciones de gran tamaño, pero permite la estandarización de un único motor de base de datos para todas las cargas de trabajo que requieran RDBMS. Spanner proporciona un tiempo de inactividad cero para el mantenimiento planificado o las fallas de la región, con un ANS de disponibilidad del 99.999%. Admite aplicaciones modernas, ya que proporciona alta disponibilidad y escalabilidad.

Qué aprenderás

  • Cómo instalar Magento en GCE
  • Cómo configurar el emulador de Spanner
  • Cómo migrar un esquema de MySQL existente a Spanner con HarbourBridge
  • Qué debes cambiar para integrar aplicaciones de PHP, como Magento, que usan MySQL para que el backend de la base de datos funcione con Spanner

Qué compilarás

Este codelab se enfoca en integrar Magento a Spanner. Se proporcionan bloques de código y las instrucciones de configuración para que copies y pegues, pero no se analizan en detalle.

En este codelab, comenzarás a integrar Magento en Spanner. Harás lo siguiente:

Requisitos

  • Un proyecto de Google Cloud que esté conectado a una cuenta de facturación
  • Además, tienes conocimientos de configuración de PHP, Linux y Apache.
  • La experiencia de Magento será útil, pero no es obligatoria.

2. Prepara la instancia de GCE

Crea la instancia de GCE

Sigue los pasos que se mencionan aquí para crear una instancia de Compute Engine en Google Cloud Platform.

Cuando crees la instancia de GCE, cambia el tipo de instancia a e2-standard-2 y el tamaño del disco de arranque a 20 GB. Puedes dejar todo con la configuración predeterminada, pero asegúrate de seleccionar “Permitir tráfico HTTP” y "Permitir tráfico HTTP", ya que aprovecharemos la interfaz web de Magento.

Esto da como resultado un tipo de máquina e2-standard-2 que no es una instancia de núcleo compartido y tiene 2 CPU virtuales, 8 GB de RAM y 20 GB de espacio en el disco.

El sistema operativo es Debian 10. La creación de la instancia puede tardar uno o dos minutos.

Una vez creada, haz clic en “SSH” para acceder. En la consola de Cloud:

4bf915ef8d37c942.png

Se abrirá una nueva ventana del navegador y se te dirigirá a una terminal.

Instala el software de requisitos previos

Para poder ejecutar Magento, deberá instalarse el software de requisitos previos. En particular, instalarás PHP, Elastic, MySQL y Apache como se detalla a continuación.

  1. Instala algunos paquetes obligatorios.
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. Instala los módulos de PHP necesarios para 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. Instala Elasticsearch y, luego, inicia el servicio
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. Instala MySQL

Instala MySQL para instalar el esquema de Magento predeterminado. Más adelante, migrarás el esquema a Spanner mediante HarbourBridge.

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

sudo dpkg -i mysql-apt-config*

El comando dpkg anterior mostrará un indicador interactivo para instalar el servidor MySQL 5.7. Selecciona las siguientes opciones:

  • MySQL Server y Clúster
  • mysql-5.7
  • Aceptar

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. Instala Apache2
sudo apt -y install apache2

sudo a2enmod proxy_fcgi rewrite

Cómo instalar y configurar Magento2

El proyecto de Magento Commerce Cloud incluye un esquema de base de datos y servicios para acceder completamente al sitio y a la tienda de Magento.

La manera más sencilla de instalarlo y ejecutarlo es seguir las instrucciones de Magento para instalarlo con Composer:

  1. Instala la versión 2.4.2 de Magento con el compositor. Magento 2 requiere la versión 1.x del compositor. Es posible que veas algunas advertencias que indican que esta versión es obsoleta.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
  1. Configura los permisos de las carpetas
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. Para configurar el host virtual de Magento, crea /etc/apache2/sites-available/magento.conf con el contenido que se indica a continuación.
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. Crea los symlinks y reinicia 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. Crea la base de datos y el usuario para Magento en 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. Verifica tu lugar de trabajo local. Para verificar que el entorno local aloja el servidor, accede al almacén con la URL base que pasaste en el comando de instalación. Para este ejemplo, puede acceder a la tienda local de Magento utilizando los siguientes formatos de URL:
  • http://&lt;GCEexternalIP&gt;/
  • http://&lt;GCEexternalIP&gt;/&lt;adminuri&gt;

Se puede encontrar GCEexternalIP en la consola de Cloud:

3947f1164e1d5409.png

Si quieres cambiar el URI del panel de administración, usa este comando para localizarlo:

php bin/magento info:adminuri
  1. Inhabilitar caché de página completa Para propósitos de desarrollo, puedes inhabilitar la caché de página completa de Magento2. Esto te permitirá modificar los datos en Spanner y hacer que se reflejen en el sitio web sin que los valores almacenados en caché se vean afectados.
php bin/magento cache:disable full_page

Configura Spanner

Instala el emulador de Spanner

El SDK de Cloud proporciona un emulador local en la memoria que puedes usar para desarrollar y probar tus aplicaciones de forma gratuita sin crear un proyecto de GCP ni una cuenta de facturación. Como el emulador almacena datos solo en la memoria, todos los estados, incluidos los datos, el esquema y los parámetros de configuración, se pierden durante el reinicio. El emulador ofrece las mismas APIs que el servicio de producción de Spanner y está diseñado para el desarrollo y las pruebas locales, no para implementaciones de producción.

Usa el siguiente vínculo para obtener más información sobre la instalación, el uso y la implementación del emulador:

Usa el emulador de 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

Migra MySQL de Magento a Spanner

Antes de profundizar en la integración de Spanner, usaremos una herramienta llamada HarbourBridge para convertir la base de datos de MySQL que se creó como parte de la instalación de Magento que mencionamos anteriormente a Spanner.

En esencia, HarbourBridge proporciona un flujo de trabajo automatizado para cargar el contenido de una base de datos existente de MySQL o PostgreSQL en Spanner. No requiere configuración, no se requieren manifiestos ni mapas de datos para escribir. En su lugar, importa la base de datos de origen, compila un esquema de Spanner, crea una nueva base de datos de Spanner propagada con datos de la base de datos de origen y genera un informe de evaluación detallado. HarbourBridge está diseñado para cargar bases de datos de hasta unas decenas de GB con fines de evaluación, no para migraciones a gran escala.

HarbourBridge inicia la migración en etapa temprana a Spanner mediante el uso de una base de datos de origen MySQL o PostgreSQL existente para que comiences a usar Spanner rápidamente. Genera un informe de evaluación con una puntuación general de aptitud para la migración para Spanner, un análisis tabla por tabla de las asignaciones de tipos y una lista de los atributos usados en la base de datos de origen que no son compatibles con Spanner.

HarbourBridge se puede usar con el emulador de Spanner o directamente con una instancia de Spanner.

El archivo README de HarbourBridge contiene una guía de inicio rápido paso a paso para usar la herramienta con una instancia de Spanner.

Instala HarbourBridge

Descarga la herramienta en tu máquina y, luego, instálala. Es necesario instalar golang para que funcione. La instalación de todos los módulos requeridos en una instancia nueva sin que Go esté configurado previamente puede llevar un tiempo.

# 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

Migra los datos

Usa el siguiente comando para migrar la base de datos de Magento a Spanner:

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

Cómo configurar la herramienta Spanner-cli

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

3. Convierte Magento para que funcione con Spanner

Ahora que tenemos Magento en ejecución y la instancia de Spanner creada con la base de datos de Magento migró, trabajaremos en la modificación de Magento para trabajar con los datos almacenados en Spanner.

Para convertir la instalación de Magento, se realizarán los siguientes pasos:

  • Clona el proyecto magento-spanner-port
  • Cambia la conexión a Spanner
  • Valida que los detalles del catálogo se propaguen desde Spanner

Clona la bifurcación del proyecto de Magento

Clona el código de la aplicación PHP para Magento que contiene las modificaciones de los módulos Catalog, Wishlist y Cart de la URL de Git que se menciona a continuación.

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

El directorio principal debería ser similar al siguiente:

$ ls
go  harbourbridge  magento-spanner-port  magento2

Donde magento2 es la base de código que modificaremos, con el código de magento-spanner-port.

Cambia la conexión a Spanner

Para comprobar si las modificaciones del código se reflejan en la IU, podemos seguir los pasos que se indican a continuación:

Consulta el vínculo de GitHub https://github.com/searceinc/magento-spanner-port para ver una implementación de muestra.

  • Solicita la biblioteca cliente de PHP google/cloud-spanner
  • Agregar el adaptador de Spanner para crear una conexión a Spanner
  • Configurar la instancia y la información del servidor de Spanner
  • Agregar SpannerInterface y Spanner al adaptador para implementar la conexión a Spanner

Primero, debes instalar la biblioteca PHP de Cloud Spanner con el compositor. En el directorio magento2, ejecuta este comando:

cd ~/magento2
composer require google/cloud-spanner

Luego, agregamos los archivos del adaptador de Spanner desde magento-spanner-port a nuestra base de código 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

A continuación, modifica el archivo DB/Adapter/Spanner/Spanner.php para ingresar la información de conectividad de Spanner para $project_id, $instance y $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();
    }

Modifica la clase AbstractDB en Magento para conectarte a Spanner mediante la función de conexión recién creada en el adaptador de Spanner. Agrega las líneas verdes después de las líneas blancas en el archivo. Consulta 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;
    }
...

Una vez que se establece la conexión, debemos modificar el método de recuperación de datos del adaptador de MySQL al adaptador de Spanner . Modifica el método _loadAttributes en AbstractCollection para conectarte a Spanner y recuperar los datos de este servicio. Reemplaza la línea roja por las líneas en verde.

Consulta /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);

...

Valida que los detalles del catálogo se propaguen desde Spanner

Eso es todo. A continuación, vaya a la instalación de Magento en el navegador y compruebe que los datos se estén cargando.

Por ejemplo, estas son las entradas del catálogo para relojes:

13b54ba4482408fc.png

Modificar los datos de Spanner a través de la terminal de uno de los productos y consultar los datos a través de la terminal para confirmar la modificación en 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)

Ahora, vuelve a cargar la pantalla para confirmar que el nombre del reloj haya cambiado a "Aim Analog Spanner". según las actualizaciones en la terminal de Spanner.

63a9c7b065c7051f.png

4. Felicitaciones

Felicitaciones. Conectaste correctamente el módulo de catálogo de Magento para trabajar con Spanner. No es una integración completa, pero ahora conoces los elementos para conectar una aplicación de PHP como Magento a una instancia de Spanner.

Realice una limpieza

Una vez completada la configuración y validación del PDC, puedes borrar los recursos de GCP creados durante el proceso. Esto incluiría la máquina virtual de Compute Engine, así como una instancia de Cloud Spanner si decides usar una en lugar del emulador.

Próximos pasos

Este es solo un prototipo de modelo para un POC de Spanner.

Si quieres obtener más información para trabajar con Spanner y las tecnologías que aprovechamos en este codelab, estos son algunos recursos adicionales: