1. Introducción

Integra Magento con 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 para aprovechar Cloud Spanner en lugar de MySQL para el módulo de catálogo. Es útil para cualquier persona interesada en integrar, probar e implementar Magento o cualquier otra aplicación de PHP con Spanner.
Spanner es la base de datos uniforme, distribuida y completamente administrada 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 de procesamiento de transacciones en línea globales, semántica de SQL, escalamiento horizontal con alta disponibilidad y coherencia transaccional. Spanner puede controlar grandes volúmenes de datos. Su uso no se limita a aplicaciones de gran tamaño, sino que permite la estandarización de un solo motor de base de datos para todas las cargas de trabajo que requieren RDBMS. Spanner proporciona un tiempo de inactividad cero para el mantenimiento planificado o los fallos regionales, 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 la integración de Magento con Spanner. Se proporcionan bloques de código y las instrucciones de configuración para que los copies y pegues, pero no se analizan en detalle.
En este codelab, comenzarás a integrar Magento con Spanner. Harás lo siguiente:
- Configurar una instancia de GCE con Magento instalado
- Instalar el emulador de Spanner
- Instalar la herramienta HarbourBridge para la migración de datos de MySQL a Spanner
- Modificar las colecciones de Magento para cargar el catálogo de productos desde Spanner
Requisitos
- Un proyecto de Google Cloud conectado a una cuenta de facturación
- Tener conocimientos de PHP, Linux y la configuración de Apache es una ventaja.
- Tener experiencia en Magento será útil, pero no es obligatorio.
2. Prepara la instancia de GCE
Crea la instancia de GCE
Para crear una instancia de Compute Engine en Google Cloud Platform, sigue los pasos que se mencionan aquí.
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 como predeterminado, pero asegúrate de seleccionar “Permitir tráfico HTTP” y “Permitir tráfico HTTPS”, 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 disco.
El sistema operativo es Debian 10. La creación de la instancia puede tardar uno o dos minutos.
Una vez que se cree, haz clic en “SSH” en la consola de Cloud para acceder:

Se abrirá una nueva ventana del navegador y te colocará en una terminal.
Instala el software de requisitos previos
Magento necesitará que se instale algún software de requisitos previos antes de que podamos ejecutarlo. En particular, instalarás PHP, Elastic, MySQL y Apache como se detalla a continuación.
- 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
- 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
- Instala Elasticsearch e 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
- Instala MySQL.
Instalarás MySQL para instalar el esquema predeterminado de Magento. Más adelante, migrarás el esquema a Spanner con 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 mensaje interactivo para instalar el servidor MySQL 5.7. Selecciona las opciones:
- Servidor y clúster de MySQL
- mysql-5.7
- Aceptar

sudo apt update && sudo apt -y install mysql-server # You will be prompted to enter a root password
- Instala Apache2.
sudo apt -y install apache2 sudo a2enmod proxy_fcgi rewrite
Instala y configura Magento2
El proyecto de Magento Commerce Cloud incluye un esquema de base de datos y servicios para acceder por completo al sitio y la tienda de Magento.
La forma más sencilla de instalarlo y ejecutarlo es seguir las instrucciones de Magento para instalarlo con Composer:
- Instala Magento versión 2.4.2 con Composer. Magento 2 requiere la versión 1.x de Composer. Es posible que veas algunas advertencias sobre la baja de compatibilidad con esta versión.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
- 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 {} +
- Configura el host virtual de Magento creando /etc/apache2/sites-available/magento.conf con el contenido que se muestra 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>
- Crea los vínculos simbólicos 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
- 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/.
- Verifica tu espacio de trabajo local. Para verificar que el entorno local aloje el servidor, accede a la tienda con la URL base que pasaste en el comando de instalación. En este ejemplo, puedes acceder a la tienda local de Magento con los siguientes formatos de URL:
- http://<GCEexternalIP>/
- http://<GCEexternalIP>/<adminuri>
La GCEexternalIP se puede encontrar en la consola de Cloud:

Para cambiar el URI del panel de administración, usa este comando para ubicarlo:
php bin/magento info:adminuri
- Inhabilita el almacenamiento caché de página completa. Para fines de desarrollo, puedes inhabilitar el almacenamiento caché de página completa de Magento2. Esto te permitirá modificar los datos en Spanner y reflejarlos en el sitio web sin que se vean afectados por los valores almacenados en caché.
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, todo el estado, incluidos los datos, el esquema y los parámetros de configuración, se pierde cuando se reinicia. El emulador ofrece las mismas APIs que el servicio de producción de Spanner y está destinado al desarrollo y las pruebas locales, no a las 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:
# 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 Magento MySQL 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 nuestra instalación de Magento anterior a Spanner.
En esencia, HarbourBridge proporciona un flujo de trabajo automatizado para cargar el contenido de una base de datos de MySQL o PostgreSQL existente en Spanner. No requiere configuración: no hay manifiestos ni mapas de datos para escribir. En cambio, importa la base de datos de origen, compila un esquema de Spanner, crea una base de datos de Spanner nueva 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 para fines de evaluación, no para migraciones a gran escala.
HarbourBridge inicia la migración en etapa inicial a Spanner mediante el uso de una base de datos de origen de MySQL o PostgreSQL existente para que puedas comenzar a usar Spanner rápidamente. Genera un informe de evaluación con una puntuación general de preparación para la migración a Spanner, un análisis tabla por tabla de las asignaciones de tipos y una lista de las funciones que se usan 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. Puede tardar un tiempo en instalar todos los módulos necesarios en una instancia nueva sin que se haya configurado Go anteriormente.
# 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
Configura 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 migrada, trabajaremos para modificar Magento para que funcione con los datos almacenados en Spanner.
Se realizarán los siguientes pasos para convertir la instalación de Magento:
- 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 de catálogo, lista de deseos y carrito de la URL de Git que se menciona a continuación.
cd ~ git clone https://github.com/searceinc/magento-spanner-port
Tu directorio principal debería verse de la siguiente manera:
$ ls go harbourbridge magento-spanner-port magento2
Donde magento2 es el código base que modificaremos con el código de magento-spanner-port.
Cambia la conexión a Spanner
Para verificar 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 obtener una implementación de muestra.
- Requiere la biblioteca cliente de PHP google/cloud-spanner.
- Agrega el adaptador de Spanner para crear una conexión a Spanner.
- Configura la instancia de Spanner y la información del servidor.
- Agrega SpannerInterface y Spanner en el adaptador para implementar la conexión a Spanner.
Primero, debemos instalar la biblioteca de PHP cloud-spanner con Composer. En el directorio magento2, ejecuta este comando:
cd ~/magento2 composer require google/cloud-spanner
Luego, agregamos los archivos del adaptador de Spanner de magento-spanner-port a nuestro código base 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
Ahora, 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 que ahora se conecte a Spanner con la función Connection recién creada dentro del 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 Spanner. 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. Ahora, puedes ir a tu instalación de Magento en el navegador y verificar que se carguen los datos.
Por ejemplo, estas son las entradas del catálogo de relojes:

Modifica los datos de Spanner a través de la terminal para uno de los productos y consulta 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 ahora cambió a “Aim Analog Spanner” como se actualizó a través de la terminal de Spanner.

4. Felicitaciones
¡Felicitaciones! Conectaste correctamente el módulo de catálogo de Magento para que funcione 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.
Realiza una limpieza
Cuando se complete la configuración y la validación de la prueba de concepto, es posible que desees 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 decidiste usar una en lugar del emulador.
Próximos pasos
Este es solo un modelo de prototipo para una prueba de concepto de Spanner.
Si quieres obtener más información para trabajar con Spanner y las tecnologías que aprovechamos en este codelab, consulta estos recursos adicionales: