はやさがたりない。

へっぽこぷろぐらまのメモログ

Amazon SQSのテストでelasticMQを使おうとしてちょっとハマった話

最近はもっぱら AWS を使ったサービスの開発をしている。
あいかわらず、サーバサイド(Java)の開発+ちょっとインフラも。

さてさて、今回は Amazon SQS を使うことになった。
SQS周りの単体テストをしょうということで elasticMQ っていう子を使うことになりました。

adamw/elasticmq · GitHub

今回はその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を流すと下の流れでテストが動く。

  1. RESTのテスト
    1. APIのテストを実施(この中でプロセスElasticMQにメッセージを発行)
  2. 単体テスト
    1. テスト内でElasticMQ起動
    2. ElasticMQに接続してキューを削除(しているつもりだった)
    3. テストで起動したElasticMQにメッセージを発行
    4. メッッセージの確認(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」 だから?<--多分こっち (ここわかってないのでインフラ先生に教えを乞おう)

キューへのアクセッサーはシングルトンなので接続状態とかテストをどうやって実行するかも関係してて

  1. RESTのテスト
    1. APIのテストを実施(この中でプロセスElasticMQにメッセージを発行)
      (ここで「*.9324」へのコネクションを確立している)
  2. 単体テスト
    1. テスト内でElasticMQ起動
    2. ElasticMQに接続してキューを削除(しているつもりだった)
      (ここは「127.0.0.1.9324」へ接続、消しているつもりになっていた)
    3. テストで起動したElasticMQにメッセージを発行
      (こっちは「*.9324」に接続している)
    4. メッセージの確認(APIテストのメッセージが残ってる!!)
      (こっちは「*.9324」に接続している)

ということで失敗してしまっていた様子。

今回の対処方法は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の実行対象サーバ側で

--

> python
> import yum

--

とするだけでもエラーとなった。

 

この事象を回避するには、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週間ごとにやることを決めているだけな感、それじゃそんなに意味なくない?

ぬあああああ、結論、「進捗管理」のためのイテレーションになっているのでなくすことはできない思います。

なくすためにはお客さん、さらにはその先の先まで思想の共有をして納得してもらって
もっと透明性のある情報共有を行なっていく必要がある。

とは言ってみたが

個人的になくすことは賛成。
進捗管理なんて、エンドユーザからしたら何の意味もない。
大型リリースとかならともかく、細かい改善やバグフィックスは許可なんて得ないでどんどん出していけばいい。 もっと意味のあることに時間を費やすべき。
自由にやらせた方がいいものができるんじゃない?(→これは妄想かもしれぬ) そのためにいろんな仕組みが必要になると思うけど、自分がこっちのほうがいいと思った以上それに向けて頑張る。

elasticsearch 勉強会 第6回

Aggregationあれこれ

  • Facetはdeprecated。2.X系でなくなるらしい
  • Group by color : Bucket
    検索結果のドキュメントを分類
  • Count(color) : Metric
    Bucket内のドキュメントのデータをもとに計算
    ドキュメント数、平均値や最大値など
  • shard毎にAggsして、最終的にノードがマージする
    検索と同じ仕組み、クエリフェーズで実行
  • post_filterはAggsの影響を受けない
  • filterr aggsはAggsのみに影響して、検索結果には影響しない
  • Bucket
    • terms Facetの代わり、結果は近似値
      shard毎で最初に足切りされている。shard_sizeを使うとチューニングできる
    • significant terms
      異常検知、レコメンドなどに利用?
    • keydクエリ
      結果にkeyをつけて名前がわかりすくできる
  • Metric
    • stats はmin/max/avg/sum
    • cardinality SQLのDistinct
      近似値(HyperLogLog++) 最大40,000まで指定可能
      precision_threshold あげるとメモリを消費する
    • persentiles パーセンタイル
      compressionでメモリ使用量を調整可能
    • top-hits ★ $expand ?! グルーピングされた検索結果(Filed Collapsing)に検索できる
      Bucket内のドキュメントを結果として出力
      メモリを食うらしい。
    • scripted metrics 1.4.0で導入予定

秒間3万の広告配信ログをElasticsearchでリアルタイム集計してきた戦いの記録

  • ディスプレイ広告配信DSP Smalgo
  • 広告主 -> DSP -> アドネットワーク/SSP -> ユーザ
  • impression / click / conversion それぞれでログを出しており
    FluentdでElasticsearchに入れる
  • mark 行動履歴もログに落とし込んでElasticsearchに入れる
  fluentd 10node -> ELB -> | Elasticsearch coordinate Node  (write)   2node r3.large
  kibana         -> ELB -> | Elasticsearch Data Node        (read)    2node r3.large
                           | Elasticsearch searchNode                28node
                           |     12shard 1replica r3.xlarge / 1GB SSD
  • kibanaはエグイクエリを発行するので使いすぎると負荷が上がるw
  • 柔軟だがインデックスとドキュメントの設計は大事
  • 1日1.5TB (primary & replica)
  • データドライブのEBSをSSDに変更して高速化
  • 検索処理のキャッシュ化(ElastiCache)
  • バージョンアップの話はうちでも使えそう
  • indexingのパフォーマンスアップ -> johtaniさんのブログ

Elasticsearch日本語スキーマレス環境構築と、ついでに多言語対応

  • dynamic templates & index templates を駆使する
  • dynamic templates
    • 最初にマッチしたtemplatesが使われる
  • index templates
    • nodeの再起動は必要なく、新規で作成したインデックスのみに適用される
    • _analyzer path langage
      -> 多言語対応の部分は後で見たい

elasticsearchソースコード読みはじめてみた

非常に勇気をもらえた。
おらでもソースを読めそうだ!?

  • クエリを受けて結果を返す部分から読むのがベター と言われたものたどりつくのも大変!
  • ノード起動から導入した時のお話

reroute APIを使用してシャードの配置を制御する (LT)

  • 複数シャード移動のはまりどころ
    自動再配置に注意!自動再配置を抑止するべし。
  • Bonsai is cool !!
  • shardの移動でRemoteTransportExceptionが頻発
    (shardが多すぎる?)

タグを振って配置することもできる(whereness?)

検索のダウンタイム0でバックアップからIndexをリストアする方法 (LT)

  • snapshot & resotre api
  • 無停止でバックアップできる!
  • リストアにはIndexをいったん削除 or closeする必要がある!無停止できない!
  • index alias & restore api rename_replacement field
  • リストア実行後にAliasの削除! → include_aliases : false

サーバ・インフラエンジニア養成読本 ログ収集~可視化編 勉強会

最近、行ってきたブログばかり。。。
もうちょいがんばりたい。。。

サービス改善はログデータ解析から

すずけんさん @suzu_v adingo

  • 分析はコアだ
  • データの分析はチームで作るもの
    そして、データを活かせるようにするエンジニアが必要
  • 収集、変換、保存、分析、表示、運用
  • 「ログ分析は後にして機能追加をしましょう」ありがち
  • とりあえずやってると何とかなる
    可視化してから考えよう
  • チームとして「データを活かそう」というスタンスにならないと進まない

Fluentd

よしけんさん @yoshi_ken y-ken リブセンス

  • 再送処理など、ネットワーク周りの例外は任せられる
  • Rubyを用いたプラグイン記述のハードルは低い
  • ログ収集コストの最小化
    時差もなくなる
  • tailプラグインはファイルのローテーションにも対応
  • レイテンシの改善、帯域バーストの緩和
  • ファイルやDBといった複数データストアへの保存も可能
  • QoS レベル At Most One
  • 変更のないシンプルな処理のみを担うといい
  • 各ノードは単一責任がいい
    • 転送元ノード
    • 集約ノード(Aggregator)
    • Processor
    • Watcher
  • シングル構成や複数構成も組める
  • 固い運用には向き不向きがある

Elasticsearchもうちょっと入門

@johtaniさん

  • サジェストもあるんだ
  • クラスタの監視もできる?
  • Logstash 1回 Redisにため込む!?
  • aggregation
    • 階層的な集計、グループ化
    • 動的な集計、グループ化
    • Bucket ドキュメントのある値ごとに結果をグルーピング
      男性、女性など
    • Metric ドキュメントの持つ値を集計
      ツイートの文字数の平均、最大値最小値とか 

Kibana

みちいしゅんすけさん @harukasan pixiv

  • 17回/1日 デプロイ
  • グロースチーム
    • サービスのグロースのためになんでもやる人たち
  • 可視化も継続的デリバリーの手段の一つ
  • fluent-plugin-elasticsearch作者
  • 3割くらいが使っている
    • クエリ:ログを検索
    • フィルタ:すべてのクエリに適用
    • パネル:どう表示するか
  • Dashboard
    見たい数値が1画面に収まっている
    1つのデータに対して複数の面から分析する
    毎日・毎週継続して変化をみることができる
  • タグ deployとかイベントを
  • Trends 1週間前との傾向

  • つくってから「Share」で一時URL
    ミーティングなどで見るようにする

  • GoogleBigQueryを間にかましてデータ量を絞る

パネルディスカッション

  • サーバ/インフラエンジニア?

    • 趣味でいれた
    • ログエンジニアがいた
  • ログ解析

  • 前はGoogleAnalyticsとか、体系化された方法があったわけではないと。

    • GrowthForecastとか
    • DataWareHouse / BI (たぶろー)
      • EFK は DataWareHouseのモダン版
  • データどうしてる?

    • ため込んだやつ消してます or 閉じてしまう
    • 生データはS3
    • 直近版と長期版2段階構成が定番
  • A・Bテストしてたら数値しか見なくなった
    直感というか感覚も大事。数値は一つの指標

  • Elasticsearch使うならmemoryはつめ!

  • 認証方法

    • LDAP認証
    • メソッドをふさぐ
    • @typesterさん Googleアカウントでできる認証Proxyを作ったのでそれを使うのもあり