ラベル rds の投稿を表示しています。 すべての投稿を表示
ラベル rds の投稿を表示しています。 すべての投稿を表示

2013年3月4日月曜日

RDSってなんじゃ?(Free SpaceのAlarmが出たら)

今回はさらっとオプティマイズの話です。
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年2月19日火曜日

RDSってなんじゃ?(MySQL on EBS-PIOPS vs RDS-PIOPS)

最近、Provisioned IOPS(以下PIOPS)という機能がEBSと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パラメータグループに合わせる


準備


 以下のようにm1.largeを選び、EBS-Optimized instanceにチェックを入れます。



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 IOPSを上回る数値が出ています。
その後、落ち着くと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

perlbrewcpanmをインストールします。

# 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';

また、RDSのセキュリティグループも設定します。


また、管理サーバーのEC2の5125(GrowthForecastのデフォルトポート)のInboundに管理者とWEBサーバーから接続できるように追加しておきます。




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というとても便利なグラフ化ツールで、いろいろなリソースを可視化してみると、運用の負荷軽減だけではなく、ユーザーの動向などもわかってお得ですね。
以上です。