serverless はまった
serverlessはnode v4以上必須なのだが
lambdaのnodeはv0.10なので
classとか使うと怒られます。
ローカルのテストの意味が。。。ねぇ!!
serverlessで一つのfunctionをrunする方法
公式ドキュメントには
sls function run myModule/myFunctions#functionOne
って書いてあるけど実際にそれでやっても
Serverless: Select a function to run: myFunctions > functionOne functionTwo
ってなっちゃうのでもやもやしてた。
こう書いたら選択しなくてもテストできるのですな。
sls function run -n functionOne
serverless さわってみた
所感
serverless (旧名JAWS)の使い勝手を調べてみた。
結果としては割といい感じ。
serverlessならansibleとかもいらなくなる!
AWSのリソースもserverlessの中のCloudFormationでOKだぜ!!みたいな。。?
まだまだドキュメントは少ないけど、もうちょっと勉強していこうと思う。。
手順
初期セットアップ
※Node 4系以上が必要
$ sudo npm install serverless -g
$ mkdir ~/.aws
$ vi ~/.aws/credentials
--
[default]
aws_access_key_id=<<アクセスキー>>
aws_secret_access_key=<<シークレットアクセスキー>>
--
$ vi ~/.aws/config
--
[default]
region = ap-northeast-1
--
作ってみる
$ serverless project create
_______ __
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v.0.0.12
`-------'
Serverless: Enter a project name: (serverlessN1A2rULrx) akira-test
Serverless: Enter a project domain (used for serverless regional bucket names): (myapp.com) akira-test.com
Serverless: Enter an email to use for AWS alarms: (me@myapp.com)
Serverless: Select a region for your project:
us-east-1
us-west-2
eu-west-1
> ap-northeast-1
Serverless: Select an AWS profile for your project:
> default
Serverless: Creating a project region bucket on S3: serverless.apnortheast1.akira-test.com...
Serverless: Creating CloudFormation Stack for your new project (~5 mins)...
Serverless: Successfully created project: akira-test
- 作られたもの
- S3
- IAM Group
- IAM Role
- ディレクトリ構成
-rw-r--r-- 1 arika staff 11 12 13 21:38 README.md
-rw-r--r-- 1 arika staff 136 12 13 21:38 admin.env
drwxr-xr-x 4 arika staff 136 12 13 21:38 back
drwxr-xr-x 3 arika staff 102 12 13 21:38 cloudformation
drwxr-xr-x 2 arika staff 68 12 13 21:38 plugins
-rw-r--r-- 1 arika staff 495 12 13 21:41 s-project.json
CloudFormationでIAMあたりを作っているっぽ。S3は別。
CloudFormationのテンプレートが自動生成されて、そこにIAMのロールやらの定義が書かれている。
んで、おそらくここにAWS elsaticsearchの設定とかを書いておいてserverless resources deploy
ってやるとデプロイされる、とかができるための仕組みだと思う。
AWSのリソースの管理もできるということですね。素晴らしい。
モジュールとかファンクションとかを作る
$ serverless module create -m greetings -f hello
Serverless: Successfully created hello function.
Serverless: Installing "serverless-helpers" for this module via NPM...
serverless-helpers-js@0.0.3 node_modules/serverless-helpers-js
└── dotenv@1.2.0
Serverless: Successfully created new serverless module "greetings" with its first function "hello"
$ ls -l back/modules/greetings/
total 16
drwxr-xr-x 5 arika staff 170 12 13 21:49 hello
drwxr-xr-x 3 arika staff 102 12 13 21:49 lib
drwxr-xr-x 3 arika staff 102 12 13 21:49 node_modules
drwxr-xr-x 2 arika staff 68 12 13 21:49 package
-rw-r--r-- 1 arika staff 359 12 13 21:49 package.json
-rw-r--r-- 1 arika staff 277 12 13 21:49 s-module.json
backっていうディレクトリの下にhelloっていうのができて、
そこのhandler.jsってやつがメイン処理っぽい。。。?
'use strict';
/**
* Serverless Module: Lambda Handler
* - Your lambda functions should be a thin wrapper around your own separate
* modules, to keep your code testable, reusable and AWS independent
* - 'serverless-helpers-js' module is required for Serverless ENV var support. Hopefully, AWS will add ENV support to Lambda soon :)
*/
// Require Serverless ENV vars
var ServerlessHelpers = require('serverless-helpers-js').loadEnv();
// Require Logic
var lib = require('../lib');
// Lambda Handler
module.exports.handler = function(event, context) {
lib.respond(event, function(error, response) {
return context.done(error, response);
});
};
...いや、こっちか?でもlibの下にメイン処理があるもんか?
おそらくhandlerはいじらずここだけ意識していじればいいぜって感じか?
/**
* Lib
*/
module.exports.respond = function(event, cb) {
var response = {
message: "Your Serverless function ran successfully!"
};
return cb(null, response);
};
lambdaへのデプロイ
$ serverless function deploy
Serverless: Deploying functions in "development" to the following regions: ap-northeast-1
Serverless: Successfully deployed functions in "development" to the following regions: ap-northeast-1
api gatewayへのデプロイ
$ serverless endpoint deploy
Serverless: Deploying endpoints in "development" to the following regions: ap-northeast-1
Serverless: Successfully deployed endpoints in "development" to the following regions:
Serverless: ap-northeast-1 ------------------------
Serverless: GET - https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/development/greetings/hello
ローカルでのテスト
ローカルでのテストも簡単にできるのは素晴らしい。
$ serverless function run
Serverless: Running GreetingsHello...
Serverless: -----------------
Serverless: Success! - This Response Was Returned:
Serverless: {"message":"Your Serverless function ran successfully!"}
リンク集
http://docs.serverless.com/v0/docs
http://qiita.com/mokemokechicken/items/f81c886053f7d81a655d
elasticsearch勉強会
elasticsearch勉強会
percolatorのユースケース
アラート
インデックスが特定のクエリにマッチしたら教えてくれ。広告出稿する場合
ユーザがサイト検索する
アパートを検索して結果を表示するが
新しいマッチする物件が出たら知りたい
どのメールに通知すればいいのかみたいなのを取得して通知することができる分類
ニュースサイトやブログがあってカテゴリわされている
カテゴリは検索として表現できる
ニュースに地域などの属性があれば東京のニュース一覧とかできる
どの記事がどの地域に属するかというのを設定するにはどうしたら良いか
percolation queryを使えばどの記事がどの地域に属するかということを簡単に設定できる。
記事をかいてpercolationを使えばその記事のカテゴリを得られるgroclassificationについて
例えば緯度経度を使って検索することもできるけど検索はめんどい
percolationを使ってこのお地域はどの地域内にあるみたいなことも。言語の検出にも使える
日本語は簡単だけどラテン語なんかは難しい
特定の言語固有の単語などもあるのでこの言語にしかない単語をpercolationクエリとして
設定しておけば言語判別できるpercolatorにはメタデータを設定できる
いつそのクエリが保存されたのかなどなど
課金している人にのみ通知したい場合、課金しているかという情報もメタデータになる
そのメタデータによって通知の頻度を変えるとかもできるハイライトをできる
特定のトピックについて通知をしてもらいたい場合
トピックをpercolatorとして保存しておいて結果をハイライトできる
これが reverse search
esとRDBMSを検索するのはどう違うか
単にマッチするかどうかだけでなく、関連性も検出できる
TF-IDF
TF term frequency : 単語の出現頻度、頻度により関連性を調べられる。
IDF : どれくらいドキュメント内でレアかどうか
例えばisとかtheとか検索してもほぼ全部のドキュメントに出てくるので
あんまり関連性の重要性には寄与しない。
luceneはTF-IDF以外にもフィールドの長さを加味する
東京の本で東京について検索した場合たくさんヒットするけど
その中のタイトルでヒットすれば関連性が高いと言える
function scoreという機能を使えばドキュメント自体に
格納されていない情報も検索のタイミングでスコア算出につかうことができる
映画を検索した場合、映画のレビュー情報も算出できる。
レビューの星の数だけでソートしないほうがいいですね?
それだけでランクが決まってしまうので。
でも少しだけ順序に入れると良い。。
ホテルを検索する例
grand hotelというホテルを検索
指定した地点から1km以内がいいと指定した場合、1km以内であれば完全にマッチとするけど
そこから離れていても検査くっかに入れる
バルコニーが欲しいと指定した場合、バルコニーがなくても検索結果に入れる
でもバルコニーがあればより検索結果の上位に出すようにする
populartyというフィールド(レビュー)もランクに加味する
さらに幾分ランダムも入れる。つど発見があるように。
これらのウェイトはチューニング可能。
esは単語の頻度だけではなくいろんな情報を持っている。
aggregationについて
facetsともいう。
githubの検索結果の左側のようなやつ。
検索結果の中から検出したものでオーバービュートなる(どの言語がどれくらいあるかとか)
esを使うことで多次元の情報を見ることができる。
グラフ化するだけならRDBMSでもでk里う。
レコメンデーション
音楽について、特定のアーティストをlikeしているかどうか。
誰がどのアーティストをlikeしているのかという情報を格納する。
レコメンドする方法としてアーティストを検索して
さらにアーティストをlikeしている人を算出。
でも人気は必ずしも寒冷生徒はなりません。
termsでaggregateする代わりにsignificant term というものを使う。
これはaggregationの一種で単に人気があるということだけでなく、
特定のグループ内で突出しているものを調べられる。
アーティストを、誰が、likeしているのかという情報持っているし、
転値インデックスもあるので検出できる。
バンドをlikeした人数と、その検索termでlikeした人数を比較すれば
突出したものを検知することができる。sampler aggregation es2.0の新機能
例えば1ユーザにつき1ドキュメントだけ、とかできる。
1ユーザが何百ドキュメントを持っている場合効率的。
自分と同じものをよりたくさんlikeしている人は近い傾向を持っているとわかる。
誰もが好きなバンドをlikeしているというのはあまり参考にならないが
レアなバンドであれば大変好みが近いと言える(TF-IDFの応用)
sampler aggregationを使えばより効率的に、すばやくレコメンデーションできる。wikipediaの記事をグラフ化した場合、各記事同士がたくさんリンクしている。
共通のコネクションが大事。
たくさん調べればスーパーノード(共通してリンクしているノード、記事)がわかる
でも、人名が人物とリンクしているという情報なんかは意味があまりない。カンファレンスで、どのwebサイトによく行きますか?と聞いたら
githubとかstackoverflowと答えが出るでしょう。
googleではなく、これがカンファレンス特有の答えです。人間が、世の中をどういう風に見ているのかと同じ考え方。
データを期間で区切って調べる(週とか時間とかで)
signficant term を調べたら何が得られるか?例えばハッシュタグで。
その日で他の人に比べてたくさん使われているハッシュタグがわかる。
トレンドがわかる。
情報は力です。esを使えばよりたくさんの情報が得られる。
next stack
Amazon SQSのテストでelasticMQを使おうとしてちょっとハマった話
最近はもっぱら AWS を使ったサービスの開発をしている。
あいかわらず、サーバサイド(Java)の開発+ちょっとインフラも。
さてさて、今回は Amazon SQS を使うことになった。
SQS周りの単体テストをしょうということで elasticMQ っていう子を使うことになりました。
今回はそのelasticMQの使い方でちょっとハマっている話。
elasticMQはAmazonSQS互換のインターフェースを持っている子で起動の仕方は大きく2種類ある。
Readmeにも書いてあるけども
プロセスとして起動する方法
java -jar elasticmq-server-0.8.8.jar
JUnitとかのテスト内で起動する方法
val server = SQSRestServerBuilder.start() // ... use ... server.stopAndWait()
ローカル環境で開発するときにはプロセスとして起動しながらサーブレット起動して動作確認したり。
JUnitでの単体テストのときはテスト内で起動したり。そんな感じで使ってる。
で、CI環境では(ちょっとテストがいけていないっていうのもあるけども)
プロセスが起動してあることが前提で動くAPIのRESTテストと
テスト内で起動して動作確認をする単体テスト両方が動く。
この時にテストの中でキューのメッセージを消しているはずなのに消せない!って問題が起きた。
というかそもそもキューがない!って言われる。
流れはこんな感じ。
maven testを流すと下の流れでテストが動く。
- RESTのテスト
- APIのテストを実施(この中でプロセスElasticMQにメッセージを発行)
- 単体テスト
- テスト内でElasticMQ起動
- ElasticMQに接続してキューを削除(しているつもりだった)
- テストで起動したElasticMQにメッセージを発行
- メッッセージの確認(APIテストのメッセージが残ってる!!)
ちゃんとした原因は、まだわかっていないんだけども
$ netstat -an | grep 9324 tcp46 0 0 *.9324 *.* LISTEN <---- プロセスで起動したElasticMQ tcp4 0 0 127.0.0.1.9324 *.* LISTEN <----テスト内で起動したElasticMQ
このように起動したプロセスが同じポート使って別ヤツもので動くっぽい。
ポートってぶつかってたらダメなやつだと思っていたけども
「tcp46」と「tcp4」だったら別ヤツでうごけるの?
それともアドレスが「*」と「127.0.0.1」 だから?<--多分こっち
(ここわかってないのでインフラ先生に教えを乞おう)
キューへのアクセッサーはシングルトンなので接続状態とかテストをどうやって実行するかも関係してて
ということで失敗してしまっていた様子。
今回の対処方法は2つ?
1つ目
- プロセス起動側の設定ファイルを指定する(elasticMQのReadme 参照)
bind-hostname = "127.0.0.1"
- テスト内の起動時にすでにプロセス側が起動していたら(java.lang.RuntimeException: Binding failed.例外が発生したら)スルーする。
2つ目
- テスト内の起動時にインターフェースを「"0.0.0.0"」で設定して、 すでにプロセス側が起動していたら(java.lang.RuntimeException: Binding failed.例外が発生したら)スルーする。
SQSRestServerBuilder.withInterface("0.0.0.0").start();
1つ目のやり方だと他の人にも影響がでてしまうので2つ目のやり方で試してみようと思う。
Amazon Linux で yum update したら Ansible が動かなくなった
今日Amazon Linux 上でAnsibleを実行したら
--
ImportError: No module named yum
--
とか言われて動かなくなった。
つい先日まで動いていたのに、なんでやねんとおもいつつ調べてみたら
どうやら Amazon Linux 2015.03 がリリースされていて色々と変わっていたらしい。
(何でこんなタイムリーなんだ…と思いつつ)
Amazon Linux AMI 2015.03 Release Notes
今回問題になったのが 「Python 2.7 by default」となったこと。
Ansible で yum update を実行しているのだけど
それでpythonのバージョンが上がっていた。
バージョンが上がっても普通に動いてくれればいいんだけど、
python2.6側が動かなくなっているみたいで
Ansibleの実行対象サーバ側で
--
--
とするだけでもエラーとなった。
この事象を回避するには、Ansibleの実行対象サーバ側で
sudo alternatives --set python /usr/bin/python2.7
としてあげれば動くようになった。
Ansible側で
--
ansible_python_interpreter="/usr/bin/python2.7"
--
とやっても動きました。
しかしどうも、なんだかなぁという感覚なので
今回は yum updateでアップデートしないようにした。
/etc/yum.conf の
---
releasever=latest
---
を
---
releasever=2014.09
---
のようにしてあげれば、リポジトリ先を指定することができて
pythonが上がらないようにできる。
もうちょっと様子見てからどうするか考える。
イテレーションについて考える
最近うちの上司がイテレーションをなくしたいということを言っているので、
なくすことによってどんなメリットがあるのか、
そもそもなんでイテレーションが存在するのかについて考えてみることにする。
イテレーション
うちは2週間でイテレーションを区切っている。BtoBtoC。
最初に計画を立てて、物を作り、最終テストをしてリリースする。という流れ。
イテレーションとはつまり期限を決めることか?
違う、イテレーション=反復という意味らしい。
イテレーションがあることによるメリット
顧客と開発者、両方の目線で考えて見る。
顧客からの視点
ある程度、いつまでにできるかわかる
これはどうだ?そもそも、今のうちのやり方がおかしいからこういう発想になるのではないか?計画、レビューのみ参加するってことができる
がっつり入り込めない忙しい人には嬉しいのかもしれない。
でもこれもちがう、ダメだと思う。
開発者の視点から
開発リズムができる
計画を全員で立てればなんとなく全体の状況が把握できる。終わったーっていう達成感とか。
あとは、この日までにここまでやらなきゃいけないという気持ちにさせてくれる。進捗を管理できる
もう完全に何のためだかわからなくなってきた。
イテレーションがないことによるメリット
顧客からの視点
- できたものがすぐに提供できる
イテレーションで区切ると最後のタイミングで一斉にリリースってなるけど、それがなくなる感じ。
開発者の視点から
期限に間に合わせようと品質を犠牲にしなくなる
やはりなんとか間に合わせようとしてしまうことはある。物を作る、以外の付加価値作業ができる ここまでにこれ終わらせなきゃ、ってならないと
なんかこの作業いつもめんどくさいから自動化するかって発想になりそう。
自分が作ったものの使われ方とか気になって、ログ解析とかしそう。
いや、ちゃんと顧客にその価値を伝えてやらせて貰えばいいんだけど、進捗を管理しなくていい
ちょっと言い過ぎかもしれないけど。
でもさぼるやつでそう。俺みたいな。
現状を踏まえての結論
今のままではイテレーションをなくすことはできないんだと思う。
「相手にこの機能をここまでに出します」って約束しちゃってるから、
そうするとイテレーションなりなんなりで進捗の管理をせざるを得ない。
でも、イテレーションがある意味があまりない、かな。
「不完全」な状態でも一旦見せて、フィードバックを受けて成長させるということができていないから。
最初から特定の機能をどーんと作って、それで終わり。というものが多い。
ちょこっとはフィードバック受けているだろうけども、なんか違う気がする。
ただ2週間ごとにやることを決めているだけな感、それじゃそんなに意味なくない?
ぬあああああ、結論、「進捗管理」のためのイテレーションになっているのでなくすことはできない思います。
なくすためにはお客さん、さらにはその先の先まで思想の共有をして納得してもらって
もっと透明性のある情報共有を行なっていく必要がある。
とは言ってみたが
個人的になくすことは賛成。
進捗管理なんて、エンドユーザからしたら何の意味もない。
大型リリースとかならともかく、細かい改善やバグフィックスは許可なんて得ないでどんどん出していけばいい。
もっと意味のあることに時間を費やすべき。
自由にやらせた方がいいものができるんじゃない?(→これは妄想かもしれぬ)
そのためにいろんな仕組みが必要になると思うけど、自分がこっちのほうがいいと思った以上それに向けて頑張る。