読者です 読者をやめる 読者になる 読者になる

まめ畑

ゆるゆると書いていきます

AWS Casual Talks#1を開催しました

AWS

AWS Casual Talks#1を開催しました。
参加登録自体は15分程で枠が埋まってしまい、最終的に210人の方に登録を頂きました。
発表して頂いた方、参加頂いた方ありがとうございました!アンケートも多く集まり次回開催の参考にしようと思います。


AWS Casual Talksは、カジュアルにAWSとかその周辺の普段はあまり出てこない深い(深淵な)事を話す会を作ろうと思ったのが最初で、少し時間が空きましたが1回目を開催出来ました。
AWSの深淵な話からMBaaS・SWFまで幅広い感じで普段あまり一緒にならないテーマでカジュアルな雰囲気で終えることが出来ました。きわどい話もあったのは秘密です。
ただ、参加者管理と懇親会周りでごたついてしまい迷惑をかけてしまったので、次回は改善します。


次回は年明け速いうちにやろうかと考えています。
形式は発表 or 俺の考える〜 かなぁと。

会場だけで出したスライドにも書きましたが、Casualに初心者という意味は全くありません。

AWSさん会場提供ありがとうございました!

会場の天井が!

f:id:con_mame:20131102155505j:plain

EC2・オンプレ環境のMySQLからRDSのマイグレーションがやりやすくなった

本日
Migrate On-Premises MySQL Data to Amazon RDS (and back) | AWS Official Blog
Importing Data to an Amazon RDS MySQL DB Instance with Reduced Downtime - Amazon Relational Database Service
の発表があり、RDSに対して、オンプレミス環境・EC2上で動いているMySQLとのマイグレーションが行い易くなりました。

ただ、常にレプリケーションさせてというわけではなく、移行時に使うという用途です。

オンプレミス環境・EC2上で動いているMySQLとRDSでレプリケーションが可能になりました。
ドキュメントには環境・データサイズ毎のマイグレーションについて書かれているのでご一読下さい。

つまり
f:id:con_mame:20130906121306p:plain
このような構成が取れるようになりました。


RDS(MySQL5.6) -> EC2・オンプレ上のMySQLにもレプリケーションが可能です。
Using Replication to Export MySQL 5.6 Data - Amazon Relational Database Service
をご参照ください。手順は一般的なレプリケーションの設定と同じですが、Security Groupで接続元の開放が必要です。


簡単に試してみたので書いておきます。

こちらを使うことでDBをRDSに移行したいというときに、今までだと、サービスや書き込みを停止させ、dump -> importを行ってと時間がかかりましたが、バックアップなどからRDSを作成し、レプリケーションを追い付かせて、接続先の変更だけを行なうだけで良くなるので、サービスなどを止める時間を大幅に軽減出来ます。

制限

現在RDSでこの機能に対応しているMySQLのバージョンは

  • 5.5.33
  • 5.6.13

のみです。

他のバージョンではストアード・プロシージャーが入っていません。
現在のMySQLの最新版のみという感じです。

RDSはGTIDをONに出来ないので、GTID modeは有効に出来ません。

設定方法

通常のレプリケーションを組むのとあまり変わりは無いですが、

なのですが、RDSでレプリケーションの設定に関しては、通常のCHANGE MASTERやSTART / STOP SLAVEが使えません。
これらは用意されているストアード・プロシージャーを使用します。

 GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.%' IDENTIFIED BY 'slavepass';

接続元のIPアドレスは、VPC内であればRDSが所属しているサブネットのIPアドレスになります。

  • dump / impot
mysqldump -uhoge -p DB | mysql -hrds-database.xxxxxx.ap-northeast-1.rds.amazonaws.com -uhogehoge -pfugafuga -DDB

という感じで流し込めます。

もしくは一旦dumpしてなど。

サイズの大きなDBをimportする際は、一時的にRDSのパラメータグループで、innodbトランザクションやコミット周りの設定を変更しておくことでimportの時間が速くなりますが、安全ではないので、必ずもとに戻しておきます。
時間があるのであればそのままimportで問題ないです。

この時にmasterのbinlog名とポジションを控えておきます。

  • RDS側

mysql.rds_set_external_master - Amazon Relational Database Service
ここがRDS特有なのですが、CHANGE MASTERなどは権限がないためストアード・プロシージャーを使用します。

call mysql.rds_set_external_master('接続先DBのIPアドレス or FQDN',PORT,'USER','PASS','Binlog name',position,0);

最後の0はSSLを使うかどうかです、default 0は使用しない。1で使用する。

成功すると何も出てこないですが、

SHOW SLAVE STATUS;

レプリケーションの状態を確認します。

start / stop slaveは

call mysql.rds_start_replication;

を実行します

+-------------------------+
| Message                 |
+-------------------------+
| Slave running normally. |
+-------------------------+
1 row in set (1.04 sec)

このような感じでエラーがなければレプリケーションが開始されます。

stopは

call mysql.rds_stop_replication;
+---------------------------+
| Message                   |
+---------------------------+
| Slave is down or disabled |
+---------------------------+
1 row in set (1.02 sec)

となっています。


レプリケーションを解除する場合は

call mysql.rds_reset_external_master;

を実行します。
これは、内部でstop slaveとreset slave allを実行しています。

ストアード・プロシージャーの中身が気になる方は

show create procedure mysql.rds_set_external_master;

で見れます。

おまけ

現在

  • 5.5.33
  • 5.6.13

をストアード・プロシージャーが増えており

+-------+-----------------------------------+-----------+--------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db    | Name                              | Type      | Definer            | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+-------+-----------------------------------+-----------+--------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| mysql | rds_collect_global_status_history | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_disable_gsh_collector         | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_disable_gsh_rotation          | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_enable_gsh_collector          | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_enable_gsh_rotation           | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_external_master               | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_kill                          | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_kill_query                    | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_next_master_log               | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_reset_external_master         | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_rotate_general_log            | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_rotate_global_status_history  | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_rotate_slow_log               | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_set_configuration             | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_set_external_master           | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_set_gsh_collector             | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_set_gsh_rotation              | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_show_configuration            | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_skip_repl_error               | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:33 | 2013-09-06 01:48:33 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_start_replication             | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
| mysql | rds_stop_replication              | PROCEDURE | rdsadmin@localhost | 2013-09-06 01:48:39 | 2013-09-06 01:48:39 | DEFINER       |         | utf8                 | utf8_general_ci      | latin1_swedish_ci  |
+-------+-----------------------------------+-----------+--------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+

となっております。

対応していないバージョンのMySQLをRDSで使っている場合は、ModifyからバージョンをUpdateしたタイミングで作成されます。


レプリケーションを操作したログは

 select * from mysql.rds_history;
+---------------------+-----------------------+-------------------+---------------+--------------+-------------+--------------+------------------+----------------+------------+
| action_timestamp    | called_by_user        | action            | mysql_version | master_host  | master_port | master_user  | master_log_file  | master_log_pos | master_ssl |
+---------------------+-----------------------+-------------------+---------------+--------------+-------------+--------------+------------------+----------------+------------+
| 2013-09-06 01:49:01 | rdsadmin@localhost    | enable set master | 5.6.13        | NULL         |        NULL | rdsrepladmin | NULL             | NULL           |       NULL |
| 2013-09-06 01:58:57 | hogehoge@xxx.xxx.xxx.xxx | set master        | 5.6.13        | xxx.xxx.xxx.xxx |        3306 | repl         | mysql-bin.000001 | 1061           |          0 |
| 2013-09-06 01:59:30 | hogehoge@xxx.xxx.xxx.xxx | start slave       | 5.6.13        | NULL         |        NULL | NULL         | NULL             | NULL           |       NULL |
| 2013-09-06 01:59:55 | hogehoge@xxx.xxx.xxx.xxx | stop slave        | 5.6.13        | NULL         |        NULL | NULL         | NULL             | NULL           |       NULL |
| 2013-09-06 02:00:55 | hogehoge@xxx.xxx.xxx.xxx | start slave       | 5.6.13        | NULL         |        NULL | NULL         | NULL             | NULL           |       NULL |
+---------------------+-----------------------+-------------------+---------------+--------------+-------------+--------------+------------------+----------------+------------+

このテーブルに追加されていきます。

レプリケーションの状態は

select * from mysql.rds_replication_status;
+---------------------+-----------------------+-------------+---------------+--------------+-------------+
| action_timestamp    | called_by_user        | action      | mysql_version | master_host  | master_port |
+---------------------+-----------------------+-------------+---------------+--------------+-------------+
| 2013-09-06 04:26:32 | hogehoge@xxx.xxx.xxx.xxx | start slave | 5.6.13-log    | xxx.xxx.xxx.xxx |        3306 |
+---------------------+-----------------------+-------------+---------------+--------------+-------------+

を事項すると状態がとれます。

レプリケーションのエラーが起こった場合は、

call mysql.rds_skip_repl_error

でSET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;が実行されます。

レプリケーションのエラーは
f:id:con_mame:20130906134319p:plain
とManagement Consoleにも表示されます。

こういうのも出来ます

EC2やオンプレDB -> RDS -> ReadReplica

こちらは、上記の手順でレプリケーションを組んだ後にRRを作成するだけです。
f:id:con_mame:20130906121303p:plain

まとめ

RDSへのマイグレーションが今までよりも行いやすくなりました。サイズの大きなDBのdumpデータをS3にuploadして、S3から直接import出来ると便利だなぁと思いました。

しかし、あくまでマイグレーション用かなという感じで、Multi-AZ配置した場合にfailoverが行わた時や、Promoted Readreplicaについてはまだ検証していませんが、接続元のIPアドレスも変わりますし、レプリケーション情報も同期されていないと思うので、通常用途では検証の余地があるかと思います。
一時的に集計などで使う場合に簡単に状況に応じてスペックが変えやすいので、そういう場合は常にレプリケーションさせて置いていいかもしれません。

また、replicate-do-dbは設定出来ないので、既存のDBの一部テーブル・DBだけを移行用にレプリケーションというのが出来ないので、これが出来るようになると更に便利になるかと思います。

ElastiCache Redis Engineのベンチマークともろもろ

AWS redis ElastiCache

Amazon Web Services Blog: Amazon ElastiCache - Now With a Dash of Redis
で本日ElastiCacheでRedisが使えるようになりました。今まではmemcachedだけでした。
(同時にAmazon Web Services Blog: More Database Power - 20,000 IOPS for MySQL With the CR1 Instance も発表されています)

f:id:con_mame:20130905103345p:plain

基本的なこと

機能

  • Replication GroupsによるRedisレプリケーションのサポート
  • Replication Groupsは1ノード毎にSlaveとなる、Endpointは各ノード毎にアサインされる
    • Masterへは統一のEndpoitが与えられ、Read replicaをmasterにpromoteしてもendpointの変更は必要ない
    • slaveは各ノードへアクセスする必要がある
    • slaveはread only mode
  • S3に配置したRDBファイルからノードを作成可能
    • 現在オンプレ環境やEC2インスタンス上で使ってるRedisの中身をそのまま移行可能
    • とても楽でした
  • 現在のところRedis2.6.13
  • Maintenance Windowがある

system

redis_version:2.6.13
redis_git_sha1:00000000
redis_git_dirty:0
redis_mode:standalone
os:Amazon ElastiCache
arch_bits:64
multiplexing_api:epoll
gcc_version:0.0.0
process_id:1
run_id:5d523a3bd3f8a8ef0ce2dc617e861c3122a43f56
tcp_port:6379
uptime_in_seconds:3118
uptime_in_days:0
hz:10
lru_clock:1264120

RDBファイルのインポート

既存の環境から移行する場合は、RDBファイルをS3からインポートすることで簡単に環境を以降可能です。

f:id:con_mame:20130905172103p:plain

性能

性能は格納するデータサイズ・タイプなどによって変わるので使用前には必ずベンチマークをとって、必要な性能が出ているかや、必要なノード数を出しておきましょう。

以下の検証はとある本番環境を模擬したものです。

検証項目

ノード単体の基本性能
  • requests per second
  • 100,000 keys / 1000 clients / 100,000,000 variables / 75 bytes
cache.m1.small cache.m1.medium cache.m1.large cache.m1.xlarge cache.m2.xlarge cache.m2.2xlarge cache.m2.4xlarge cache.c1.xlarge
SET 10738.83 17190.99 22537.6 16488.05 18964.54 19512.2 18839.49 19774.57
GET 11944.58 17208.74 22187.71 17975.91 20108.59 19394.88 18467.22 19413.71
INCR 10894.43 17364.13 20350.02 18406.04 20635.57 18740.63 18274.85 19735.54
LPUSH 11298.16 18978.93 22810.22 19383.6 20271.64 19782.39 18765.25 21413.28
LPOP 11189.44 17649.13 21682.57 19409.94 18907.17 19615.54 18484.29 20263.42
SADD 10986.6 17349.06 20275.75 18508.24 18712.58 18399.26 17674.09 19535.07
SPOP 10672.36 18093 21939.45 20020.02 19531.25 19040.37 18545.99 20316.95
LRANGE_100 4383.85 8798.17 8550.66 8817.56 8726.77 8597.71 8690.36 8901.55
LRANGE_300 1365.32 2988.11 2911.63 2253 3059.41 2957.88 2912.48 3095.02
LRANGE_500 747.76 1978.67 1995.41 2040.15 1965.56 1837.02 1725.63 1623.59
LRANGE_600 473.79 1524.67 1522.93 1591.98 1513.34 1482.27 1543.83 1254.25
MSET 5904.58 15857.91 11161.96 18005.04 16871.94 18175.21 18201.67 17649.13

f:id:con_mame:20130905103302p:plain

latency

  • milli seconds
  • 10,000 samples
cache.m1.small cache.m1.medium cache.m1.large cache.m1.xlarge cache.m2.xlarge cache.m2.2xlarge cache.m2.4xlarge cache.c1.xlarge
latency min 0 0 0 0 0 0 0 0
latency max 38 23 16 11 5 7 15 8
latency avg 0.77 0.38 0.34 0.31 0.4 0.34 0.37 0.37

f:id:con_mame:20130905103413p:plain

インスタンスタイプによるlatencyの差異はほとんど無い

EC2インスタンス上に構築してあるRedis<->ELB間は0.02-0.08 milli seconds. EC2->ELBもそのくらいなので、EC2->ElastiCacheは少しlatency高め

Cache Replicaの追加

  • Masterに大量にデータが格納されている時にCache Replicaを作成した場合つまりが起こるか
  • cache.m1.small / 1GB
  • replica 1
GET: 12482.84 requests per second
GET: 10188.49 requests per second
GET: 11746.74 requests per second
GET: 14409.22 requests per second
GET: 6359.71 requests per second <- bgsave start
GET: 7206.17 requests per second
GET: 8850.34 requests per second
GET: 13363.62 requests per second <- online
  • replica 3
GET: 10001.00 requests per second <- bgsave start 1台め
GET: 9691.80 requests per second
GET: 9633.91 requests per second
GET: 10574.18 requests per second
GET: 12965.12 requests per second
GET: 11664.53 requests per second
GET: 6945.89 requests per second <- bgsave start 2台 / replication
GET: 8538.98 requests per second
GET: 9387.03 requests per second
GET: 10625.86 requests per second  <- online

bgsaveからtransfer完了してonline statusになるまで若干のつまりがあった。転送に関しては、一気にreplicaをぶら下げるとぶら下げた台数全てに全データを一気に転送するため並列度が高いと時間がかかったが数%の劣化といったところだった。これはmasterが持っているデータ量による。

cache.m2.4xlargeで10GBのデータのrdb_last_bgsave_time_secは約120sec。1台のreplicaへの転送は50-60sec以内 (1Gbps以上出てる)

Paramater Group / node type

CACHENODETYPESPECIFICPARAMETER  maxmemory  system  integer  false  2.6.13
      CACHENODETYPESPECIFICVALUE  cache.c1.xlarge   6501171200
      CACHENODETYPESPECIFICVALUE  cache.m1.large    7025459200
      CACHENODETYPESPECIFICVALUE  cache.m1.medium   3093299200
      CACHENODETYPESPECIFICVALUE  cache.m1.small    943718400
      CACHENODETYPESPECIFICVALUE  cache.m1.xlarge   14889779200
      CACHENODETYPESPECIFICVALUE  cache.m2.2xlarge  35022438400
      CACHENODETYPESPECIFICVALUE  cache.m2.4xlarge  70883737600
      CACHENODETYPESPECIFICVALUE  cache.m2.xlarge   17091788800
      CACHENODETYPESPECIFICVALUE  cache.t1.micro    142606336
  • 共有
CACHEPARAMETER  activerehashing                                 yes           system  string   true   2.6.13
CACHEPARAMETER  appendfsync                                     everysec      system  string   true   2.6.13
CACHEPARAMETER  appendonly                                      no            system  string   true   2.6.13
CACHEPARAMETER  client-output-buffer-limit-normal-hard-limit    0             system  integer  true   2.6.13
CACHEPARAMETER  client-output-buffer-limit-normal-soft-limit    0             system  integer  true   2.6.13
CACHEPARAMETER  client-output-buffer-limit-normal-soft-seconds  0             system  integer  true   2.6.13
CACHEPARAMETER  client-output-buffer-limit-pubsub-hard-limit    33554432      system  integer  true   2.6.13
CACHEPARAMETER  client-output-buffer-limit-pubsub-soft-limit    8388608       system  integer  true   2.6.13
CACHEPARAMETER  client-output-buffer-limit-pubsub-soft-seconds  60            system  integer  true   2.6.13
CACHEPARAMETER  client-output-buffer-limit-slave-hard-limit     268435456     system  integer  false  2.6.13
CACHEPARAMETER  client-output-buffer-limit-slave-soft-limit     67108864      system  integer  false  2.6.13
CACHEPARAMETER  client-output-buffer-limit-slave-soft-seconds   60            system  integer  false  2.6.13
CACHEPARAMETER  databases                                       16            system  integer  true   2.6.13
CACHEPARAMETER  hash-max-ziplist-entries                        512           system  integer  true   2.6.13
CACHEPARAMETER  hash-max-ziplist-value                          64            system  integer  true   2.6.13
CACHEPARAMETER  list-max-ziplist-entries                        512           system  integer  true   2.6.13
CACHEPARAMETER  list-max-ziplist-value                          64            system  integer  true   2.6.13
CACHEPARAMETER  lua-time-limit                                  5000          system  integer  false  2.6.13
CACHEPARAMETER  maxclients                                      65000         system  integer  false  2.6.13
CACHEPARAMETER  maxmemory-policy                                volatile-lru  system  string   true   2.6.13
CACHEPARAMETER  maxmemory-samples                               3             system  integer  true   2.6.13
CACHEPARAMETER  set-max-intset-entries                          512           system  integer  true   2.6.13
CACHEPARAMETER  slave-allow-chaining                            no            system  string   false  2.6.13
CACHEPARAMETER  slowlog-log-slower-than                         10000         system  integer  true   2.6.13
CACHEPARAMETER  slowlog-max-len                                 128           system  integer  true   2.6.13
CACHEPARAMETER  tcp-keepalive                                   0             system  integer  true   2.6.13
CACHEPARAMETER  timeout                                         0             system  integer  true   2.6.13
CACHEPARAMETER  zset-max-ziplist-entries                        128           system  integer  true   2.6.13
CACHEPARAMETER  zset-max-ziplist-value                          64            system  integer  true   2.6.13

masterノードに大量のデータが入っている場合、一気にslaveをぶら下げると高負荷環境ではredisのbuffer(client-output-buffer-limitのあたり)に少し気を使うとよいです。

使えないコマンド

  • rename-commandされてる
  • CONFIG SET / GET
  • BGSAVE / SAVE
  • SLAVEOF などなど制御系
  • LASTSAVEは使える
* Replication
role:slave
master_host:xxx.9xxxx.0001.apne1.cache.amazonaws.com
master_port:6379
master_link_status:down

ファイル書き出し

INFOは使えるが、CONFIG GETが使えないのでParameter Groupで設定出来る値以外は参照できない。SAVEが参照出来ないがSAVEのタイミングは調整されているのだろうか、AOFファイルの肥大化に対応(auto-aof-rewrite-min-sizeとか)できているかは調べ中。

書き出しタイミングは調査中。BGREWRITEAOFコマンドは使えない。

Replication Group

Replication Groups and Read Replicas - Amazon ElastiCache

  • RedisのMaster-Slave構成
  • MasterでINFOを除くと、172.x.x.xのネットワークに属してる事がわかる(slaveのIPアドレス)
  • SlaveではMasterはドメイン名で指定されている
  • ElastiCacheのRedisにEC2からつなげてSlave作ることも出来る (逆は無理)
  • Readonly modeになっている
  • 削除時
    • Read replica削除時はRead Replicaから削除していく
    • masterノードを削除する前に、Replication Groupを削除する
    • Replication Group消したら自動でMaster nodeが削除される (残せないのか。。)

Masterの様子

* Replication
role:master
connected_slaves:5
slave0:172.16.xxx.xxx,6379,online
slave1:172.16.xxx.xxx,6379,online
slave2:172.16.xxx.xxx,6379,online
slave3:172.16.xxx.xxx,6379,online
slave4:172.16.xxx.xxx,6379,online

Slaveの様子

# Replication
role:slave
master_host:xxxxx.xxx.0001.internal.apne1.cache.amazonaws.com   <- Replication Group名がprefix
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_priority:100
slave_read_only:1
connected_slaves:0

Replication Groupを作成すると、
f:id:con_mame:20130905122136p:plain
の様な感じで、AZを跨いで作成することも可能。また、共有のMaster nodeへのendopointが発行され、アプリケーションからはこちらにアクセスをすると、Masterが切り替わっても意識することなく接続が可能になる。
promoteを押下して、modifyが終わっても、2−3分はレスポンスが3秒近くかかる状態になる。この間はmaster statusはdown
Slaveノードへのアクセスは各ノード名を直接指定しないといけないのでバランシングしたほうがアプリケーションからslaveのdownを意識しないでよい。
各slaveはReplication Groupの内部用共通endpointを使用していて、こちらはユーザ側からはDNSで名前解決が出来ません。

masterノードへは

replication-group-hoge.xxxx.ng.0001.apne1.cache.amazonaws.com. 15 IN CNAME xxx.xxx.0001.apne1.cache.amazonaws.com.
xxx.xxx.0001.apne1.cache.amazonaws.com. 15 IN A xxx.xxx.xxx.xxx

と、CNAMEでmasterノードが切り替わるようになっています。その為、どのAWSサービスでもそうですが、こちらもIPアドレスを長時間キャッシュしておくと接続できなくなる事があります。

監視

f:id:con_mame:20130905122612p:plain
このような感じで、サーバリソースの他に、redisへ発行されたコマンドの種類の統計やreplicationの状態も監視されています。

replicationの状態は

> get "ElastiCacheMasterReplicationTimestamp"
"2013-09-05T01:25:01.001Z"

このような感じでmaster nodeでsetした時間を読み出してラグを見ているようです。

おまけ

  • Fork time in different systems

http://redis.io/topics/latency

Linux beefy VM on VMware 6.0GB RSS forked in 77 milliseconds (12.8 milliseconds per GB).
Linux running on physical machine (Unknown HW) 6.1GB RSS forked in 8
0 milliseconds (13.1 milliseconds per GB)
Linux running on physical machine (Xeon @ 2.27Ghz) 6.9GB RSS forked into 62 millisecodns (9 milliseconds per GB).
Linux VM on 6sync (KVM) 360 MB RSS forked in 8.2 milliseconds (23.3 millisecond per GB).
Linux VM on EC2 (Xen) 6.1GB RSS forked in 1460 milliseconds (239.3 milliseconds per GB).
Linux VM on Linode (Xen) 0.9GB RSS forked into 382 millisecodns (424 milliseconds per GB).

AWSでRedisを動かすのはforkがちょっとネック。ElastiCacheもxenの上で動いてると思われるので若干の影響は受けているはず。

感想

RDBファイルのインポートやMaster nodeへの単一endpointは嬉しいのですが、Slaveのバランスを行なうendpointやSAVEの間隔などユーザが変更出来るパラメータの追加などを期待しています!

SlaveのMulti-AZ配置も良かったです。

また、Maintenance Windowがあるので繋がらない時間があることもお忘れなく。

Redshiftのことを話してきました

AWS Redshift

先日、cloudpack Night #7 - A New Hope - on ZusaarでRedshiftの話をしてきました。

今回のcloudpack nightは各社若手新卒のLTの初々しい感じで始まって、懇親会までAWSの深い話が続いていました。

そこで、Redshiftの利用事例を話してきました。
会場にはRedshiftユーザの方が少なかったのですが、それ以上にWLM周りを知っている方が少なかったです…特にdefault 5並列のため並列度のベンチマークをとる時に6並列を超えた当たりから性能が悪くなっていくというのはこちらに起因していることが多いです。

他に、ProductionとDevelopmentを同一クラスタで使う場合の事も話しました。

少し直したスライドを乗っけておきます。

USTはこちら


Video streaming by Ustream


時間の都合で掲載出来なかった、WLMの状態を管理・取得するためのシステムテーブルが用意されています。
Monitoring workload management - Amazon Redshift
こちらのページに各システムテーブルの詳細とクエリサンプルが乗っているので、WLMの状態管理にご活用下さい。


次は9/26 京セラドームでアンカンファレンスのモデレータをするので是非お越しください!JAWS FESTA Kansai 2013

そして、AWS Casual Talkも企画しているので、スピーカを募集しています!

スタッフの皆さんありがとうございました!次回も是非!

RedshiftのIAM PolicyとWLM

AWS Redshift

先日、Redshiftの管理面 - まめ畑 でRedshiftの管理周りをざっくり書いたのですが、その中でIAM Policyの事も書いていました。

今日、IAM Policyの「Redshift readonly access」ではManagement ConsoleでQuery情報が取得できなくなっていました。

Query情報は
f:id:con_mame:20130731155816p:plain
の様な、PerformanceタブやQueriesタブの中で、リソースの使用状況や実行計画、クエリ毎のリソース使用状況を確認出来るものです。

もともと、redshift:Describe* ではQuery情報を見ることが出来ず、redshift:get*を与えなければいけなかったのですが、急に「User: arn:aws:iam::xxx:user/xxx is not authorized to perform: redshift:ViewQueriesInConsole 〜」
というエラーが出てQuery情報だけが参照できなくなりました。

Forumとdocumentにも掲載が現在は無いのですが、現在は以下の様なポリシーを設定することで、RedshiftのQueryやPerformance・クラスタ状態を参照することが出来ます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "redshift:Describe*",
        "redshift:ViewQueriesInConsole",
        "ec2:DescribeAccountAttributes",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSubnets",
        "ec2:DescribeVpcs",
        "ec2:DescribeInternetGateways",
        "sns:Get*",
        "sns:List*",
        "cloudwatch:Describe*",
        "cloudwatch:List*",
        "cloudwatch:Get*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

こちらは、cloudwatchやsnsにも参照権限を与えた場合です。

変更としては
"redshift:get*"

"redshift:ViewQueriesInConsole"
に変わりました。

Performanceは見せたいけど、クエリまでは見せたくないとかそういうために分けた気がします。
DescribeとViewと揃っていないのが気になりますが、用途は一応表してるかな…


他にもアナウンスはありませんでしたが、WLMを現在開くとQueue毎にTimeoutが設定出来るようになっています。リソースを取られたくないクエリを投げるQueueはTimeoutを短めにすることで、前よりはリソース割り当てに幅が出たかなという印象です。
f:id:con_mame:20130731155821p:plain

Redshiftのworkload management

AWS Redshift

Redshiftのパフォーマンス検証記事は見かけるのですが、WLMに関して言及されているものをみないのと、ちょっと複雑なのでまとめておきます。

管理面については Redshiftの管理面 - まめ畑を参照下さい。

WLMの重要性

DWHでは往々にして、実行時間のかかるクエリからサクッと終わるもの、バッチがガリガリと長時間かけて実行するクエリまで様々なタイプのクエリが投げ込まれます。

これらクエリはリソースをガッツリ割り当ててさっさと思ってほしいものから、重要でないから気長に実行をまてるものまで要件は様々です。これら、クラスタリソースを管理してクエリ毎に割り当てることで1つのクラスタ内で様々な種類・用途のクエリを扱いやすくすることが出来ます。

Redshiftでは標準で1キュー・5並列とParameter Groupで設定されています。この状態では実行時間が長くかかるクエリが5本実行されている状態で、数秒で終わるようなクエリが続いて実行されると、この早く終るはずのクエリは先行している5本のクエリのうち1本が終わるまで実行されないため、結果として数秒で終わるはずが数時間たたないと結果が帰ってこないとか、タイムアウトしてしまうということになってしまいます。

Redshiftでいうworkload management(WLM)とは

ドキュメントはImplementing Workload Management - Amazon Redshift

WLMはクラスタに対して実行されるクエリをキューで管理するものです。Redshiftでは、ユーザグループ・クエリグループ毎にキューを設定することができます。

それぞれのグループは以下のまとまりになっています。

  • ユーザグループ: 接続アカウントに対して
  • クエリグループ: 実行するSQLに対して

このグループ毎にクエリが実行される際の並列度を制御することが可能です。こちらのキューは標準では1つ設定されており、並列度は5となっていますので、同時に5つのSQLを実行することが可能です。最大で8つのキューを定義することが可能で、全てのキューの並列度の合計は15までとなっています。この8つのキューの1つはデフォルトキューに設定しないといけないため、グループを割り当てることが出来るのは7つとなります。

また、暗黙的に並列度1のSuperuserキュー(クエリグループ)というものが存在しますが、こちらはデバッグ用など管理用に使うために割り当てないことが推薦されます。Superuserクエリグループを設定するにはsuperuserでログインしている必要があります。

Redshiftではキューに対してクラスタリソースの配分などの優先度をつけることが出来ないため、メモリ・CPUなどの計算機資源は全てのキューで実行されているクエリに対して等しく割り当てられます。擬似的に優先度をつけるという意味では、キュー毎に並列度を変え、クエリの実行時間や用途毎に分類するくらいです。

キュー毎に優先度をつける事ができ、優先度でCPUなどのリソース割り当て優先順位が付けられれば実行時間が長いクエリは優先度低くなどの使い方も出来るので、こちらは将来の機能拡張に期待したいところです。

Redshiftでの設定

Redshiftでは、Management ConsoleのRedshift Parammeter Groupで設定を行います。設定項目名はwlm_json_configurationです。こちらにjson形式で設定します。
しかし、Editのタブ内でこちらの項目を編集することが出来ません。設定は隣のWLMタブで行います。

f:id:con_mame:20130718213907p:plain

こちらのタブを開くと
f:id:con_mame:20130718222054p:plain

このような形で並列度と各グループ名を割り当てます。最後の1つがデフォルトキューとなるため、ユーザグループ・クエリグループ共に何も入れてはいけません。

こちらで設定すると、

[{"user_group":["fast"],"query_group":[],"query_concurrency":5},{"user_group":["middle"],"query_group":[],"query_concurrency":2},{"user_group":[],"query_group":["batch"],"query_concurrency":1},{"user_group":[],"query_group":[],"query_concurrency":3}]

というjsonファイルがwlm_json_configurationにセットされます。

default.redshift-1.0がデフォルトで用意されているParameter Groupですがこちらは全ての項目が編集することが出来ないので、独自にParameter Groupを作って、そちらを変更します。既に起動しているクラスタにParameter Groupの変更を適用するとクラスタrebootが必要になるので、運用中の場合は注意が必要です。Parameter Groupの箇所がpending-rebootになっています。普段はin-syncです。

キューの使用方法

  • ユーザグループ

以下のクエリでユーザをグループに追加することが可能です。
1. グループ作成と同時にユーザ追加 (with以下はオプション)
2. ユーザ作成時にグループに指定 (既に存在するグループに対して)
3. 既存のグループにユーザ追加

1# create group fast with user user1, user2;
2# create user user3 in fast,middle password 'hoge';
3# alter group fast add user user3, user4, user5;  

Redshiftに接続するユーザでキューを切り替えるという方法です。速いクエリを発行するアプリケーション・バッチ・長時間かかるクエリ用といった感じでアカウントを切り替えて使うことが出来ます。

  • クエリグループ

こちらは、クエリを発行するタイミングで、set query_group / reset query_group で囲まれている間、指定したクエリグループが使用されます。

もし、存在しないクエリグループを指定した場合は影響を及ぼしません。

set query_group to 'batch';
select count(*) from big_table;
select user_name, city, age from hoge_table order by age desc limit 100; 
reset query_group;

アカウントは一つで、クエリを投げる段階で個々に指定するという感じです。

キューの適用規則

キューの適用規則についてはドキュメントにフローチャートが乗っています。

f:id:con_mame:20130718213908p:plain


1. Superuserでログインしていて、クエリグループでSuperuserを指定している場合はSuperuerキューで実行
2. ログインユーザがユーザグループに含まれている場合は、一番最初にマッチするユーザグループで指定されているキューで実行
3. ユーザグループに存在しておらず、クエリグループが指定されている場合は、最初にマッチしたクエリグループのキューで実行
4. どれにも当てはまらない場合はデフォルトキューで実行


つまり、ユーザグループがクエリグループよりも優先されます。

例えば、user1 が fastユーザグループに入っていて、クエリパラメータとして batchを指定した場合はどうなるでしょうか。その場合はfastユーザグループで指定されているキューで実行されます。

どのキューでクエリが実行されているかなどの情報をwlm system tableから取得することが可能です。詳細はMonitoring Workload Management - Amazon Redshiftのドキュメントに書かれています。

service_classがWLM設定画面で指定した際のQueue番号です。

キューの並列度

キューの並列度の設定については、運用しながらクラスタリソースの使用状況を見ながら変えていくのが最初はいいですが、変更にはクラスタrebootが必要なため、運用前にある程度想定クエリで様子をみて調整しておくと後で困らないと思います。

実行時間が短いクエリ用に多めに並列度を設定したキューを割り当て、長い時間実行されリソースも消費するクエリ用には並列度が低いキューを割り当てることで、クラスタリソースの使用量をある程度制限出来ます。

しかし、キューを多くするとクラスタ全体として並列度も上がってしまうため、1つのクエリに割り当てられるクラスタリソースが減ってしまうので注意が必要です。

まとめ

WLMでキューを設定することで、クラスタリソースの使用をある程度クエリに分配することが可能になります。実際は実行されているクエリそれぞれに等しくリソースが割り当てられるため、キューの細分化で全体の並列度の増加にならないように気をつけることが大切です。

また、パフォーマンステストを行う際に、同時実行数もパラメータに含める場合は、WLMの設定を変えないと、6同時接続・実行以上になった場合に6本目からは先の5本のクエリのうち1本が終わるまで待たされている状態になるので、レスポンスタイムに待ちの時間も含まれてしまいます。こちらも注意です。

おまけ

Redshiftはleader nodeで実行計画が作られた後、C++のコードに変換されコンパイルされたものが各データノードに配布され実行されますが、このcompiled comdeは2回目以降はキャッシュがあればそれが使われるので、1回目だけオーバヘッドが乗るためクエリの実行時間が長くなります。パフォーマンステストでは1回めのクエリの結果は含めない方がよいとRedshiftのドキュメントでも触れられています。

また、こちらのcompiled codeですが、 JDBCODBCpsql (libpq)で接続した場合はそれぞれ別の物が作られます。JDBCで接続して1回クエリを実行し、全く同じクエリをpsqlで接続したて実行した場合はそれぞれ別々のcompiled codeが作られるため、2回めの実行ですが、コンパイルのオーバヘッドがかかるため実行が遅くなります。

RDSがMySQL5.6対応したのでベンチマークをとってみた

AWS RDS MySQL

先日
Amazon Web Services Blog: MySQL 5.6 Support for Amazon RDS
で、RDSがMySQL5.6対応(現在は5.6.12が最新)したということで簡単にベンチマークをかけてみました。

RDSはメジャーバージョンアップが簡単に出来るようになりましたが、5.6へのUpgradeはまだ対応していないので、dump->version up->importする必要があります。

今回RDSがMySQL5.6対応した際に5.6から導入されたMemcached Pluginが使用出来るようになったり、Binlogへのアクセス、innodbの新オプションが使えるようになっています。innodb_buffer_pool_dump_at_shutdownやGTID modeも有効に出来ます。

5.5からあるParameter Groupの中での変更点は

  • innodb_flush_methodがO_DIRECTからfdatasync
  • log_slave_updatesがON

くらいです。
GTID mode OFF
explicit_defaults_for_timestampはONになっています


以前
MySQL5.5 と MySQL5.6 と RDS - まめ畑
Amazon RDSで3TB 30,000IOPSのディスクが使えるようになった - まめ畑
ベンチマークを取りましたので、今回はRDS MySQL5.6.12 2,000IOPS / 15,000IOPSで計測してみました。ベンチマーク条件は以前と同一です。あくまで1ベンチマークの結果としてお考え下さい。

The result logs which where found and the options:
 1 mysql-rds_5.6_2000                              : MySQL 5.6.12 log
 2 mysql-rds_5.6_15000                             : MySQL 5.6.12 log

=====================================================
Operation                           |      1|      2|
                                    |mysql-r|mysql-r|
-----------------------------------------------------
Results per test in seconds:                        |
-----------------------------------------------------
ATIS                                |  23.00|  21.00|
alter-table                         |  34.00|  30.00|
big-tables                          |  13.00|  13.00|
connect                             | 315.00| 310.00|
create                              |4421.00|3650.00|
insert                              |2221.00|2159.00|
select                              | 275.00| 272.00|
wisconsin                           |  45.00|  43.00|
-----------------------------------------------------
The results per operation:                          |
-----------------------------------------------------
alter_table_add (100)               |  17.00|  15.00|
alter_table_drop (91)               |  15.00|  14.00|
connect (10000)                     |  18.00|  18.00|
connect+select_1_row (10000)        |  22.00|  22.00|
connect+select_simple (10000)       |  22.00|  21.00|
count (100)                         |  11.00|  11.00|
count_distinct (1000)               |   4.00|   4.00|
count_distinct_2 (1000)             |   7.00|   7.00|
count_distinct_big (120)            |   9.00|   9.00|
count_distinct_group (1000)         |   8.00|   7.00|
count_distinct_group_on_key (1000)  |   5.00|   6.00|
count_distinct_group_on_key_parts (1|   8.00|   7.00|
count_distinct_key_prefix (1000)    |   3.00|   2.00|
count_group_on_key_parts (1000)     |   6.00|   6.00|
count_on_key (50100)                |  73.00|  73.00|
create+drop (10000)                 | 513.00| 254.00|
create_MANY_tables (10000)          | 158.00| 156.00|
create_index (8)                    |   0.00|   0.00|
create_key+drop (10000)             |3386.00|3152.00|
create_table (31)                   |   1.00|   0.00|
delete_all_many_keys (1)            |  10.00|  11.00|
delete_big (1)                      |   0.00|   0.00|
delete_big_many_keys (128)          |  10.00|  11.00|
delete_key (10000)                  |   9.00|   9.00|
delete_range (12)                   |   3.00|   3.00|
drop_index (8)                      |   1.00|   0.00|
drop_table (28)                     |   1.00|   0.00|
drop_table_when_MANY_tables (10000) | 357.00|  81.00|
insert (350768)                     | 490.00| 458.00|
insert_duplicates (100000)          |  43.00|  42.00|
insert_key (100000)                 | 161.00| 156.00|
insert_many_fields (2000)           |   5.00|   5.00|
insert_select_1_key (1)             |   2.00|   2.00|
insert_select_2_keys (1)            |   3.00|   3.00|
min_max (60)                        |   5.00|   5.00|
min_max_on_key (85000)              |  42.00|  41.00|
multiple_value_insert (100000)      |   1.00|   1.00|
once_prepared_select (100000)       |  47.00|  47.00|
order_by_big (10)                   |   9.00|   8.00|
order_by_big_key (10)               |   8.00|   9.00|
order_by_big_key2 (10)              |   8.00|   8.00|
order_by_big_key_desc (10)          |   9.00|   8.00|
order_by_big_key_diff (10)          |   7.00|   8.00|
order_by_big_key_prefix (10)        |   8.00|   8.00|
order_by_key2_diff (500)            |   1.00|   1.00|
order_by_key_prefix (500)           |   0.00|   1.00|
order_by_range (500)                |   1.00|   1.00|
outer_join (10)                     |  12.00|  11.00|
outer_join_found (10)               |  11.00|  11.00|
outer_join_not_found (500)          |   9.00|   9.00|
outer_join_on_key (10)              |   8.00|   8.00|
prepared_select (100000)            |  52.00|  52.00|
select_1_row (100000)               |  41.00|  41.00|
select_1_row_cache (100000)         |  41.00|  41.00|
select_2_rows (100000)              |  42.00|  40.00|
select_big (80)                     |   7.00|   7.00|
select_big_str (10000)              |  13.00|  12.00|
select_cache (10000)                |  49.00|  50.00|
select_cache2 (10000)               |  49.00|  49.00|
select_column+column (100000)       |  43.00|  42.00|
select_diff_key (500)               |   0.00|   0.00|
select_distinct (800)               |   2.00|   2.00|
select_group (2911)                 |  10.00|  10.00|
select_group_when_MANY_tables (10000|   7.00|   7.00|
select_join (100)                   |   0.00|   0.00|
select_key (200000)                 | 102.00| 101.00|
select_key2 (200000)                | 106.00| 107.00|
select_key2_return_key (200000)     | 102.00| 102.00|
select_key2_return_prim (200000)    | 105.00| 103.00|
select_key_prefix (200000)          | 106.00| 107.00|
select_key_prefix_join (100)        |   2.00|   2.00|
select_key_return_key (200000)      | 100.00| 102.00|
select_many_fields (2000)           |   8.00|   8.00|
select_range (410)                  |  16.00|  16.00|
select_range_key2 (25010)           |  10.00|  10.00|
select_range_prefix (25010)         |  10.00|   9.00|
select_simple (100000)              |  36.00|  37.00|
select_simple_cache (100000)        |  37.00|  36.00|
select_simple_join (500)            |   1.00|   1.00|
update_big (10)                     |  16.00|  16.00|
update_of_key (50000)               |  71.00|  68.00|
update_of_key_big (501)             |   8.00|   7.00|
update_of_primary_key_many_keys (256|  35.00|  36.00|
update_with_key (300000)            | 408.00| 391.00|
update_with_key_prefix (100000)     | 142.00| 135.00|
wisc_benchmark (114)                |   1.00|   1.00|
-----------------------------------------------------
TOTALS                              |7345.00|6498.00|
=====================================================

fdatasyncになり、もう少し性能あがるかなと思ったのですが、性能は芳しくない結果となっています。

CREATE / INSERの性能がかなり落ちているのと、IOPSの成果が芳しくないので現在原因調査と追試をしています。

追記

完全に見落としていましたが、sync_binlogが有効になってました。5.5では編集可能ですが5.6 familyのParameter Groupでは編集不可です。

確かに、編集不可というところで、クラッシュリカバリ中でBinlogが使われるようになったのでそれを保護するためかと思います。
MySQL Bugs: #68932: A regression in 5.6 crash recovery atomicity
全体的に安全側に倒している感じがします。Crash Safe Read Replicasのためとか。

GTIDがデフォルトでOFFなのは運用面が問題になったのでしょうか。

お使いの際はユースケースで検証の後使うことをおすすめします。

その他

Innodb Memcached Pluginが使えるということで
MySQL Bugs: #68530: memory leak with innodb memcached plugin for stale connection
こちらのBugが対応済みか気になります。

こちらも