1. はじめに

Magento と Cloud Spanner バックエンドの統合
Magento は、PHP ベースのオープンソースの e コマース プラットフォームで、MySQL にデータを保存します。
この Codelab は、カタログ モジュールで MySQL の代わりに Cloud Spanner を活用するための概念実証です。これは、Magento や他の PHP アプリケーションを Spanner と統合、テスト、デプロイすることに関心のある方にとって役立ちます。
Spanner は、リレーショナル データベース モデルのメリットと非リレーショナルの水平方向のスケーラビリティを兼ね備えた、Google Cloud のフルマネージド型、エンタープライズ クラス、分散型かつ整合性を備えたデータベースです。グローバル オンライン トランザクション処理のデプロイ、SQL セマンティクス、高可用性の水平スケーリング、トランザクションの整合性をサポートするように設計されています。Spanner は大量のデータを処理できます。大規模なアプリケーションだけでなく、RDBMS を必要とするすべてのワークロードを 1 つのデータベース エンジンで標準化できます。Spanner は、計画的なメンテナンスやリージョンの障害が発生した場合に、99.999%の可用性 SLA でゼロ ダウンタイムを実現します。高可用性とスケーラビリティにより、最新のアプリケーションがサポートされます。
学習内容
- GCE に Magento をインストールする方法
- Spanner エミュレータの設定方法
- HarbourBridge を使用して既存の MySQL スキーマを Spanner に移行する方法
- データベース バックエンドに MySQL を使用する Magento などの PHP アプリケーションを Spanner と連携させるために変更する必要がある内容
作成するアプリの概要
この Codelab では、Magento と Spanner の統合に焦点を当てます。コードブロックと設定手順はコピーして貼り付けられるように提供していますが、詳細については説明していません。
この Codelab では、Magento と Spanner の統合を開始します。次のことを行います。
- Magento がインストールされた GCE インスタンスを設定する
- Spanner エミュレータ をインストールする
- MySQL から Spanner へのデータ移行用に HarbourBridge ツールをインストールする
- Magento コレクションを変更して Spanner から商品カタログを読み込む
必要なもの
- 請求先アカウントに接続されている Google Cloud プロジェクト。
- PHP、Linux、Apache の構成に関する知識があれば尚可。
- Magento の経験があると役立ちますが、必須ではありません。
2. GCE インスタンスの準備
GCE インスタンスを作成する
こちらの手順に沿って、Google Cloud Platform で Compute Engine インスタンスを作成します。
GCE インスタンスの作成時に、インスタンス タイプを e2-standard-2 に、ブートディスクのサイズを 20 GB に変更します。すべてをデフォルトのままにできますが、Magento のウェブ インターフェースを利用するため、[HTTP トラフィックを許可する] と [HTTPs トラフィックを許可する] を必ず選択してください。
これにより、共有コア インスタンスではなく、2 個の vCPU、8 GB の RAM、20 GB のディスク容量を持つ e2-standard-2 のマシンタイプが作成されます。
オペレーティング システムは Debian 10 です。インスタンスの作成には 1 ~ 2 分かかることがあります。
作成したら、Cloud Console で [SSH] をクリックしてログインします。

新しいブラウザ ウィンドウが開き、ターミナルが表示されます。
前提条件のソフトウェアをインストールする
Magento を実行するには、いくつかの前提条件となるソフトウェアをインストールする必要があります。具体的には、以下で説明するように、PHP、Elastic、MySQL、Apache をインストールします。
- 必要なパッケージをインストールします。
sudo apt update sudo apt -y install lsb-release apt-transport-https ca-certificates wget git screen composer google-cloud-sdk-spanner-emulator gcc
- Magento に必要な PHP モジュールをインストールします。
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
- Elasticsearch をインストールしてサービスを開始する
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
- MySQL のインストール
デフォルトの Magento スキーマをインストールするために MySQL をインストールしている。その後、HarbourBridge を使用してスキーマを Spanner に移行します。
wget https://dev.mysql.com/get/mysql-apt-config_0.8.13-1_all.deb sudo dpkg -i mysql-apt-config*
上記の dpkg コマンドを実行すると、MySQL 5.7 Server をインストールするためのインタラクティブなプロンプトが表示されます。オプションを選択します。
- MySQL Server と Cluster
- mysql-5.7
- OK

sudo apt update && sudo apt -y install mysql-server # You will be prompted to enter a root password
- Apache2 をインストールする
sudo apt -y install apache2 sudo a2enmod proxy_fcgi rewrite
Magento2 をインストールして構成する
Magento Commerce Cloud プロジェクトには、Magento サイトとストアに完全にアクセスするためのデータベース スキーマとサービスが含まれています。
これをインストールして実行する最も簡単な方法は、Magento の手順に沿って Composer を使用してインストールすることです。
- composer を使用して Magento バージョン 2.4.2 をインストールします。Magento 2 には composer 1.x バージョンが必要です。このバージョンのサポートが非推奨になったという警告が表示されることがあります。
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
- フォルダの権限を設定する
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 {} +
- 次の内容で /etc/apache2/sites-available/magento.conf を作成して、Magento 仮想ホストを構成します。
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>
- シンボリック リンクを作成して 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
- MySQL で Magento のデータベースとユーザーを作成する
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/.
- ローカル ワークスペースを確認するローカル環境がサーバーをホストしていることを確認するには、インストール コマンドで渡したベース URL を使用してストアにアクセスします。この例では、次の URL 形式を使用してローカルの Magento ストアにアクセスできます。
- http://<GCEexternalIP>/
- http://<GCEexternalIP>/<adminuri>
GCEexternalIP は Cloud コンソールで確認できます。

管理パネルの URI を変更するには、次のコマンドを使用して URI を特定します。
php bin/magento info:adminuri
- フルページ キャッシュを無効にする開発目的で、Magento2 のフルページ キャッシュを無効にできます。これにより、キャッシュに保存された値の影響を受けることなく、Spanner のデータを変更してウェブサイトに反映させることができます。
php bin/magento cache:disable full_page
Spanner を設定する
Spanner エミュレータをインストールする
Cloud SDK にはローカルなインメモリのエミュレータが用意されています。このエミュレータを使用すると、GCP プロジェクトや請求先アカウントを作成することなく、アプリケーションを開発してテストできます。エミュレータはメモリにのみデータを格納するため、再起動すると、データ、スキーマ、構成を含め、すべての状態が失われます。Spanner の本番環境サービスと同じ API を提供するこのエミュレータは、本番環境へのデプロイではなく、ローカルでの開発とテストを目的として作られています。
エミュレータのインストール、使用、デプロイについて詳しくは、以下のリンクをご覧ください。
# 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
Magento MySQL を Spanner に移行する
Spanner の統合に入る前に、HarbourBridge というツールを使用して、上記の Magento インストールの一部として作成された MySQL データベースを Spanner に変換します。
HarbourBridge は、既存の MySQL または PostgreSQL データベースの内容を Spanner に読み込むための自動化されたワークフローを提供します。構成は不要で、マニフェストやデータマップを記述する必要はありません。代わりに、ソース データベースをインポートし、Spanner スキーマをビルドし、ソース データベースのデータが入力された新しい Spanner データベースを作成し、詳細な評価レポートを生成します。HarbourBridge は、本格的な移行ではなく、評価目的で数十 GB までのデータベースを読み込むことを目的としています。
HarbourBridge は、既存の MySQL または PostgreSQL のソース データベースを使用して、Spanner への初期段階の移行をブートストラップし、Spanner での迅速な稼働を可能にします。Spanner の移行適性スコア、型マッピングのテーブルごとの分析、Spanner でサポートされていない移行元データベースで使用されている機能のリストを含む評価レポートが生成されます。
HarbourBridge は、Spanner エミュレータまたは Spanner インスタンスで直接使用できます。
HarbourBridge README には、Spanner インスタンスでツールを使用するためのクイックスタート ガイドが記載されています。
HarbourBridge をインストールする
ツールをマシンにダウンロードしてインストールします。この機能を動作させるには、golang をインストールする必要があります。Go が事前に設定されていない新しいインスタンスに、必要なモジュールをすべてインストールするには時間がかかることがあります。
# 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
データを移行する
次のコマンドを使用して、Magento データベースを Spanner に移行します。
mysqldump --user='root' --password=$ROOT_PASSWORD magento | go run github.com/cloudspannerecosystem/harbourbridge -driver=mysqldump -dbname=magento
spanner-cli ツールを設定する
go install github.com/cloudspannerecosystem/spanner-cli@latest
3. Magento を変換して Spanner で動作させる
Magento が実行され、Magento データベースが移行された Spanner インスタンスが作成されたので、Spanner に保存されているデータを操作するように Magento を変更します。
Magento のインストールを変換する手順は次のとおりです。
- magento-spanner-port プロジェクトのクローンを作成する
- Spanner への接続を変更する
- カタログの詳細が Spanner から入力されていることを検証する
Magento プロジェクトのフォークのクローンを作成する
以下の Git URL から、Magento の PHP アプリケーション コードのクローンを作成します。このコードには、カタログ、ウィッシュリスト、カートの各モジュールに対する変更が含まれています。
cd ~ git clone https://github.com/searceinc/magento-spanner-port
ホーム ディレクトリは次のようになります。
$ ls go harbourbridge magento-spanner-port magento2
ここで、magento2 は変更するコードベースであり、magento-spanner-port のコードを使用します。
Spanner への接続を変更する
コードの変更が UI に反映されているかどうかを確認する手順は次のとおりです。
実装例については、Github リンク https://github.com/searceinc/magento-spanner-port を参照してください。
- google/cloud-spanner PHP クライアント ライブラリを必要とする
- Spanner への接続を作成するための Spanner アダプタを追加。
- Spanner インスタンスとサーバー情報を構成します。
- Adapter に SpannerInterface と Spanner を追加して、Spanner への接続を実装します。
まず、composer を使用して cloud-spanner PHP ライブラリをインストールする必要があります。magento2 ディレクトリで、次のコマンドを実行します。
cd ~/magento2 composer require google/cloud-spanner
次に、magento-spanner-port から magento2 コードベースに Spanner アダプタ ファイルを追加します。
~/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
次に、DB/Adapter/Spanner/Spanner.php ファイルを変更して、$project_id、$instance、$database の Spanner 接続情報を入力します。
$ 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();
}
Magento 内の AbstractDB クラスを変更して、Spanner アダプタ内で新しく作成された Connection 関数を使用して Spanner に接続するようにします。ファイルの白い行の後に緑の行を追加します。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;
}
...
接続が確立されたら、MySQL アダプタから Spanner アダプタにデータ取得メソッドを変更する必要があります。AbstractCollection の _loadAttributes メソッドを変更して、Spanner に接続し、Spanner からデータを取得します。赤い行を緑色の行に置き換えます。
/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);
...
カタログの詳細が Spanner から入力されていることを検証する
これで、これで、ブラウザで Magento のインストールに移動し、データが読み込まれていることを確認できます。
たとえば、時計のカタログ エントリは次のようになります。

いずれかのプロダクトのターミナルから Spanner データを変更し、ターミナルからデータをクエリして、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)
画面を再読み込みして、Spanner ターミナルで更新されたとおり、スマートウォッチの名前が「Aim Analog Spanner」に変更されていることを確認します。

4. 完了
おめでとうございます。Magento のカタログ モジュールを Spanner と連携させることに成功しました。完全な統合ではありませんが、Magento などの PHP アプリケーションを Spanner インスタンスに接続するための要素を理解できました。
クリーンアップ
POC の設定と検証が完了したら、プロセス中に作成された GCP リソースを削除することをおすすめします。これには、Compute Engine 仮想マシンと、エミュレータの代わりに Cloud Spanner インスタンスを使用する場合はそのインスタンスが含まれます。
次のステップ
これは、Spanner の POC のプロトタイプ モデルです。
Spanner とこの Codelab で使用したテクノロジーの詳細については、以下のリソースをご覧ください。