ども、cloudpack の かっぱ (@inokara) です。(福岡県出身ではありません)
はじめに
ElastiCache for Redis を触る機会に恵まれて、検証中 Snapshot を API 経由で取る際にムラムラっとしたのでエイやって作ってみました。せっかくなんでコマンドラインツールっぽくしたかったのでThorもソーっと使って RubyGems に公開してみました。
尚、このツールを作るにあたっていくつか勉強になったことがありますので合わせて書いていきたいと思います。(記事中の「☆」印がポイントです…もちろん、ドキュメントに書かれていることです。)
おれんコマンドツールくさ
ギットハヴとルビィジェムズ
「おれん」は博多弁で「俺の」という意味です。
機能
詳細は README.md を御覧下さい
- スナップショット一覧を取得する
- スナップショットを作成する(クラスタ内で最も最近作成されたノードで且つレプリカノードから作成)
- スナップショットを削除する
スナップショット一覧を取得する
以下のように実行します。
bundle exec bin/elasticache_snapshot list
以下のように出力されます。
+---------------------+-------------------------+ | SNAPSHOT Name | SNAPSHOT Create time | +---------------------+-------------------------+ | snapshot-1420457086 | 2015-01-05 11:25:01 UTC | | snapshot-1420457295 | 2015-01-05 11:28:31 UTC | | snapshot-1420461070 | 2015-01-05 12:31:21 UTC | +---------------------+-------------------------+
テーブル表示は自己満足です。
スナップショットを作成する
以下のように実行します。
bundle exec bin/elasticache_snapshot create
スナップショット名を指定することも可能ですが、指定しない場合には snapshot-#{UNIX 時間}
となります。(☆1)
スナップショットはクラスタ内で最も作成日付が新しいノードで且つレプリカノードから取得します。(※このあたりが十分に動作確認が出来ていない部分ですので引続き手を入れていきます)尚、これは、スナップショット作成時のマスターノードへの負荷軽減を目的としています。(☆2)
実行すると以下のようにスナップショット名とどのノードから取得したかが表示されます。(☆3)
% bundle exec bin/elasticache_snapshot create hoge-20150105 Create hoge-20150105 from kappa-test-003...
一覧を確認すると以下のようにスナップショット一覧に名を連ねます。
+---------------------+-------------------------+ | SNAPSHOT Name | SNAPSHOT Create time | +---------------------+-------------------------+ | hoge-20150105 | 2015-01-05 16:34:18 UTC | | snapshot-1420455477 | 2015-01-05 10:58:07 UTC | | snapshot-1420455721 | 2015-01-05 11:02:11 UTC | | snapshot-1420475287 | 2015-01-05 16:28:20 UTC |
スナップショットを削除する
bundle exec bin/elasticache_snapshot delete xxxx-xxxx
xxxx-xxxx
には削除したいスナップショット名を指定します。もちろん、スナップショット名を指定し忘れると…
ERROR: "elasticache_snapshot delete" was called with no arguments Usage: "elasticache_snapshot delete SNAPSHOT_NAME"
Thor にソーッと叱られます。
たったこんだけの機能ですが…
ダメ出しお願い致します。
目標と言う名の todo
- ちゃんとしたエラー処理を入れる
- 出来るだけ綺麗なコードにする
- クラスタ及びノードの一覧の取得が出来るようにする
- スナップショットを取得するノードを任意で指定出来るようにする
おれんメモ
参考
- Class: AWS::ElastiCache::Client::V20140930
- Ruby の CLI ツールの作成を支援する、thor gem の基本について。#thor #ruby
- Thorの使い方まとめ
コマンドラインツールを作る上で学んだこと
- スナップショット名(☆1)
- スナップショット対象ノードの選定とスナップショット取得時のステータス(☆2 ☆3)
- describe snapshots に含まれる情報
- Thor でコマンドラインツールを作る方法(初歩的な使い方)
スナップショット名
スナップショットを取得する際に適当な名前だと怒られてしまいます。例えば、以下のように2015010601
のような日付の羅列の場合には…
aws elasticache create-snapshot --cache-cluster-id kappa-test-003 --snapshot-name 2015010601
以下のようなエラーとなります。
A client error (InvalidParameterValue) occurred when calling the CreateSnapshot operation: The parameter SnapshotIdentifier is not a valid identifier. Identifiers must begin with a letter; must contain only ASCII letters, digits, and hyphens; and must not end with a hyphen or contain two consecutive hyphens.
ざっくり訳すと…
- ASCII 文字と数字とハイフンを含めましょう
- ハイフンで終わるのと連続したハイフンはダメよダメダメ
とのことです。
スナップショット対象ノードの選定とスナップショット取得時のステータス
今回、スナップショット対応ノードの選定に際しては以下のような条件を想定しました。(この条件が一般的かは定かではありませんが…)
- レプリカノードであること
- クラスタ内で最も若い(作成時間が最新であること)
この条件でノードを抽出するにあたっては describe_cache_clusters
に含まれる :cache_cluster_create_time
を利用して並べ替えを行っています。(※以下、抜粋)
... (snip) elc.describe_cache_clusters.cache_clusters.each do |i| cluster << { :cluster_id => i.cache_cluster_id, :create_time => i.cache_cluster_create_time, :cache_cluster_status => i.cache_cluster_status } end puts cluster sorted = cluster.sort {|x, y| y[:create_time] <=> x[:create_time]} (snip) ...
エイヤ!で考えたロジックなので色々と不安でツメが必要かなと思っていますが、SDK のレスポンスに色々と情報が盛られているのでこれらを組み合わせることが出来そうです。
また、スナップショット作成を行った場合にノード(cluster_id
)のステータスは以下のようなレスポンスが得られます
{:cluster_id=>"kappa-test-003", :create_time=>2015-01-05 04:27:10 UTC, :cache_cluster_status=>"snapshotting"}
上記は SDK のレスポンスから必要な部分を抜き出して配列に突っ込んだものですので実際のレスポンスとは異なりますが、スナップショット取得中のノード(cluster_id
)の :cache_cluster_status
は snapshotting
というステータスとなります。この snapshotting
の状態である場合にはスナップショットを取得することは出来なくなります。尚、:cache_cluster_status
はクラスタの状態により以下のような値を返却します。
- available
- creating
- deleted
- deleting
- incompatible-network
- modifying
- rebooting cache cluster nodes
- restore-failed
- snapshotting
若干、解り辛いですがこちらに記載されています。
describe snapshots に含まれる情報
describe snapshots に含まれる情報は以下のような情報が含まれます。(読みやすくする為に JSON で出力させました)
{ "num_cache_nodes": 1, "snapshot_window": "14:00-15:00", "cache_subnet_group_name": "default", "cache_cluster_create_time": "2015-01-05 04:27:10 UTC", "preferred_availability_zone": "ap-northeast-1a", "engine": "redis", "cache_node_type": "cache.m1.small", "cache_parameter_group_name": "test", "port": 6379, "cache_cluster_id": "kappa-test-003", "node_snapshots": [ { "cache_size": "19 MB", "cache_node_id": "0001", "cache_node_create_time": "2015-01-05 04:27:10 UTC", "snapshot_create_time": "2015-01-05 16:28:20 UTC" } ], "engine_version": "2.8.6", "snapshot_source": "manual", "auto_minor_version_upgrade": true, "preferred_maintenance_window": "thu:15:30-thu:16:30", "snapshot_name": "snapshot-1420475287", "vpc_id": "vpc-xxxxxxxxxx", "snapshot_retention_limit": 0, "snapshot_status": "available" }
スナップショット作成日は取得したノードの情報などがレスポンスとして返ってきています…。
ということで、ほんのちょっと API に触れてみた分際で恐縮ですが API って楽しいですな。
Thor でコマンドラインツールを作る方法(初歩的な使い方)
Thor については以下の記事などを参考にさせて頂きました。
以下のように thor
を require
して Thor
クラスを継承したおれん(俺の)クラスを作りメソッドを書いていけばメソッド自体がコマンドになるという筋書きです。
require 'thor' class HagenoCLI < Thor desc "zura usage", "zura desc" def zura(name) puts "zura #{name}" end end HagenoCLI.start(ARGV)
引数ナシで実行すると以下のように…
% ruby zura.rb Commands: zura.rb help [COMMAND] # Describe available commands or one specific command zura.rb zura usage # zura desc
コマンド zura
を付けて実行すると…
% ruby zura.rb zura ERROR: "zura.rb zura" was called with no arguments Usage: "zura.rb zura usage"
コマンド zura
に引数を付けて実行すると…
% ruby zura.rb zura de_fusafusa zura de_fusafusa
上記のように zura
コマンドの引数 de_fusafusa
を出力しました。
超初歩的な Thor の使い方を書きましたが、普段から利用している UNIX コマンドのような --foo
又は -f
のような指定も可能ですし、デフォルト値なども定義出来るようなのでちょっとしたコマンドラインツールを作る際には是非覚えておきたいツール!、ソー(そう)、ソーれが(それが)、Thor(ダジャレ三連発)。ということで詳細は上記の参考記事やオフィシャルサイト を御覧ください。
ということで…
ちょっとしたツールを作ることで色々と勉強になりましたが、Redis っぽい側面については触れられていないので引続き触れていきたいと思います。尚、紹介したツールは引続き手を入れていきたいなと思います!
元記事はこちらです。
「ElastiCache のスナップショットを取得するコマンドラインツールを作ったメモ(おれん(俺の) ElastiCache Snapshot)」