2012年12月17日月曜日

CloudWatchのコマンドラインツールでDynamoDBの統計情報作成

前回のブログでDynamoDBの話をしたけど、インフラエンジニアの私は実際のテーブル設計
よりは、運用後のリソース管理が気になるところ。DynamoDBの良いところはスループットが
保障される事。とは言えこれは設定した値が保障されると言う事で、その値が適切でない
場合は結局「なんかレスポンス悪くね?」と言う残念な結果になってしまう事に。。。
それを恐れるがあまり、値を大きくしてしまうと請求の時に「高っ!」とびっくりする事に。
スループットの値は変更が聞くので、今回はDynamoDBの稼動統計を行うために情報取得を
してみましょ!


・情報取得方法
AWSでは稼動情報をみる事ができるCloudWatchという機能があります。こちらはEC2や
RDSなどAWSで扱っているサービスの情報が全て取得できます。何か動きがおかしいと
思った時には、ManagementConsoleからグラフ化されたものを見る事ができます。
ですが稼動統計を行う場合は、定期的に情報を取得しておく必要があります。
そこでコマンドラインツールを使用する事でデータを取得する事とします。

・準備
AWSの下記リンクから「Amazon CloudWatch Command Line Tool」をDownloadします。
http://aws.amazon.com/developertools/2534
今回はLinux(CentOS)を使用するため、DownloadしたzipファイルをEC2に格納します。
格納先は/usr/localとします。

/usr/local以下でzipファイルを解凍します。
# cd /usr/local
# unzip CloudWatch-2010-08-01.zip
# rm -f CloudWatch-2010-08-01.zip
使いやすいようにバージョン情報が入ったディレクトリ名を変更します。
# mv CloudWatch-1.0.13.4 CloudWatch
AWSにアクセスするためのアクセスキー用ファイルをコピーします。
# cp -p CloudWatch/credential-file-path.template ~/credential.txt
→コピー後にファイルを編集します。アクセスキー及びシークレットアクセスキーは事前に
 ManagementConsoleなどで確認しておきましょう。ファイルの中身は下記の通りです。

AWSAccessKeyId=<Write your AWS access ID>
AWSSecretKey=<Write your AWS secret key>


中身を他人に見られないようにパーミッションを変更します。
# chmod 600 ~/credential.txt
環境変数の設定です。(これらは.bashrcに記載しておくと良いでしょう)

export AWS_CLOUDWATCH_HOME=/usr/local/CloudWatch
export PATH=$PATH:$AWS_CLOUDWATCH_HOME/bin
export AWS_CREDENTIAL_FILE=~/credential.txt
export AWS_CLOUDWATCH_URL=https://monitoring.ap-northeast-1.amazonaws.com


これで準備は完了です。

・情報取得
今回用意したツールでは情報取得以外にもアラームの設定なども出来ます。今回は
統計情報を取得する事が目的のため、二種類のコマンドの紹介です。

○mon-get-stats
実際に情報を取得するコマンドです。
○mon-list-metrics
どのようなMetricがあるのかを確認(一覧表示)するコマンドです。

では実際に情報取得です。まずはmon-list-metricsで一覧を取得します。
# mon-list-metrics
結果は長いので省略ですが、今回はDynamoDBのRequestLatencyを取得するため一覧
から下記のものを対象とする事とします。

SuccessfulRequestLatency               AWS/DynamoDB     {Operation=GetItem,TableName=test_table}
SuccessfulRequestLatency               AWS/DynamoDB     {Operation=PutItem,TableName=test_table}
SuccessfulRequestLatency               AWS/DynamoDB     {Operation=UpdateItem,TableName=test_table}

mon-get-statsを使用して情報取得です。取り込み易いようにカンマ区切りにします。
# mon-get-stats SuccessfulRequestLatency \
   --statistics "Average,Sum,Minimum,Maximum" \
   --namespace "AWS/DynamoDB" \
   --dimensions "Operation=PutItem,TableName=test_table" \
   awk '{print $1 "," $2 "," $3 "," $4 "," $5 "," $6}' \
   >> ~/PutItem_test_table.cvs

ファイルの中身は下記のようになります。(時間はUTCのため注意)

2012-12-16,14:55:00,5.25654654646,196.23000000000002,3.265,6.013
2012-12-16,15:00:00,4.95656856565636,188.082,3.258,6.189
2012-12-16,15:05:00,3.565959565332,121.566,3.315,6.396
2012-12-16,15:10:00,4.4421333333333335,133.264,3.345,6.261
2012-12-16,15:15:00,4.2650526315795,165.88600000000002,3.279,6.124
2012-12-16,15:20:00,4.507655172413792,130.761999999998,3.392,6.659
2012-12-16,15:25:00,4.53334375,145.067,3.309,6.538
2012-12-16,15:30:00,4.254555555555555,123.87299999999,3.286,7.649
2012-12-16,15:35:00,4.309178571428572,120.65700000000001,3.251,6.151
2012-12-16,15:40:00,4.5852150000000001,93.043,3.343,5.876
2012-12-16,15:45:00,4.04362,101.138,3.284,5.2546


コマンドの最初の引数はMetricNameです。後の引数は下記になります。
--statistics 集計方法の指定
--namespace サービス名(DynamoDB、EC2など)の指定
--dimensions 集計情報のうちのどの情報かの指定
*ここがポイントで前述のmon-list-metricsの3カラム目の値となります。

上記のコマンドをcronなどで自動的に取得すれば良いということになります。
少々分からないのが5分おきの直近1時間のデータが取得されるはずなのですが、
11個(55分)しか取得できませんでした。ですので、データの抜けが内容に取得する
間隔を調整して重複するデータはuniqなどで排除する必要がありそうです。
(何か方法があるのかも知れませんが。。。)


大事なのは情報を取得する事ではなく、ここからいかに適切なリソース状態を導き
出すかです。(今後の課題ですね。。。)

2012年12月8日土曜日

DynamoDBをIAMでアクセス制限

DynamoDBは便利。AWSのManagementConsoleのウィザードでちょちょいとテーブル
作成が簡単にできる。検証でさくっと作ってぱぱっとテストも出来てしまう。テーブル
削除もぽちっとすれば、はい消えた!となるのでお手軽。テーブルはあるだけでお金
がかかるので、不要となったら小まめに消さなきゃね。
と、調子にのっているとミスって肝心の本番用テーブルを消してしまいがちなものですね。

そこで、IAMアカウントで本番用と開発用と分けてアクセス制限してしまいましょう^^


・制御内容
ネーミングルール(少なくとも本番用)が必要となります。今回は下記のようにします。
■本番用はテーブル名の頭にprd_がついている
■開発用はそれ以外

・アカウント
アカウントは二つ作成します。
■本番用アカウント prd_dynamo
■開発用アカウント dev_dynamo

・グループ
DynamoDBではアラート設定が出来るため、cloudwatchの権限を付与します。
テーブル自体は個々のアカウントでアクセス制御しますので、cloudwatchの権限はgroupで
管理します。Policy Generatorで簡単に作れますが、一応JSON載せておきます。

{
  "Statement": [
    {
      "Sid": "Stmt1354899265648",
      "Action": [
      "cloudwatch:*"
      ],
      "Effect": "Allow",
      "Resource": [
        "*"
      ]
    }
  ]
}


では実際にアカウントへのpolicy設定です。
まずはprd_dynamoです。
{
  "Statement": [
    {
      "Sid": "Stmt1330073911360",
      "Action": [
        "dynamodb:DescribeTable",
        "dynamodb:ListTables"
      ],
      "Effect": "Allow",
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "Stmt1330073911361",
      "Action": [
        "dynamodb:*"
      ],
      "Effect": "Allow",
      "Resource": [
      "arn:aws:dynamodb:ap-northeast-1:<アカウントID>:table/prd_*"
      ]
    }
  ]
}

キーとなるのは、次の二点です。
■最初のAllowでDescribeTableとListTablesを入れる事
→これで全体のテーブルリストを表示する事ができます。全体を表示できるように
 設定しておかないと、自身のテーブルも表示出来ません。この設定でテーブル
 リストの表示のみ出来るようになります。
■次のAllowのリソースでtable/prd_*と記載する事
→これでprd_*で始まるテーブルを全て制御できるようになります。

次にdev_dynamoです。
{
  "Statement": [
    {
      "Sid": "Stmt1330073911370",
      "Action": [
        "dynamodb:BatchGetItem",
        "dynamodb:CreateTable",
        "dynamodb:DeleteItem",
        "dynamodb:DeleteTable",
        "dynamodb:DescribeTable",
        "dynamodb:GetItem",
        "dynamodb:ListTables",
        "dynamodb:PutItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem",
        "dynamodb:UpdateTable"
      ],
      "Effect": "Allow",
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "Stmt1330073911371",
      "Action": [
        "dynamodb:BatchGetItem",
        "dynamodb:CreateTable",
        "dynamodb:DeleteItem",
        "dynamodb:DeleteTable",
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem",
        "dynamodb:UpdateTable" ],
      "Effect": "Deny",
      "Resource": [
      "arn:aws:dynamodb:ap-northeast-1:<アカウントID>:table/prd_*"
      ]
    }
  ]
}

キーとなるのは、次の二点です。
■最初のAllowでDynamoDBの全ての権限を記載する事
→これで全てのテーブルの制御ができるようになります。ほんとは*でも良いかと
 思うのですが、ちょっと上手く動かなかったので個別に記載しています。
■次のDneyでtable/prd_*を記載する事
→これでprd_*で始まるテーブルを全て制御出来なくなります。但し、ここの記載
 にListTablesとDescribeTableは記載してはいけません。テーブルリスト表示が
 出来なくなるため、全体のテーブルリストも表示できなくなります。

さて、アクセス制御出来ているか確認してみましょう。

まずはprd_dynamoです。

テーブルリストが確認できます。

prd_testにアクセスできます。

testにアクセスできません。


次にdev_dynamoです。
テーブルリストが確認できます。

prd_testにアクセスできません。
testにアクセスできます。


最初はActionは*でResourceをprd_*のAllowとDenyで逆にすれば簡単に制御できる
かと思いましたが、テーブルリスト表示などの細かい部分で*で制御出来ない感じ
でした。


2012年9月17日月曜日

CentOSでRAID0

前回のブログでawsのEC2インスタンスでエフェメラルディスクを使う方法を記載した。
EC2インスタンスサイズによっては複数のディスクを使用する事ができる。
という事で折角なのでCentOSでRAID0を組んでみたので、設定方をを記載してみる。
ちなみにCentOSは6.3を使用。


・最初に
CentOSでソフトウェアRAIDを組む場合はmdadmを使用します。パッケージが組み込まれて
いない場合はyumでインストールできます。
# yum -y install mdadm

・デバイスの確認
エフェメラルディスクがOS上でどのように認識されているか確認します。
# ls -l /dev |grep xvd
→基本的にはEC2インスタンス作成時に割り当てたデバイス名とリンクしています。
 sdbで指定した場合は/dev/xvdbとなります。

今回はディスクを/dev/xvdi、/dev/xvdjの二つ使用する事とします。

・ディスクの初期化
fdiskを使用してディスクを初期化します。
# fdisk /dev/xvdi
→対話型となるため下記の流れで応答します。
 n 新たに領域を作成する
 p 基本領域 (1-4)
 1 一番目
   空Enter(開始シリンダを一番最初)
   空Enter(終了シリンダを一番最後)
 w 書き込み終了

同様に/dev/xvdjも初期化します。

・デバイスの作成
新規でRAID用デバイスを作成します。
# mknod /dev/md1 b 210 1
→オプション説明
 /dev/md1 デバイスファイル名。mdXとするため今回は/dev/md1を指定
 b デバイス種別。ブロックデバイスのためbを指定
 210 メジャー番号。空いている番号であれば良いため今回は210を指定
 1 マイナー番号。メジャー番号の中で空いている番号であれば良いため1を指定

・RAIDの作成
mdadmを使用してRAIDを作成します。
# mdadm --create --verbose /dev/md1 --level=0 --raid-devices=2 /dev/xvdi /dev/xvdj
→オプション説明
 --create 作成
 --verbose 画面表示
 /dev/md1 RAIDを作成するデバイス名
 --level= RAIDのレベル。今回はRAID0のため0を指定。
 --raid-devices= RAIDに組み込むディスク数。今回は二つのため2を指定。
 /dev/XX 組み込むディスクデバイス名。今回は/dev/xvdi、/dev/xvdjを指定

・RAID構成の確認
指定した内容で作成されているか確認します。
# cat /proc/mdstat

・ファイルシステムの作成
作成したRAIDデバイスを使用してファイルシステムを作成します。今回はex4とします。
# mkfs.ext4 /dev/md1

・mdadm.confの作成
再起動後も使用できるようにmdadm.confファイルを作成します。
# vi /etc/mdadm.conf
→下記の内容を記載します。

DEVICE /dev/xvd[a-z]*
ARRAY /dev/md1 devices=/dev/xvdi,/dev/xvdj


・fatabへの登録
自動起動するようにfstabに追記します。今回は/mnt/1にマウントします。
# vi /etc/fstab
→下記の内容を記載します。
/dev/md1  /mnt/1 ext4 defaults 0 0

・マウントの実施
マウントを実施します。
# mount /mnt/1

・容量の確認
マウントされたボリュームが期待する容量となっている事を確認します。
# df -h /mnt/1

今回の手順はEC2のエフェメラルディスクを使用している事による特別な内容は無く
普通にRAIDを組む場合と同じになります。但し、エフェメラルディスクはEC2インスタンス
のstopで設定などが消えてしまうため、上記手順の一部を再度行う必要があります。
・RAIDの作成
・ファイルシステムの作成
・マウントの実施

私が確認したところ、rebootではRAID構成情報もデータも残っていましたので、stopを
した場合のみ再作成となる様子です。

awsのエフェメラルディスクを使う

久々となってしまったが技術情報を書こうと思う。
今回はawsのEC2インスタンスでエフェメラルディスクを簡単に使う方法を記載する。


・最初に
EC2インスタンスを作成する場合に最近はEBSを使用するのが通常の方法です。
しかしEC2インスタンスにはエフェメラルディスクと呼ばれるテンポラリ的なディスクが
ついています。エフェメラルディスクはEC2インスタンスをstopするとデータが消えて
しまうため、bootディスクやデータファイルのように消えてしまうと問題となる場合には
使用が厳しい事となります。しかし、ファイル転送やデータをダンプして別のディスク
(S3など)へ転送するなどの一時領域としては有効な領域となります。

・使用方法
元々、EC2インスタンスを作成した場合にエフェメラルディスクは自動で付与されて
います。EC2 APIなどを使いEC2インスタンスを起動する際に指定する方法がある
のですが、今回はEC2インスタンスを作成する時に最初からディスク割り当てする
方法を記載します。
1.AWS Management Consoleより新規でEC2インスタンスをlaunch
  (作成済みAMIからでもOKです)
2.ウィザードの「Storage Device Configuration」にて「Instance Store Volumes」タブ
  を選択します。
3.ここでエフェメラルディスクを追加します。注意としては0~3と四つ選択する事が
  できますが、インスタンスサイズにより使用可能なディスクの数や容量に違いが
  あります。(下記はaws Documentationより抜粋(2012/9現在))

TypeNameInstance Store Volumes
Microt1.microNone (use Amazon EBS volumes)
Smallm1.small1 x 150 GiB
Mediumm1.medium1 x 400 GiB
Largem1.large2 x 420 GiB (840 GiB)
Extra Largem1.xlarge4 x 420 GiB (1680 GiB)
High-CPU Mediumc1.medium1 x 340 GiB
High CPU Extra Largec1.xlarge4 x 420 GiB (1680 GiB)
High-Memory Extra Largem2.xlarge1 x 410 GiB
High-Memory Double Extra Largem2.2xlarge1 x 840 GiB
High-Memory Quadruple Extra Largem2.4xlarge2 x 840 GiB (1680 GiB)
High I/Ohi1.4xlarge2 x 1 TiB SSD (2 TiB)
Cluster Compute Quadruple Extra Largecc1.4xlarge2 x 840 GiB (1680 GiB)
Cluster Compute Eight Extra Largecc2.8xlarge4 x 840 GiB (3360 GiB)
Cluster GPU Quadruple Extra Largecg1.4xlarge2 x 840 GiB (1680 GiB)


要は通常のEC2インスタンス作成をする際のディスク設定で指定するだけで、EC2 API
などを使用して起動しなくてもエフェメラルディスクが使用できるようになります。

2012年8月20日月曜日

CentOSにCassndra

ブログを始める理由の一つが、インフラ構築で行った作業を記載する事である。
今回はCassandraのインストール手順を記載してみようと思う。


・最初に
Cassandraとはkey-valueストア型のデータベースで所謂NoSQLのデータベースです。
今回はVer1.1.3を/usr/localにインストールします。
 
・インストール 
CassndaraはJavaで動作するため、まずは Javaをインストールします。
# yum -y install java-1.6.0-openjdk.x86_64

Cassandraはbinaryのアーカイブファイルが公開されているので取得します。
# cd /usr/local/src
# wget http://ftp.jaist.ac.jp/pub/apache/cassandra/1.1.3/apache-cassandra-1.1.3-bin.tar.gz


取得したアーカイブファイルを展開します。
# cd /usr/local
# tar -zxvf src/apache-cassandra-1.1.3-bin.tar.gz


シンボリックリンクを張ります。
# ln -s apache-cassandra-1.1.3 cassandra

作業領域(データ、ログなど)ディレクトリを作成します。
# mkdir -p /var/lib/cassandra


cassandra.yamlの編集
localhostの記載を自ホスト名に変更します。
# vi cassandra/conf/cassandra.yaml

ここまででインストールと(基本的な)設定は完了です。
では起動してみましょう!

・cassandra起動
フォアグラウンドで起動されるため、バックグラウンドの場合は&をつけましょう。
# /usr/local/cassandra/bin/cassandra -f


・起動確認
下記コマンドで結果が表示されればOKです。
# /usr/local/cassandra/bin/nodetool -host `hostname` ring



Cassandraはクラスタ対応されており、簡単に設定できますが、今回はここまで!

2012年8月18日土曜日

ブログを始める事に

大人の事情でブログを始める事にした。
何を書こうかという事より先に、タイトルで悩んだ悩んだ(;´д`)ゞ
1時間ほど悩んだ結果、「Macedonia Shooter」にしてしまった(一応意味は内緒)

疲れたんで今日はここまで|Д´)/~~