概要
CloudSQLのIO性能を観察する。CloudSQLはGCPで提供されているRDBMSのマネジメントサービス。(AWSで言うところのRDS)
CloudSQLのディスクのスループットとIOPSは、ディスクサイズで決定されるため、ここを変化させたときのパフォーマンスの変化も観察する。
この記事では検証のための準備を行う。(長くなりそうなため記事を分割)
検証方法
MySQLの"LOAD DATA LOCAL INFILE"でファイルから巨大なデータを読み込ませる。必要に応じて複数プロセスから並列でデータをロードする。
環境
CloudSQL
- MySQL 第 2 世代
- MySQL 5.7
- asia-northeast1-a
- インスタンスタイプ、ディスクサイズは検証ごとに変える
クライアント側
CloudSQLに対して接続するためのクライアント。
- ComputeEngine
- n1-standard-1(vCPU x 1、メモリ 3.75 GB)
- クライアント側がボトルネックになりそうなら、スケールアップする
- asia-northeast1-b
- Debian GNU/Linux 9
- ディスクは200GBのボリュームをアタッチ
セットアップ
クライアントの作成、設定
- WebUIからインスタンスを作成
- IPアドレスは、CloudSQLに登録するため固定IPアドレスにする(エフェメラル -> 静的)
$ sudo apt install mysql-client
$ mysql --version
mysql Ver 15.1 Distrib 10.1.37-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
MySQLインスタンスの作成
- WebUIからインスタンスを作成
- 接続を許可するIPするとして、クライアントの静的IPアドレスを指定
- 本当はCloudProxyを使った方がいいが、面倒なので今回はIPアドレスを許可する
検証用のデータやMySQLテーブルの用意
BigQueryの公開データが、いい感じでサイズが大きいので利用させてもらう。
今回は、bigquery-public-data.stackoverflow.stackoverflow_posts
を使った。(行数:31,017,889、サイズ:29.36 GB)
- BigQueryのWebUIから上記のテーブルをCSV形式でエクスポートする。圧縮は指定した方が良い。
- 必要に応じてストレージ(GCS)のバケットを作成する
- データサイズが大きいので、エクスポート先のファイル名に"*"を使わないとエラーになる
- ComputeEngineでもろもろ準備する
$ cd /path/to/work_dir
$ mkdir data/ && cd data/
$ gsutil -m copy gs://your_backet_name/csv/* .
# いい感じにファイル名を指定していたら不要かも
$ find . -type f | xargs -i mv {} {}.gz
$ find . -type f | xargs gzip -d
$ cd ..
スクリプトを設置して実行権限を付与する。
table_load.sh
#!/bin/bash
# 環境に合わせて変える
FILE_DIR="data/"
MYSQL_HOST="xxx.xxx.xxx.xxx"
MYSQL_USER="user"
MYSQL_PASS="pass"
MYSQL_TABLE="t1"
MYSQL_DB="mydb"
for f in $(ls $FILE_DIR); do
echo "START $f"
# 一行目はCSVのヘッダがあるのでIGNOREする
# バックスラッシュが含まれるとエスケープの関係で"utf-8ではない"的なエラーが出るので、"ESCAPED BY"が必要
command="LOAD DATA LOCAL INFILE \"$FILE_DIR$f\" INTO TABLE $MYSQL_TABLE
FIELDS TERMINATED BY ',' ESCAPED BY '' IGNORE 1 LINES;"
mysql -h$MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASS -e "$command" $MYSQL_DB
echo "END $f"
done
- MySQLにデータベース、テーブルを作成する
MySQL [(none)]> create database mydb;
MySQL [(none)]> use mydb;
MySQL [mydb]> create table ...(下記を参照)
create_table.sql
-- id, parent_idなどはBigQueryではINTEGERのためINTにしたくなるが、データがない(null)の場合もあるので、
-- INTにするとwarningが発生する. 今回はVARCHARやTEXTにしても問題ないと判断.(IO性能が見たいだけなので)
CREATE TABLE t1 (
id VARCHAR(10),
title TEXT,
body TEXT,
accepted_answer_id VARCHAR(10),
answer_count VARCHAR(10),
comment_count VARCHAR(10),
community_owned_date TEXT,
creation_date TEXT,
favorite_count VARCHAR(10),
last_activity_date TEXT,
last_edit_date TEXT,
last_editor_display_name TEXT,
last_editor_user_id VARCHAR(10),
owner_display_name TEXT,
owner_user_id VARCHAR(10),
parent_id VARCHAR(10),
post_type_id VARCHAR(10),
score VARCHAR(10),
tags TEXT,
view_count VARCHAR(10)
);
- 設定したスクリプトを実行すると、データのロードが始まり、データベースにIO負荷がかかる
参考文献
- 13.2.6 LOAD DATA INFILE 構文