1. מבוא

שילוב של Magento עם קצה עורפי של Cloud Spanner
Magento היא פלטפורמת קוד פתוח פופולרית מאוד למסחר אלקטרוני שמבוססת על PHP ומאחסנת נתונים ב-MySQL.
ה-Codelab הזה הוא הוכחת היתכנות לשימוש ב-Cloud Spanner במקום ב-MySQL עבור מודול הקטלוג. המדריך הזה שימושי לכל מי שרוצה לשלב, לבדוק ולפרוס את Magento או אפליקציות אחרות של PHP עם Spanner.
Spanner הוא מסד נתונים מנוהל, מבוזר ועקבי של Google Cloud ברמה שמתאימה לארגונים, שמשלב את היתרונות של מודל מסד הנתונים הרלציוני עם יכולת הרחבה אופקית לא רלציונית. הוא נועד לתמוך בפריסות גלובליות של עיבוד עסקאות אונליין, בסמנטיקה של SQL, בהתאמה אופקית לעומס (scaling) עם זמינות גבוהה ובעקביות של עסקאות. Spanner יכול לטפל בכמויות גדולות של נתונים. השימוש בו לא מוגבל לאפליקציות גדולות, אבל הוא מאפשר סטנדרטיזציה של המנוע של מסד הנתונים יחיד לכל עומסי העבודה שדורשים RDBMS. Spanner מספק אפס זמן השבתה לתחזוקה מתוכננת או לכשלים באזור, עם הסכם רמת שירות (SLA) לזמינות של 99.999%. הוא תומך באפליקציות מודרניות על ידי מתן זמינות ומדרגיות גבוהות.
מה תלמדו
- איך מתקינים את Magento ב-GCE
- איך מגדירים את Spanner Emulator
- איך מעבירים סכימת MySQL קיימת ל-Spanner באמצעות HarbourBridge
- מה צריך לשנות כדי לשלב אפליקציות PHP כמו Magento שמשתמשות ב-MySQL כקצה עורפי של מסד הנתונים, כדי שהן יפעלו עם Spanner
מה תפַתחו
ה-Codelab הזה מתמקד בשילוב של Magento עם Spanner. בלוקים של קוד והוראות להגדרה מוצגים כדי שתוכלו להעתיק ולהדביק אותם, אבל לא מוסבר עליהם בפירוט.
ב-codelab הזה תתחילו לשלב את Magento עם Spanner. תצטרכו:
- הגדרה של מופע GCE עם Magento מותקן
- התקנה של Spanner Emulator
- התקנה של HarbourBridge Tool להעברת נתונים מ-MySQL ל-Spanner
- שינוי קולקציות של Magento כדי לטעון את קטלוג המוצרים מ-Spanner
הדרישות
- פרויקט ב-Google Cloud שמקושר לחשבון לחיוב.
- ידע בהגדרות של PHP, Linux ו-Apache הוא יתרון.
- ניסיון ב-Magento יעזור, אבל הוא לא חובה.
2. הכנת מופע GCE
יצירת מופע GCE
יוצרים מכונה של Compute Engine ב-Google Cloud Platform לפי השלבים שמפורטים כאן.
כשיוצרים את מופע GCE, משנים את סוג המופע ל-e2-standard-2 ואת גודל דיסק האתחול ל-20GB. אפשר להשאיר את כל ההגדרות כברירת מחדל, אבל חשוב לבחור באפשרויות Allow HTTP traffic (התרת תנועת HTTP) ו-Allow HTTPs traffic (התרת תנועת HTTPs), כי נשתמש בממשק האינטרנט של Magento.
התוצאה היא סוג מכונה e2-standard-2, שלא מבוססת על ליבה משותפת וכוללת 2vCPU, 8GB של RAM ו-20GB של נפח אחסון בדיסק.
מערכת ההפעלה היא Debian 10. יצירת המכונה עשויה להימשך דקה או שתיים.
אחרי שיוצרים את המכונה, לוחצים על SSH במסוף Cloud כדי להתחבר אליה:

ייפתח חלון חדש בדפדפן ותועברו לטרמינל.
התקנת התוכנה הנדרשת
כדי להריץ את 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
- מתקינים את מודולי ה-PHP שנדרשים ל-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
- התקנה של 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
אתם מתקינים את MySQL כדי להתקין את סכימת ברירת המחדל של Magento. בהמשך, תעבירו את הסכימה ל-Spanner באמצעות HarbourBridge.
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. בוחרים את האפשרויות:
- MySQL Server & Cluster
- mysql-5.7
- אישור

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:
- מתקינים את Magento בגרסה 2.4.2 באמצעות Composer. ב-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 {} +
- מגדירים את המארח הווירטואלי של Magento על ידי יצירת הקובץ /etc/apache2/sites-available/magento.conf עם התוכן שמופיע בהמשך.
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
- יצירת מסד נתונים ומשתמש עבור Magento ב-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/.
- אימות סביבת העבודה המקומית כדי לוודא שהסביבה המקומית מארחת את השרת, ניגשים לחנות באמצעות כתובת ה-URL הבסיסית שהועברה בפקודת ההתקנה. בדוגמה הזו, אפשר לגשת לחנות המקומית של Magento באמצעות הפורמטים הבאים של כתובות URL:
- http://<GCEexternalIP>/
- http://<GCEexternalIP>/<adminuri>
אפשר למצוא את ה-GCEexternalIP במסוף Cloud:

כדי לשנות את ה-URI של חלונית הניהול, משתמשים בפקודה הזו כדי לאתר אותו:
php bin/magento info:adminuri
- השבתת מטמון של דף מלא למטרות פיתוח, אפשר להשבית את המטמון של דף מלא ב-Magento2. כך תוכלו לשנות את הנתונים ב-Spanner והשינויים יופיעו באתר בלי שהערכים במטמון ישפיעו עליהם.
php bin/magento cache:disable full_page
הגדרת Spanner
התקנת Spanner Emulator
Cloud SDK מספק אמולטור מקומי בזיכרון, שבו אפשר להשתמש כדי לפתח ולבדוק את האפליקציות בחינם בלי ליצור פרויקט ב-GCP או חשבון לחיוב. מכיוון שהאמולטור שומר נתונים רק בזיכרון, כל המצב, כולל נתונים, סכימה והגדרות, הולך לאיבוד בהפעלה מחדש. האמולטור מציע את אותם ממשקי API כמו שירות הייצור של 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
העברת נתוני Magento MySQL ל-Spanner
לפני שנתחיל לשלב את Spanner, נשתמש בכלי שנקרא HarbourBridge כדי להמיר את מסד הנתונים של MySQL שנוצר כחלק מההתקנה של Magento שצוינה למעלה ל-Spanner.
בבסיסו, HarbourBridge מספק תהליך עבודה אוטומטי לטעינת התוכן של מסד נתונים קיים של MySQL או PostgreSQL לתוך Spanner. לא נדרשת הגדרה – אין צורך לכתוב קובצי מניפסט או מיפוי נתונים. במקום זאת, הוא מייבא את מסד הנתונים של המקור, בונה סכמה של Spanner, יוצר מסד נתונים חדש של Spanner שאוכלס בנתונים ממסד הנתונים של המקור ומפיק דוח הערכה מפורט. HarbourBridge מיועד לטעינת מסדי נתונים בגודל של עד כמה עשרות GB למטרות הערכה, ולא להעברות בקנה מידה מלא.
HarbourBridge מאתחל העברה בשלב מוקדם אל Spanner באמצעות מסד נתונים קיים של MySQL או PostgreSQL, כדי שתוכלו להתחיל להשתמש ב-Spanner במהירות. הכלי יוצר דוח הערכה עם ציון כללי של מידת ההתאמה להעברה ל-Spanner, ניתוח של מיפוי סוגים לפי טבלה ורשימה של תכונות שנעשה בהן שימוש במסד הנתונים של המקור ושלא נתמכות ב-Spanner.
אפשר להשתמש ב-HarbourBridge עם Spanner Emulator או ישירות עם מופע Spanner.
ב-README של HarbourBridge יש מדריך למתחילים עם הוראות מפורטות לשימוש בכלי עם מופע 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 ויצרנו את מופע Spanner עם מסד הנתונים של Magento שהועבר, נשנה את Magento כך שיפעל עם הנתונים שמאוחסנים ב-Spanner.
הפעולות הבאות יבוצעו כדי להמיר את ההתקנה של Magento:
- משכפלים את הפרויקט magento-spanner-port
- שינוי החיבור ל-Spanner
- בדיקה שהפרטים של הקטלוג מאוכלסים מ-Spanner
שכפול של ה-fork של פרויקט Magento
משכפלים את קוד האפליקציה של PHP עבור Magento שמכיל את השינויים במודולים Catalog, Wishlist ו-Cart מכתובת ה-URL של Git שמצוינת בהמשך.
cd ~ git clone https://github.com/searceinc/magento-spanner-port
ספריית הבית אמורה להיראות כך:
$ ls go harbourbridge magento-spanner-port magento2
כאשר magento2 הוא בסיס הקוד שאנחנו הולכים לשנות, באמצעות קוד מ-magento-spanner-port.
שינוי החיבור ל-Spanner
כדי לבדוק אם השינויים בקוד משתקפים בממשק המשתמש, אפשר לפעול לפי השלבים הבאים:
אפשר לעיין בקישור ל-Github https://github.com/searceinc/magento-spanner-port כדי לראות הטמעה לדוגמה.
- דרישה לספריית הלקוח google/cloud-spanner PHP
- מוסיפים את Spanner Adapter כדי ליצור חיבור ל-Spanner.
- מגדירים את מופע Spanner ואת פרטי השרת.
- מוסיפים את SpannerInterface ואת Spanner למתאם כדי להטמיע את החיבור ל-Spanner.
קודם צריך להתקין את ספריית PHP של Cloud Spanner באמצעות Composer. בספרייה magento2, מריצים את הפקודה הבאה:
cd ~/magento2 composer require google/cloud-spanner
לאחר מכן מוסיפים את קובצי Spanner Adapter מ-magento-spanner-port אל בסיס הקוד של 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
עכשיו משנים את הקובץ DB/Adapter/Spanner/Spanner.php כדי להזין את פרטי הקישוריות של Spanner ל-$project_id, $instance ו-$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();
}
משנים את המחלקה AbstractDB ב-Magento כדי להתחבר ל-Spanner באמצעות פונקציית החיבור החדשה שנוצרה ב-Spanner Adapter. מוסיפים את השורות הירוקות אחרי השורות הלבנות בקובץ. מידע נוסף זמין בכתובת 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 . משנים את השיטה _loadAttributes ב-AbstractCollection כדי להתחבר ל-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)
עכשיו, טוענים מחדש את המסך כדי לוודא שהשם של השעון השתנה ל-Aim Analog Spanner, כמו שעדכנתם דרך מסוף Spanner.

4. מזל טוב
המודול Catalog של Magento קושר בהצלחה ל-Spanner. זה לא שילוב מלא, אבל עכשיו אתם יודעים מהם הרכיבים שצריך כדי לחבר אפליקציית PHP כמו Magento למופע Spanner.
סידור וארגון
אחרי שתסיימו את ההגדרה והאימות של ה-POC, יכול להיות שתרצו למחוק את משאבי ה-GCP שנוצרו במהלך התהליך. זה כולל את המכונה הווירטואלית של Compute Engine, וגם מופע של Cloud Spanner אם החלטתם להשתמש בו במקום באמולטור.
מה השלב הבא?
זהו רק מודל אב טיפוס ל-POC של Spanner.
כדי לקבל מידע נוסף על עבודה עם Spanner ועל הטכנולוגיות שבהן השתמשנו ב-codelab הזה, אפשר להיעזר במקורות המידע הבאים: