まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:aws

Amazon で商品を検索したり、その商品へのリンクを作成する作業を自動化するには Amazon Product Advertising API を使います。その際にアクセスキーとシークレットアクセスキーが必要になります。 これらの取得方法を紹介します。

前提として、AWS のアカウントが必要です。こちらから作成しておきましょう:
https://aws.amazon.com/jp/


API のアクセスキーとシークレットキーを取得するには、まず AWS にログインし、名前の部分をクリックして「セキュリティ認証情報」を選択します:
2017020801


AWS Identity and Access Management ユーザーがうんたらかんたら・・・というメッセージが表示されますが、今は無視して×をクリック:
2017020802


「セキュリティ認証情報」のページで、「アクセスキー(アクセスキーIDとシークレットアクセスキー)」と書かれた箇所をクリック&展開して、「新しいアクセスキーの作成」ボタンをクリックします(同時には2つまでのアクセスキーを所持できるらしいです):
2017020803


アクセスキーが作成されます。その中身を表示すると、アクセスキーID &シークレットアクセスキーがそれぞれ表示されます。 これで目的の情報が取得できました。なおシークレットアクセスキーはこの1回しか表示されません確認する唯一の機会です。忘れてしまった場合は1つ前の画面で一度削除して、再度アクセスキーを作成し、その際に確認する必要があるので注意してください:
2017020804


この API の使い方については公式ドキュメントを参照してください:
https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html


この情報や API を使ってアフィリエイトを行おうとすると、別途アソシエイト ID も合わせて取得する必要がありますが、その取得方法についてはこちらを参照ください:
Amazon アソシエイト ID の取得手順


最近は多くのクラウド業者が IoTMQTT との連携をアピールしています。IBM を含めて各社が「いかに簡単に IoT データを扱う/応用することができるか」を競っている感じです。

この点で IBM の強みの1つが Node-RED フローエディタだと思っています。Bluemix に統合されたこの GUI エディタは MQTT サーバー(ブローカー)との接続を簡単に行い、データを集め、保存する仕組みを簡単に提供することができます。MQTT ブローカー/クライアントの Mosquitto といい、この Node-RED といい、IoT にもオープンソース製品が多くの場面で使われるようになってきて、更なる広まりを見せているように感じます:
2015082602


IBM の場合、この Node-RED をうまく Bluemix に合わせてカスタマイズして提供しており、Bluemix 内ではすぐに使えるようになっており、また Bluemix の各サービスと簡単に組み合わせて使えるような形で提供されています。


ただ Node-RED そのものはオープンソースで提供されているものです。他のクラウドインスタンスやオンプレミスサーバー環境でも(Bluemix 用の拡張がされていない素のエディションを)動かすことが可能です。つまり IBM 以外の業者のクラウド環境内で Node-RED を使った IoT アプリ開発環境を構築することだってできるわけです。


というわけで、今回のブログエントリでは SoftLayer や AWS、IDCF、オンプレミスなどの(クラウド)サーバー環境内で Node-RED を使って IoT アプリ開発環境を構築する手順を紹介します。


まず最初に Bluemix と IBM IoT Foundation を使った場合の IoT アプリ開発環境のシステムトポロジーを確認しておきます。必要になるサーバーとしては各種センサーデバイスからの情報を集約する MQTT ブローカーと、Node-RED が稼働する Node.js アプリケーションサーバーです。Bluemix 環境の場合、前者は IBM IoT Foundation が提供する quickstart サーバーを無料で使うことができます(つまり構築不要です)。後者は Bluemix のボイラープレートを使うことで Node-RED が動く状態まで含めて簡単に構築できてしまいます。なお収集したデータを保存しようとすると別途データベースサーバーを用意する必要がありますが、Bluemix であればデータベースも簡単に追加してバインドすることが可能です(今回はデータベースを使わない環境を前提とします):
2015082601


これと同じ環境を Bluemix を使わずに構築することを考えると、(物理的には1台のマシンでも構いませんが)上記の MQTT ブローカーと Node.js の2サーバーを手動で用意することになります:
2015082602


具体的には MQTT と Node-RED それぞれの環境を用意する必要があります。1台または2台のサーバーを用意し、それぞれのサーバーインスタンスに MQTT ブローカーおよび Node-RED 環境を構築します。それぞれの手順は(CentOS サーバーの場合であれば)以下の記事を参照ください:
ラズベリーパイにオープンソース MQTT の Mosquitto をインストールする (←ラズベリーパイだけでなく CentOS の場合のインストール方法も記載しています)
CentOS に Node-RED をインストールする


まずは MQTT ブローカーを起動しておく必要があります。MQTT ブローカー(Mosquitto サーバー)を導入したマシン上で以下のコマンドを実行するなどして Mosquitto サービスを動かしておきます:
# service mosquitto start

次に Node-RED を導入したサーバーで Node-RED を起動します:
2015082603


起動した Node-RED にブラウザでアクセスします。Node-RED はデフォルトでは 1880 番ポートで起動するので、 http://(Node-RED サーバー):1880/ でアクセスするとフローエディタの画面が開きます:
2015082604


そして下図のような、MQTT インプットと Debug アウトプットを繋げただけのシンプルなフローを記述します:
2015082608


MQTT インプットの属性は以下のようにします。Broker には Mosquitto を導入したサーバーの 1883 番ポートを指定します。Topic はなんでもいいのですが、ここでは "top/001" と指定しています(後で実行するコマンドで指定することになる文字列です)。準備ができたらデプロイして実行状態にします:
2015082605


これで環境は出来上がりました。では正しく動いているかどうかを確認してみましょう。
別途 Mosquitto クライアントを導入したマシン(これも同一マシンでもかまいません)から以下のコマンドを実行して、MQTT ブローカーにメッセージをパブリッシュします:
$ mosquitto_pub -h (MQTT ブローカーサーバー) -t "top/001(上記 Node-RED で指定した Topic 属性と同じ文字列)" -m "Hello."

2015082606


すると、Node-RED 画面の debug タブには -m オプションで指定された文字列が表示されるはずです。つまり MQTT ブローカーの top/001 トピックに送信されたメッセージを、Node-RED から正しく取得することができたことになります:
20150824_nodered



ちゃんと動きました。Node-RED は Bluemix や IBM IoT Foundation がなくても、普通の(?) MQTT 環境の中でも動くことが確認できました。


・・・とはいえ、Bluemix + IBM IoT Foundation 環境で Node-RED を使ったことのある者として言わせていただくと、ここまでの環境を整えないと使えないわけです。また現実的には取得したデータをデータベースに格納しようとすると、Bluemix 環境のように簡単にはいきません。動くか動かないかでいうと動きますが、その準備のためのハードルはまだまだ高いように感じています。

IoT アプリ開発環境を検討する上で IBM Bluemix + IBM IoT Foundation + Node-RED がいかに簡単で便利なのか、を改めて再確認するような実験になったとも感じました。




 

Amazon EC2IDCF のサーバーインスタンスを使っていますが、どうしても気になるのはデフォルト状態ではスワップ領域が確保されていないことです:
2015020601


↑メモリは1GBで残り65MBほど。
 もうすぐメモリが足りなくなりそう、でもスワップ領域はゼロ・・・


特に高速化のために memcached とかを使うアプリを動かそうとすると、どうしてもメモリが不足しがちになります。スワップ領域がない状態で、一瞬でもメモリが足りなくなってしまうとアウトです。回避するにはなんとかしてスワップ領域を確保する必要があります。


EC2 や IDCF クラウドでは静的にスワップ領域が確保されているわけではないため、EBS などの追加ディスクを使う方法もありますが、これだとスワップ領域のために料金がかかる上、EBS は I/O にも課金されるので、スワップファイルを作る先としてはコスト的に不利です。

というわけで、インスタンスの起動時にディスクの空き部分を使ってスワップファイルを作ってスワップ領域とする、という方法を紹介します。これなら(ディスクに空きがあれば、の前提が必要ですが)ディスクを追加せずにスワップ領域を確保することができます。

具体的には /etc/rc.local あたりに以下のような内容を追加します。この例ではスワップサイズをメモリ量から動的に変更するようにしていますが、あくまで一例です。固定値を書き込んでしまってもいいと思います(青字は僕のコメント):
  :
  :
SWAPFILENAME=/swap.img スワップファイル名
MEMSIZE=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'` 現在のメモリ量(KB)を取得

メモリ量からスワップ領域のサイズを決定
if [ $MEMSIZE -lt 1012293 ]; then
  SIZE=${MEMSIZE}k メモリ 1GB 以下の場合、スワップ領域はメモリサイズと同じ
elif [ $MEMSIZE -lt 2097152 ]; then
  SIZE=${((MEMSIZE * 2))}k メモリ 2GB 以下の場合、スワップ領域はメモリサイズの倍
elif [ $MEMSIZE -lt 8388608 ]; then
  SIZE=${MEMSIZE}k メモリ 8GB 以下の場合、スワップ領域はメモリサイズと同じ
elif [ $MEMSIZE -lt 67108864 ]; then
  SIZE=${((MEMSIZE / 2))}k メモリ 64GB 以下の場合、スワップ領域はメモリサイズの半分
else
  SIZE=4194304k メモリ 64GB 以上の場合、スワップ領域は8GB
fi

スワップファイルを作成してスワップオン
fallocate -l $SIZE $SWAPFILENAME && mkswap $SWAPFILENAME && swapon $SWAPFILENAME
  :
  :

/etc/rc.local は他の初期化スクリプトが実行された最後に実行される設定コマンドファイルです。なのでサービスやらの自動実行が行われた最後にこのコマンドが実行され、/swap.img というスワップファイルが作成されて、スワップ領域として動き始めます。このスワップファイルのサイズは物理メモリサイズに応じて動的に切り替わるようにしています。


これでサーバーインスタンスを再起動すると、今度は起動時に上記のスクリプトが実行され、スワップ領域が動的に作成されます。これで少し安心:
2015020602



(参考)
http://dev.classmethod.jp/cloud/ec2linux-swap-bestpractice/

 

ネットワークパフォーマンス(端的に言えば回線速度)の計測方法は多々有りますが、クラウドのネットワークパフォーマンスを計測しようとすると、1つ問題が生じます。

多くのクラウドでは、サーバーインスタンス契約後に使えるインターフェースが SSH に限られています。つまりテキストのコンソール画面だけが使える状況です。その制約の中で「どこまでわかりやすくネットワークパフォーマンスを 計測できるか?」という課題があるのでした。

 自分が使っているのは speedtest と呼ばれるツールです。この導入から利用、そして実際の出力結果までを紹介します。

まず導入方法ですが、おそらく最も簡単で多くのケースで利用できるのが、この wget を使ったやり方です:
# cd /usr/local/bin
# wget -O speedtest-cli https://raw.github.com/sivel/speedtest-cli/master/speedtest_cli.py
# chmod +x speedtest-cli
上記例では /usr/local/bin という Path の通ったディレクトリにあらかじめ移動してから、そこにダウンロードしてくる、という方法を取っています。これで speedtest-cli という実行ファイル(実体は Python スクリプト)が用意できました。

そのまま(パラメータなしで)実行するだけでもアップロード速度とダウンロード速度を計測してくれます:
# speedtest-cli
Retrieving speedtest.net configuration...
Retrieving speedtest.net server list...
Testing from Kddi Corporation (XXX.XXX.XXX.XXX)...
Selecting best server based on latency...
Hosted by Too late (Ishikari) [847.06 km]: 38.316 ms
Testing download speed........................................
Download: 47.94 Mbits/s
Testing upload speed..................................................
Upload: 23.04 Mbits/s
# 

ダウンロードが 47.94 Mbps、アップロードが 23.04 Mbps という結果でした。まあこれは実行タイミングにも影響されると思いますが、1つの目安にはなると思います。

そして、このツールの特徴の1つでもある "--share" オプションがあります。これを付けて実行すると、実行結果を png 画像にして提供してくれます:
# speedtest-cli --share
Retrieving speedtest.net configuration...
Retrieving speedtest.net server list...
Testing from Kddi Corporation (XXX.XXX.XXX.XXX)...
Selecting best server based on latency...
Hosted by Too late (Ishikari) [847.06 km]: 38.316 ms
Testing download speed........................................
Download: 47.94 Mbits/s
Testing upload speed..................................................
Upload: 47.94 Mbits/s
Share results: http://www.speedtest.net/result/3980766722.png
# 

"Share results:" に書かれた URL にアクセスすると、このような画像が表示されます:


上記例は僕の自宅内のサーバーから行ったもので、契約している au ひかり(KDDI)から実行されたことも判別してくれています。また総合判断としての "GRADE: B" という記載もされています。

面白そうだったので、いくつかの環境から実行してみました:

(AWS EC2)


(DTI ServerMan/VPS)


(IDCF)



AWS の EC2 が "GRADE: A+" で速いことになってる!(悪意なし) ネットワークそのものは速いんでしょうかね、でも体感に直結しないのはやはり海外リージョンのせいなのか。。

そして IDCF クラウド、うちの au ひかりよりも速いってこと!? こうなると自宅サーバーで運用中のサービスの移行も検討しないといけないかな・・・


AWS(Amazon Web Services) のストレージサービスである S3。特定条件の中で利用する限りは無料になるし、容量1GBに付き月10円弱で使えるし、これ単体で静的なウェブホスティングにも使えるので、ちょっとしたファイル置き場以上の便利さがあります。

最近、この S3 をバケット単位でマウントできるという s3fs というツールの存在を知りました。その紹介です。

そもそも S3 をマウントできると何がうれしいのか?単なるファイル置き場というだけでなく、自分が最近使う機会の多い WordPress をクラスタリング環境にする際にネットワークマウントは必須になっている、という背景もあり、自分の場合にはそういったネットワークマウントのできるパブリックなクラウドストレージは WordPress と併用する環境としても魅力的なのでした。


ここでちょっとだけ脱線を。WordPress 自体はデータを RDB(一般的には MySQL)内に格納するので、クラスタリング環境を構築する上で特別意識することはないように思えます。ただし、ファイルをアップロードして利用する場合だけは注意が必要です。WordPress のファイルアップロード(メディアアップロード)では、アップロードされたファイルはファイルシステム上に移動されて、WordPress 自身はそのファイルパスの情報だけを格li納します(つまりバイナリの情報はDBには格納しません)。

この挙動は WordPress が1台の HTTP サーバー環境で稼働する場合は大きな問題にはなりにくいと思っていますが、例えば2台の HTTP サーバー(A, B) でクラスタリング環境を構成していた場合で考えると問題が浮き彫りになります。

仮に2台のうちのサーバーA上で、このメディアアップロードが実行されたと仮定します。サーバーA はアップロードされたファイルを自分自身の /var/www/html/wordpress/wp-content/uploads/ 以下に移動します。仮にそのファイル名が /var/www/html/wordpress/wp-content/uploads/aaa.jpg となったとします。

上記のように WordPress ではバイナリの情報は DB に格納せず、そのファイルパス情報だけを DB に格納します。つまりアップロードされたファイルは /var/www/html/wordpress/wp-content/uploads/aaa.jpg に存在する、という情報だけを DB に記憶することになります。サーバーA 内ではこれで問題になることはありません。

ところがクラスタリングのもう一台であるサーバーBも同じDBを参照しているので、サーバーBからも「該当ファイルは /var/www/html/wordpress/wp-content/uploads/aaa.jpg に存在する」と見えてしまします。このファイルはサーバーA のファイルシステムには保存されていますが、サーバーB には存在していません。したがって例えばサーバーB 上の処理でこの画像を表示させようとすると「ファイルが存在しない」ことになってしまいます。クラスタリングの振り分けはユーザーがコントロールできるわけではないので、ユーザーによってファイルが見えたり見えなかったり、ということが起きてしまいます。

これを解決するにはディレクトリを共有するしかありません。上記例であれば /var/www/html/wordpress/wp-content/uploads/ 以下が実際にはネットワークフォルダになっていて、その同じ箇所をサーバーA/B 双方からマウントして参照する、という構成になっている必要があるのでした。そしてそのようなネットワークフォルダをどうやって用意・調達するか、という問題に直面することになるのでした。


少し脱線しましたが、こんな背景の中で「無料でも使える AWS S3 がマウントできる」というのはかなり魅力的な情報なのでした。早速試してみたので以下にその手順を紹介します:

まずは S3 側の準備をします。仮に "awsuser1" という名前のバケットが S3 上に作成済みであると仮定し、このバケットを共有する前提で紹介します:
2014031201


必要な設定は、このバケットに接続するための認証ユーザーの作成です。既に別の AWS サービス用などにユーザーを作成済みであればそのユーザーを流用しても構いませんが、ここでは S3 アクセス用のフル権限を持ったユーザーを新規に作成することにします。

AWS のサービス一覧から IAM を選択します:
2014031202


左ペインで Users を選択し、"Create New Users" ボタンをクリックします:
2014031203


(名前自体はあまり重要ではないので)適当な名前のユーザーを作成します:
2014031204


作成直後のダイアログの "Show User Security Credentials" をクリックして展開します:
2014031205


展開後に表示される "Access Key ID" と "Secret Access Key" 両方の値をメモするかダウンロードして、後から参照できるようにしておきます。記録できたら "Close Window" でこのダイアログを閉じます:
2014031206


次にこのユーザーに S3 へのアクセス権を付与します。左ペインで Users が選択された状態に戻ります。ここで作成したユーザーを選択し、右下のユーザー詳細情報ペインでは "Permissions" タブを選択します。その中の "Attach User Policy" ボタンをクリックします:
2014031207


アクセス権指定のダイアログが表示されます。Select Policy Template と書かれたリストの下の方に "Amazon S3 Full Access" という列があるので、この右の "Select" ボタンをクリックします:
2014031208


確認画面になるので "Apply Policy" をクリックします。これでこのユーザーは S3 へのフルアクセス権を持ったことになります:
2014031209




次はマウント元側の設定です。今作成した(S3 へのフルアクセス権を持った)ユーザーでマウントするための設定を行います。まずインターネットに接続された Linux を用意します。以下 CentOS を使っている前提で紹介しますが、ディストリビューションによる可不可は特にないと思っています(AWS のインスタンスでも、そうでなくてもできます)。

まず事前準備として必要そうなライブラリを導入しておきます:
# yum groupinstall "Development Tools"  (C/C++ コンパイル環境を導入)
# yum install openssl-devel (libcrypt 0.9 を導入) # yum install libcurl-devel (libcurl 7.0 を導入) # yum install libxml2-devel (libxml-2.0.2.6 を導入)

上記3ライブラリに加えて fuse 2.8.5 が必要になります。AWS の EC2 インスタンスからは普通に yum でインストールすることもできます(yum install fuse fuse-devel)が、yum でインストールできないケースも多いのでビルド手順を紹介します。
# cd /usr/local/src
# wget http://sourceforge.net/projects/fuse/files/fuse-2.X/2.8.5/fuse-2.8.5.tar.gz
# tar xzvf fuse-2.8.5.tar.gz
# cd fuse-2.8.5
# ./configure --prefix=/usr
# make
# make install
# ldconfig
# modprobe fuse

fuse までが導入できると s3fs のビルド条件がそろったことになります。以下の手順で s3fs をビルドします:
# cd /usr/local/src
# wget http://s3fs.googlecode.com/files/s3fs-1.61.tar.gz
# tar xzvf s3fs-1.61.tar.gz
# cd s3fs-1.61
# export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/lib64/pkgconfig/
# ./configure --prefix=/usr
# make
# make install

これで s3fs のインストールが完了しました。最後に S3 へアクセスするためのユーザーの設定を行います。/etc/passwd-s3fs というファイルを、上記ユーザー作成時にメモした Access Key ID と Secret Access Key を使って、以下のような内容で新規に作成します(カッコは不要です):
# echo '(Access Key ID):(Secret Access Key)' > /etc/passwd-s3fs

仮に Access Key ID が ABCD で Secret Access Key が wxyz だった場合、/etc/passwd-s3fs の中身は以下の一行になります:
ABCD:wxyz

このファイルは他者から参照できないようにする必要があるため、ファイルパーミッションを変更します:
# chmod 640 /etc/passwd-s3fs

マウント先のディレクトリを用意します。ここでは /mnt/s3 というディレクトリに S3 をマウントすることにします:
# mkdir /mnt/s3

これで全ての準備が整いました。S3 の awsuser1 というバケットを /mnt/s3/ にマウントするには以下のようなコマンドを実行します。バケット名やマウント先は環境に合わせて適宜変更してください:
# s3fs awsuser1 /mnt/s3/ -o allow_other,default_acl=public_read

結果はこんな感じになりました。S3 って容量としては 256TB も用意されてるんですねw:
2014031210


再起動時にもこのマウントを有効にするには、同じコマンドを手動で再発行するのではなく、 /etc/fstab に以下の1行を追加記述するのがいいと思います。これもバケット名やマウント先は環境に合わせて適宜変更してください:
s3fs#awsuser1 /mnt/s3 fuse allow_other,default_acl=public-read 0 0


こんな感じで S3 をファイルシステムにマウントできることがわかりました。後は WordPress をクラスタ環境で使う場合は、メディアアップロードのディレクトリをこのマウント先にしておけば、同じイメージをクローンしてもクローン先でも同じ S3 を参照することになるので上述のような問題を回避できることになります、たぶん。





 

このページのトップヘ