PolarDB-Xとは
PolarDB-XはAlibaba Cloudで提供されているクラウドネイティブ分散型RDBです。
GCPのSpannerやPingCAPのTiDBと同じカテゴリの水平方向にスケーリングするNewSQLに分類されるデータベースです。
特徴:
-
分散型データベース
- データは複数のノードに跨いて保持されていて、つまりどちらのノードでも全てのデータを持っていいるのではなく、一部しかもっていない。
- AWS RDSは集中型データベースであり、master/slaveや read replicaの場合でも、書くノードはすべてのデータを持っていて、ストレージ容量が限られていて、大量の同時アクセスのシーンでは対応しきれないという課題があります。
- 水平拡張によって読み取りと書き込み両方の性能向上が可能
- AWS RDSではread replicaによって全体的な読み取りの性能が上げられるが、書き込みは全部primary instanceで処理されるため、書き込み性能をupさせるにはprimary instanceのスペックをあげるしかない。(数分程度DB停止になってしまう)
- データは複数のノードに跨いて保持されていて、つまりどちらのノードでも全てのデータを持っていいるのではなく、一部しかもっていない。
-
opensourceのデータベース
https://github.com/ApsaraDB/PolarDB-X
Component Name | Repository |
---|---|
CN (Compute Node) | galaxysql |
GMS (Global Meta Service) | galaxyengine |
DN (Data Node) | galaxyengine |
CDC (Change Data Capture) | galaxycdc |
PolarDB-XはCN,GMS,DN,CDC4つのコンポーネントから構成されている。 上記はそれぞれのgithub repoです。
-
- 基本的にMySQLと互換性があり、web frameworkからPolarDB-Xを利用するにはmysqlのライブラリがあれば、そのままPolarDB-Xに接続できる。
-
透明的なパーティション分割
- 従来のdatabaseでsharding(パーティション分割)を行うには、アプリケイーション側でどのノードにどのデータを持っているのを意識する必要があり、アプリケイーションのロジックが非常に複雑になりがちです。
- PolorDB-Xではauto incrementのprimary keyをパーティションkeyとしてデフォルトで利用、hash関数で自動的に複数のパーティションに分散される。従来のシングルノードのMySQLと同じ感覚で分散型のデータベースが利用できる。
ローカル環境(macOS)にdocker-composeを利用してPolarDB-XとWordPressをinstall
dockerのインストール
任意のディレクトリにdocker-compose.ymlを作成
version: '3'
services:
polardbx:
image: polardbx/polardb-x
restart: always
container_name: polardbx
ports:
- "8527:8527"
wordpress:
depends_on:
- polardbx
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: polardbx:8527
WORDPRESS_DB_USER: polardbx_root
WORDPRESS_DB_PASSWORD: 123456
WORDPRESS_DB_NAME: wordpress
- polardb-x:
- デフォルト設定のuser名とpasswordを利用してください。
- user名:
polardbx_root
- password:
123456
- user名:
- dockerhub にpolardb-xのdockerfileがなさそうなので、デフォルトのuser名とpasswordの変更方法が不明です。
- デフォルト設定のuser名とpasswordを利用してください。
- wordpress:
- depends_onでコンテナの依存関係を定義しているので、この例ですとpolardbxを起動してから、wordpressが起動される設定となります。
- hostやuserなどの環境変数設定方法は https://hub.docker.com/_/wordpress をご参考ください。
docker-composeを実行
docker compose up -d
[+] Running 1/2
[+] Running 2/2lardbx Starting 0.5s
⠿ Container polardbx Started 0.5s
⠿ Container wordpresspolardb-x-wordpress-1 Star... 1.0s
docker compose ps
NAME COMMAND SERVICE STATUS PORTS
polardbx "/bin/sh -c /home/ad…" polardbx running 0.0.0.0:8527->8527/tcp
wordpresspolardb-x-wordpress-1 "docker-entrypoint.s…" wordpress running 0.0.0.0:8000->80/tcp
polardb-xにログインし、wordpressに必要なdatabaseを作成しておく
$ mysql -h127.0.0.1 -P8527 -upolardbx_root -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.6.29 Tddl Server (ALIBABA)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
- 以下のエラーが発生している場合は、polardb-xクラスター準備している途中なので、三四分程度経ってから再度ログインしてください。
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
- databaseを作成
mysql> create database wordpress MODE='AUTO';
mysql> show databases;
+--------------------+
| DATABASE |
+--------------------+
| information_schema |
| wordpress |
+--------------------+
WordPressを設定
DBの中身の確認
mysql> use wordpress;
Database changed
mysql> show tables;
+-----------------------+
| TABLES_IN_WORDPRESS |
+-----------------------+
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
mysql> select * from wp_users;
+--------+------------+------------------------------------+---------------+---------------------+-----------------------+---------------------+---------------------+-------------+--------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+--------+------------+------------------------------------+---------------+---------------------+-----------------------+---------------------+---------------------+-------------+--------------+
| 100001 | dennis | $P$BkGz1QgYBqElISzywtQl7hzAEB47f3. | dennis | **** | http://localhost:8000 | 2022-07-25 05:35:30 | | 0 | dennis |
+--------+------------+------------------------------------+---------------+---------------------+-----------------------+---------------------+---------------------+-------------+--------------+
- wp_usersテーブルのpartition状況確認:
自動的に8つのpartitionに分割されていることが確認できる
mysql> show topology from wp_users;
+----+------------------------+---------------------+----------------+
| ID | GROUP_NAME | TABLE_NAME | PARTITION_NAME |
+----+------------------------+---------------------+----------------+
| 0 | WORDPRESS_P00000_GROUP | wp_users_d0DM_00000 | p1 |
| 1 | WORDPRESS_P00000_GROUP | wp_users_d0DM_00001 | p2 |
| 2 | WORDPRESS_P00000_GROUP | wp_users_d0DM_00002 | p3 |
| 3 | WORDPRESS_P00000_GROUP | wp_users_d0DM_00003 | p4 |
| 4 | WORDPRESS_P00000_GROUP | wp_users_d0DM_00004 | p5 |
| 5 | WORDPRESS_P00000_GROUP | wp_users_d0DM_00005 | p6 |
| 6 | WORDPRESS_P00000_GROUP | wp_users_d0DM_00006 | p7 |
| 7 | WORDPRESS_P00000_GROUP | wp_users_d0DM_00007 | p8 |
+----+------------------------+---------------------+----------------+
- テーブルの作成コマンドでprimary keyの
ID
はpartion keyとして利用していることが分かる。
mysql> show full create table wp_users;
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| wp_users | CREATE PARTITION TABLE `wp_users` (
`ID` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_login` varchar(60) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`user_pass` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`user_nicename` varchar(50) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`user_email` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`user_url` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`user_registered` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_activation_key` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
`user_status` int(11) NOT NULL DEFAULT '0',
`display_name` varchar(250) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
PRIMARY KEY (`ID`),
GLOBAL INDEX /* user_email_$34fb */ `user_email` (`user_email`) PARTITION BY KEY (`user_email`, `ID`) PARTITIONS 8,
GLOBAL INDEX /* user_login_key_$377b */ `user_login_key` (`user_login`) PARTITION BY KEY (`user_login`, `ID`) PARTITIONS 8,
GLOBAL INDEX /* user_nicename_$b701 */ `user_nicename` (`user_nicename`) PARTITION BY KEY (`user_nicename`, `ID`) PARTITIONS 8,
LOCAL KEY `_local_user_login_key` (`user_login`),
LOCAL KEY `_local_user_nicename` (`user_nicename`),
LOCAL KEY `_local_user_email` (`user_email`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_520_ci
PARTITION BY KEY(`ID`)
PARTITIONS 8
/* tablegroup = `tg1` */ |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
- userはどのpartitionに保持されているのかを確認
- ID=1のuserはP2に保持されていることが分かる。
mysql> SELECT PARTITION_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='wp_users';
+----------------+------------+
| PARTITION_NAME | TABLE_ROWS |
+----------------+------------+
| p1 | 0 |
| p2 | 1 |
| p3 | 0 |
| p4 | 0 |
| p5 | 0 |
| p6 | 0 |
| p7 | 0 |
| p8 | 0 |
+----------------+------------+
mysql> select * from wp_users;
+--------+------------+------------------------------------+---------------+---------------------+-----------------------+---------------------+---------------------+-------------+--------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+--------+------------+------------------------------------+---------------+---------------------+-----------------------+---------------------+---------------------+-------------+--------------+
| 100001 | dennis | $P$BkGz1QgYBqElISzywtQl7hzAEB47f3. | dennis | outanwang@gmail.com | http://localhost:8000 | 2022-07-25 05:35:30 | | 0 | dennis |
| 100002 | test | $P$BhNx08hRmtRynzmRWWBOex6glWZtwO0 | test | test4@example.com | http://test | 2022-07-25 06:26:19 | | 0 | test |
| 100003 | test2 | $P$B.ednrTvBfGla87FEXgBdGK/w1PPoe. | test2 | test2@example.com | http://test2 | 2022-07-25 07:29:13 | | 0 | test2 |
+--------+------------+------------------------------------+---------------+---------------------+-----------------------+---------------------+---------------------+-------------+--------------+
- INFORMATION_SCHEMA.PARTITIONSから取得した情報はあくまでも統計情報(概算)であり、反映されていない場合がある。
- 3つのレコードがあるにも関わらず、一つしか表示されていない。
mysql> SELECT PARTITION_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='wp_users';
+----------------+------------+
| PARTITION_NAME | TABLE_ROWS |
+----------------+------------+
| p1 | 0 |
| p2 | 1 |
| p3 | 0 |
| p4 | 0 |
| p5 | 0 |
| p6 | 0 |
| p7 | 0 |
| p8 | 0 |
+----------------+------------+
- partitionを指定し、件数を確認
- P2,P5,P7にそれぞれ一件のデータがあることが分かる。
mysql> select * from wp_users PARTITION (p1);
Empty set (0.01 sec)
mysql> select * from wp_users PARTITION (p2);
+--------+------------+------------------------------------+---------------+---------------------+-----------------------+---------------------+---------------------+-------------+--------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+--------+------------+------------------------------------+---------------+---------------------+-----------------------+---------------------+---------------------+-------------+--------------+
| 100001 | dennis | $P$BkGz1QgYBqElISzywtQl7hzAEB47f3. | dennis | outanwang@gmail.com | http://localhost:8000 | 2022-07-25 05:35:30 | | 0 | dennis |
+--------+------------+------------------------------------+---------------+---------------------+-----------------------+---------------------+---------------------+-------------+--------------+
1 row in set (0.01 sec)
mysql> select * from wp_users PARTITION (p3);
Empty set (0.00 sec)
mysql> select * from wp_users PARTITION (p4);
Empty set (0.01 sec)
mysql> select * from wp_users PARTITION (p5);
+--------+------------+------------------------------------+---------------+-------------------+-------------+---------------------+---------------------+-------------+--------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+--------+------------+------------------------------------+---------------+-------------------+-------------+---------------------+---------------------+-------------+--------------+
| 100002 | test | $P$BhNx08hRmtRynzmRWWBOex6glWZtwO0 | test | test4@example.com | http://test | 2022-07-25 06:26:19 | | 0 | test |
+--------+------------+------------------------------------+---------------+-------------------+-------------+---------------------+---------------------+-------------+--------------+
1 row in set (0.01 sec)
mysql> select * from wp_users PARTITION (p6);
Empty set (0.01 sec)
mysql> select * from wp_users PARTITION (p7);
+--------+------------+------------------------------------+---------------+-------------------+--------------+---------------------+---------------------+-------------+--------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+--------+------------+------------------------------------+---------------+-------------------+--------------+---------------------+---------------------+-------------+--------------+
| 100003 | test2 | $P$B.ednrTvBfGla87FEXgBdGK/w1PPoe. | test2 | test2@example.com | http://test2 | 2022-07-25 07:29:13 | | 0 | test2 |
+--------+------------+------------------------------------+---------------+-------------------+--------------+---------------------+---------------------+-------------+--------------+
1 row in set (0.01 sec)
mysql> select * from wp_users PARTITION (p8);
Empty set (0.02 sec)
まとめ
- polardb-xは分散型RDBであり、デフォルトはPrimary keyをpartition keyとして利用するため、MySQLのpartition関連のノウハウを持っていなくても簡単にpartition利用できて、分散型のデータベースを体験できる。
- primary keyのないテーブルに対して、自動的にBIGINTのprimary key(userから見れないkey)を作成し,partition keyとして利用することにになる。
- 特に分散やpartitionを意識しなくてもシングルノードのMySQLと同じ感覚で、分散型データベース利用できる(もちろん同時処理の性能が水平的に拡張できるという分散型のデータベースの最大のメリットを活かすにはpartiton関連の知識がある程度必要です。)
- polardb-xはopensourceのデータベースであり、ローカル環境でもdockerで簡単に実行できる。