今回はさらっとオプティマイズの話です。
RDSのMySQLでCloudWatchのFree Spaceに関するAlarmがでることがあります。
RDSに限ったことではないですが、MySQLを運用しているとディスクスペースが減っていき、データをDeleteしてもディスク空き容量が増えないことが多くあります。
データを削除しても、削除した箇所はフリースペースとして確保され、開放されないことが多く、長い間放置しているとディスク容量を圧迫してしまいます。
このようなときには、MySQLのOptimizeを行います。
サンプルとしてtpcc-mysqlのデータを投入しておきます。
RDSでデータの多いテーブルの偶数行を削除します。
削除してしばらくしてもデータ空き容量は増えないため、Optimizeを行なってみます。
"Table does not support optimize"と表示されます。
ドキュメントを見ると、InnoDBではOPTIMIZE TABLEはALTER TABLEにマップされると書いてあります。
そのため、ALTER TABLEを行なっても最適化されるようです。
再びいろいろデータを削除してみます。
削除してしばらくしてもやはり、データ空き容量は増えません。
今度はALTER TABLEをしてみます。
少し待って、RDSのCloudWatchを見てみます。
すると、OPTIMIZE TABLEやALTER TABLEをした時点で使用領域が開放され、ディスク容量が増えているのがわかります。
ALTER TABLEなのでメンテナンス時間に行う必要がありますが、
追加削除の頻度が高いDBで、ディスク容量を増やすことが難しい場合には丁度よい対策になりますし、アクセスも高速になるため定期的におこなった方がよいかと思います。
オプティマイズに関してはRDSに限ったことではないのですが、CloudWatchを使うとオプティマイズ時期の目安にもなりとても便利です。
以上です。
2013年3月4日月曜日
2013年2月19日火曜日
RDSってなんじゃ?(MySQL on EBS-PIOPS vs RDS-PIOPS)
最近、Provisioned IOPS(以下PIOPS)という機能がEBSとRDSで使用できるようになりました。
そこで、EBS with PIOPS上のMySQLと、RDS with PIOPSでベンチマークを取ってみました。
MySQLインスタンスの起動設定をします。
あとは手順にしたがって進みます。
以下のようにm1.largeを選び、EBS-Optimized instanceにチェックを入れます。
EBS VolumesでVolume Sizeを100GiBにして、Volume TypeをProvisioned IOPSにして、IOPSを1000に設定します。
立ち上がったら、SSHで入ります。
まずEBSをマウントします。
次に、RDSと同じバージョンのmysqlをインストールします。
mysqlを立ち上げます。
新しくインスタンスを立ち上げ、mysql-benchをインストールします。
mysql-benchの使い方は、以下のサイトに詳しく書かれています。
suz-lab: "mysql-bench"でMySQLのベンチマークの比較
RDS
EBS
RDSの方が良い数値のようです。やはり最適化されているみたいですね。
ちなみに、ベンチマーク中のCloudWatchでも性能差が出ていました。
どちらもディスク操作/秒の値です。
1000 IOPSを上回る数値が出ています。
その後、落ち着くと1000で頭打ちになりました。
最初から1000で頭打ちで、ベンチマーク自体もRDSより時間がかかっています。
EBSの方は、設定やチューニングなどでもっとRDSの値に近づけられるのかもしれませんが、RDSならその手間も必要なく簡単に使うことができるということでしょうか。
以上です。
そこで、EBS with PIOPS上のMySQLと、RDS with PIOPSでベンチマークを取ってみました。
RDSの準備
- db.m1.large
- 100GB/1000 IOPS
MySQLインスタンスの起動設定をします。
インスタンスタイプはdb.m1.largeにして、ストレージは100GB、use Provisioned IOPSにチェックをいれて、IOPSを1000に設定します。
あとは手順にしたがって進みます。
EBSの準備
- EC2はm1.largeのEBS Optimized
- EBSは(100GB/1000 IOPS)をマウント
- MySQLのデータディレクトリをEBS上に配置
- なるべく設定をDBパラメータグループに合わせる
準備
EBS VolumesでVolume Sizeを100GiBにして、Volume TypeをProvisioned IOPSにして、IOPSを1000に設定します。
立ち上がったら、SSHで入ります。
まずEBSをマウントします。
# yum install -y xfsprogs # mount /dev/xvdf /mnt/data
次に、RDSと同じバージョンのmysqlをインストールします。
# cd /usr/local/src # curl -OL http://downloads.mysql.com/archives/mysql-5.5/mysql-5.5.27.tar.gz # tar xzvf mysql-5.5.27.tar.gz # cd mysql-5.5.27/ # yum install -y cmake ncurses-devel # cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DENABLED_LOCAL_INFILE=true -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_EXTRA_CHARSETS=all -DWITH_READLINE=OFF # make # make install # cat /etc/my.cnf [mysqld] user=mysql datadir=/mnt/data/mysql socket=/var/lib/mysql/mysql.sock binlog_cache_size = 32768 binlog_format = MIXED innodb_additional_mem_pool_size = 2097152 innodb_buffer_pool_size = 4509715660 innodb_file_per_table = 1 innodb_flush_method = O_DIRECT innodb_log_buffer_size = 8388608 innodb_log_file_size = 134217728 key_buffer_size = 16777216 local_infile = 1 log_output = TABLE log-error = /var/log/mysql/error.log max_binlog_size = 134217728 max_connections = 477 read_buffer_size = 262144 read_only = false read_rnd_buffer_size = 524288 thread_stack = 262144 [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid # cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
mysqlを立ち上げます。
/etc/init.d/mysql start
ベンチマーク用インスタンスの準備
新しくインスタンスを立ち上げ、mysql-benchをインストールします。
mysql-benchの使い方は、以下のサイトに詳しく書かれています。
suz-lab: "mysql-bench"でMySQLのベンチマークの比較
# yum -y install mysql-bench
ベンチマークの実行
# cd /usr/share/sql-bench/ # chmod 755 run-all-tests # chmod 755 compare-results
RDS
# ./run-all-tests --host=rds-iops.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com --server=mysql --cmp=mysql --machine=rds --database=hoge --user=memorycraft --password=xxxxxxxxxx --log
EBS
# ./run-all-tests --host=ec2-46-51-237-207.ap-northeast-1.compute.amazonaws.com --server=mysql --cmp=mysql --machine=ebs --database=hoge --user=memorycraft --password= xxxxxxxxxx --log
比較
# ./compare-results --cmp=mysql The test was run with limits from: mysql The result logs which where found and the options: 1 mysql-ebs : MySQL 5.5.27 2 mysql-rds : MySQL 5.5.27 ===================================================== Operation | 1| 2| |mysql-e|mysql-r| ----------------------------------------------------- Results per test in seconds: | ----------------------------------------------------- ATIS | 31.00| 20.00| alter-table | 28.00| 29.00| big-tables | 16.00| 16.00| connect | 339.00| 345.00| create | 707.00|1003.00| insert |2929.00|2092.00| select | 331.00| 301.00| wisconsin | 65.00| 35.00| ----------------------------------------------------- The results per operation: | ----------------------------------------------------- alter_table_add (100) | 13.00| 14.00| alter_table_drop (91) | 12.00| 14.00| connect (10000) | 26.00| 24.00| connect+select_1_row (10000) | 25.00| 26.00| connect+select_simple (10000) | 24.00| 25.00| count (100) | 9.00| 8.00| count_distinct (1000) | 6.00| 5.00| count_distinct_2 (1000) | 13.00| 13.00| count_distinct_big (120) | 23.00| 14.00| count_distinct_group (1000) | 13.00| 9.00| count_distinct_group_on_key (1000) | 11.00| 9.00| count_distinct_group_on_key_parts (1| 12.00| 9.00| count_distinct_key_prefix (1000) | 5.00| 4.00| count_group_on_key_parts (1000) | 6.00| 6.00| count_on_key (50100) | 78.00| 77.00| create+drop (10000) | 124.00| 160.00| create_MANY_tables (10000) | 117.00| 187.00| create_index (8) | 0.00| 0.00| create_key+drop (10000) | 424.00| 631.00| create_table (31) | 0.00| 0.00| delete_all_many_keys (1) | 25.00| 26.00| delete_big (1) | 0.00| 0.00| delete_big_many_keys (128) | 25.00| 26.00| delete_key (10000) | 12.00| 8.00| delete_range (12) | 3.00| 3.00| drop_index (8) | 1.00| 0.00| drop_table (28) | 0.00| 0.00| drop_table_when_MANY_tables (10000) | 38.00| 20.00| insert (350768) | 695.00| 357.00| insert_duplicates (100000) | 39.00| 39.00| insert_key (100000) | 224.00| 141.00| insert_many_fields (2000) | 6.00| 6.00| insert_select_1_key (1) | 3.00| 3.00| insert_select_2_keys (1) | 4.00| 5.00| min_max (60) | 5.00| 5.00| min_max_on_key (85000) | 39.00| 38.00| multiple_value_insert (100000) | 2.00| 2.00| once_prepared_select (100000) | 45.00| 44.00| order_by_big (10) | 18.00| 18.00| order_by_big_key (10) | 17.00| 17.00| order_by_big_key2 (10) | 16.00| 17.00| order_by_big_key_desc (10) | 17.00| 17.00| order_by_big_key_diff (10) | 17.00| 16.00| order_by_big_key_prefix (10) | 17.00| 17.00| order_by_key2_diff (500) | 1.00| 2.00| order_by_key_prefix (500) | 1.00| 1.00| order_by_range (500) | 1.00| 1.00| outer_join (10) | 11.00| 11.00| outer_join_found (10) | 11.00| 11.00| outer_join_not_found (500) | 9.00| 8.00| outer_join_on_key (10) | 8.00| 7.00| prepared_select (100000) | 52.00| 48.00| select_1_row (100000) | 38.00| 38.00| select_1_row_cache (100000) | 38.00| 38.00| select_2_rows (100000) | 40.00| 48.00| select_big (80) | 17.00| 17.00| select_big_str (10000) | 43.00| 42.00| select_cache (10000) | 49.00| 46.00| select_cache2 (10000) | 55.00| 47.00| select_column+column (100000) | 39.00| 38.00| select_diff_key (500) | 1.00| 0.00| select_distinct (800) | 3.00| 2.00| select_group (2911) | 12.00| 11.00| select_group_when_MANY_tables (10000| 4.00| 5.00| select_join (100) | 0.00| 0.00| select_key (200000) | 99.00| 95.00| select_key2 (200000) | 119.00| 113.00| select_key2_return_key (200000) | 117.00| 116.00| select_key2_return_prim (200000) | 115.00| 110.00| select_key_prefix (200000) | 108.00| 103.00| select_key_prefix_join (100) | 4.00| 4.00| select_key_return_key (200000) | 96.00| 93.00| select_many_fields (2000) | 10.00| 10.00| select_range (410) | 30.00| 33.00| select_range_key2 (25010) | 9.00| 10.00| select_range_prefix (25010) | 9.00| 10.00| select_simple (100000) | 33.00| 34.00| select_simple_cache (100000) | 33.00| 32.00| select_simple_join (500) | 1.00| 1.00| update_big (10) | 29.00| 37.00| update_of_key (50000) | 99.00| 56.00| update_of_key_big (501) | 28.00| 19.00| update_of_primary_key_many_keys (256| 74.00| 86.00| update_with_key (300000) | 596.00| 307.00| update_with_key_prefix (100000) | 198.00| 99.00| wisc_benchmark (114) | 3.00| 3.00| ----------------------------------------------------- TOTALS |4452.00|3852.00| =====================================================
RDSの方が良い数値のようです。やはり最適化されているみたいですね。
ちなみに、ベンチマーク中のCloudWatchでも性能差が出ていました。
どちらもディスク操作/秒の値です。
RDS
その後、落ち着くと1000で頭打ちになりました。
EBS
最初から1000で頭打ちで、ベンチマーク自体もRDSより時間がかかっています。
EBSの方は、設定やチューニングなどでもっとRDSの値に近づけられるのかもしれませんが、RDSならその手間も必要なく簡単に使うことができるということでしょうか。
以上です。
2013年1月15日火曜日
Fluentdってなんじゃ?(datacounter+Growthforecast+RDSでステータスコードの傾向を可視化)
Fluentdではさまざまなデータを構造化することができるので、フロント側の可視化ツールに渡すことも柔軟に対応できます。今回はGrowthForecastという可視化ツールに表示させてみます。
データはApacheのログを使い、表示する内容はHTTPステータスコードの2xx,3xx,4xx,5xxのそれぞれの回数を時系列で表示してみたいと思います。またGrouthForecastはデータのスタックにDBを使用し、デフォルトではsqlite3ですが、今回はRDSのMySQLを利用してみます。
構成は下図のようなイメージです。
管理サーバー(222.222.222.222)
まずは、管理サーバーのEC2インスタンスにGrowthForecastをインストールします。
必須ライブラリをインストールします。
# yum groupinstall "Development Tools" # yum install pkgconfig glib2-devel gettext libxml2-devel pango-devel cairo-devel cpan mysql-devel bitmap-console-fonts
# cpan YAML JSON::XS # curl -kL http://install.perlbrew.pl | bash # cpan App::perlbrew perlbrew init # perlbrew install perl-5.16.0 # perlbrew switch perl-5.16.0
# cd /usr/bin # curl -LO http://xrl.us/cpanm # chmod +x cpanm # cpanm --self-upgrade
GrowthForecastをインストールします。
# cpanm -n http://nomadscafe.jp/pub/GrowthForecast/GrowthForecast-0.34.tar.gz
次に、RDSを設定します。
今回は内容はほぼデフォルトでOKです。
設定したら接続権限を設定します。
RDSのエンドポイントに対して接続し、GRANT文を定義します。
# mysql -u memorycraft growthforecast -pmemorycraft-pass -h growthforecast.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com mysql>GRANT CREATE, ALTER, DELETE, INSERT, UPDATE, SELECT ON growthforecast.* TO 'memorycraft'@'222.222.222.222' IDENTIFIED BY 'memorycraft-pass';
GrowthForacastを起動します。
--with-mysqlオプションをつけると、データベースにMySQLを使用するようになるので、RDSのエンドポイント付きのdsnを渡します。
MYSQL_USER=memorycraft MYSQL_PASSWORD=memorycraft-pass growthforecast.pl --with-mysql dbi:mysql:growthforecast:growthforecast.cwnvl1ncuiwq.ap-northeast-1.rds.amazonaws.com
これで起動されました。
http://222.222.222.222:5125/を見ると以下のように、まだグラフがなにも表示されていません。
WEBサーバー(111.111.111.111)
GrowthForecastはAPI経由でデータを登録するのが基本です。
そしてfluentdには、GrowthForecastにAPI登録する、fluent-plugin-growthforecastというアウトプットフィルタがあるので、
今回はそれを利用します。
また、ログ中のHTTPステータスコードをカウントするために、fluent-plugin-datacounterも利用します。
fluentd(td-agent)のインストールは以前の記事の通りです。
/usr/lib/fluent/ruby/bin/fluent-gem install fluent-plugin-growthforecast /usr/lib/fluent/ruby/bin/fluent-gem install fluent-plugin-datacounter
td-agent.confは以下のように設定します。
tail: Apacheのログを正規表現で構造化
datacounter: statusを2xx,3xx,4xx,5xxに分類して其々をカウント
growthforecast: datacounterの結果をGrowthForecastへ投稿
この場合は、
http://222.222.222.222:5125/api/admintool/httpstatus/グラフ名
への投稿になり、グラフ名には
apache.httpstatus_apache_2xx_count
のように入ります。
のように入ります。
これは
growthforecastのタグ_オリジナルタグ_パターン名_count
の形で、datacounterとgrowthforecastの2つのディレクティブを通過しているためのようです。この名前が冗長であれば、それぞれのディレクティブでremove_prefixなどを使って調整など行えそうです。
<source> type tail format /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<status>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/ time_format %d/%b/%Y:%H:%M:%S %z path /var/log/httpd/access_log tag apache pos_file /tmp/access.log.pos </source> <match apache> type copy <store> type stdout </store> <store> type datacounter tag apache.httpstatus aggregate tag count_key status pattern1 2xx ^2\d\d$ pattern2 3xx ^3\d\d$ pattern3 4xx ^4\d\d$ pattern4 5xx ^5\d\d$ </store> </match> <match apache.httpstatus> type copy <store> type stdout </store> <store> type growthforecast gfapi_url http://222.222.222.222:5125/api/ service admintool section httpstatus name_keys apache_2xx_count,apache_3xx_count,apache_4xx_count,apache_5xx_count </store> </match>
ここまで出来たら、td-agentを起動します。
/etc/init.d/td-agent start
これで設定は完了です。
WEBサーバーのコンテンツに適当にアクセスしてから、管理サーバーのGrowthForecastのアドレス(http://222.222.222.222:5125)を見てみます。
項目が出来ています。このリンクを辿って行くと、、
おお、4つのグラフが表示されています。
ここで、「複合フラグの追加」というリンクをクリックすると4つの項目を1つのグラフに統合した新しいグラフを作ることができます。基本のグラフに加え、2番目以降の系列に残りの項目を追加していくと、以下の様にスタックされたグラグを作成することができます。
datacounterという汎用的すぎるプラグインと、GrowthForecastというとても便利なグラフ化ツールで、いろいろなリソースを可視化してみると、運用の負荷軽減だけではなく、ユーザーの動向などもわかってお得ですね。
以上です。
登録:
投稿 (Atom)















