Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

87
LMQ でお手軽 分散システム開発 Developers Summit 2014 Summer @yosisa

description

夏サミ2014 【B-4】LMQでお手軽分散システム開発のスライドです

Transcript of Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Page 1: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

LMQ でお手軽分散システム開発Developers Summit 2014 Summer@yosisa

Page 2: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

自己紹介

— 田中 義久— Software Engineer

— Go / Python / Erlang / Swift

— Internet Initiative Japan Inc.

— Twitter: @yosisa

— GitHub: @yosisa

— Qiita: @yosisa

Page 3: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

社内での開発スタイル

— 新監視システム開発チーム— メンバー6人— GitHub Enterprise

— 内製の CI サーバ— Docker / GCE

Page 4: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

LMQLightweight Message Queue

https://github.com/iij/lmq

Page 5: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

LMQメッセージキュー written in Erlang

— プロセス間のデータの受け渡しに使う— REST 風の HTTP API で Put / Get

— キューなのでデータを保持する

Page 6: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

LMQ の目指すところ

— 使いやすい— 運用しやすい— 十分に速い— メッセージをロストしない

Page 7: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

開発の動機

Page 8: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

より良い監視システムを作る

Page 9: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

旧来の監視システム (1)

監視データをローカルに格納している。

例えば、N 回連続で監視失敗したらアラートをあげる設定の時、ローカルにある過去の監視データが無いと正確な判定ができない。

一度割り当てた監視ターゲットを別ホストに移すのが難しい。

Page 10: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

旧来の監視システム (2)

監視の系を二重化して障害に備えている。

通知が二重に出るのを防ぐために、集約処理をするプログラムがある。

Page 11: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

旧来の監視システム (2)

複数のアラートが起きた時に、通知が多数でるのを防ぐために、30秒~10分間の間でアラートを集約している。

集約プログラムにデータが流れてくると、再起動ができなくて、メンテナンスが難しい。

Page 12: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

旧来の監視システム (3)

監視・解析・アラート担当と、集約・通知担当の二段構成。

✘監視の生データを別の用途に使う✘システムの一部だけリプレースする

Page 13: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

旧来の監視システム (4)

もう8年くらい動いてる。

つまり、ベースのコードは相当古い。

テスト?なにそれおいしいの?

建て増しに次ぐ建て増しでカオス。

亜種がたくさんあってカオス。

Perl と C で書かれてて\(^o^)/

Page 14: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

まとめると

Page 15: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

もうこれ以上

面倒みたくない!

Page 16: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

\(^o^)/

— メンテナンスがすごく大変— 設計や実装が古くて時代にそぐわない— デプロイが職人芸と化していて、デプロイしたくないからコード書きたくない

— でも新たな要求はやってくる

Page 17: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

でも新たな要求はやってくる

Page 18: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

なら

作るしかないじゃない

Page 19: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

新監視システム

毎分 10万 IPアドレスを監視できて、

監視ホストを追加するだけでスケールして、プロセスの再起動に気を遣わなくてよく、

容易に機能追加できる拡張性のある、

近代的な開発手法で作られた、

そんな監視システム

Page 20: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発
Page 21: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

おわかりいただけただろうか?

Page 22: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

大規模監視システムを支える

LMQ

Page 23: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

LMQ の特徴

Page 24: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

LMQ の特徴

— HTTP REST API

— シングル構成 / 冗長構成が可能— 名前をつけて複数のキューを作成できる— キューの自動生成— タイムアウトベースのメッセージ再送— 時間ベースのメッセージ集約

Page 25: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Erlang/OTP の特徴

— 関数型言語— 軽量プロセスモデル— Shared Nothing

— プロセス間のメッセージパッシング— マルチコアを有効活用— ネットワーク系の機能が Built-in

Page 26: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

RabbitMQ との違い

Page 27: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発
Page 28: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

GettingStarted

Page 29: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

インストール

Erlang/OTP R16B01 以上が必要$ git clone https://github.com/iij/lmq.git$ cd lmq$ make rel

Page 30: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

起動

$ rel/lmq/bin/lmq start

動作確認

$ rel/lmq/bin/lmq pingpong

Page 31: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Basic API

Page 32: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Put APIPOST /messages/:name

キューにメッセージを追加する

POST /messages/greeting HTTP/1.1content-type: text/plain

Hello, world!

HTTP/1.1 200 OKcontent-type: application/json

{"accum": "no"}

Page 33: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Get APIGET /messages/:name

キューからメッセージを取り出す

GET /messages/greeting HTTP/1.1

HTTP/1.1 200 OKcontent-type: text/plainx-lmq-message-id: e93fd6b1-d408-4ecb-9f6b-d3eeebce34c1x-lmq-message-type: normalx-lmq-queue-name: greeting

Hello, world!

Page 34: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Reply APIPOST /messages/:name/:msgid?reply=:type

メッセージの処理結果を通知するtype は ack, nack, ext の3種類

— ack: 正常終了 -> メッセージを削除— nack: 継続不能 -> メッセージを戻す— ext: 処理に時間がかかっている

-> タイムアウトをリセット

Page 35: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Reply APIPOST /messages/:name/:msgid?reply=:type

POST /messages/greeting/e93fd6b1-d408-4ecb-9f6b-d3eeebce34c1?reply=ack HTTP/1.1

HTTP/1.1 204 No Content

Page 36: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Reply APIPOST /messages/:name/:msgid?reply=:type

POST /messages/greeting/e93fd6b1-d408-4ecb-9f6b-d3eeebce34c1?reply=ack HTTP/1.1

HTTP/1.1 404 Not Found

Page 37: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Multi Queue API

Page 38: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Multi Queue API

個々のキューを指定する代わりに、パターンにマッチする全てのキューを対象にする

API。

パターンは正規表現で指定する。

Page 39: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Put all APIPOST /messages?qre=:regexp

パターンにマッチする全てのキューにメッセージを追加する。

対象のキューはあらかじめ存在している必要がある。

Page 40: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Put all APIPOST /messages?qre=:regexp

POST /messages?qre=.* HTTP/1.1Content-Type: application/json; charset=utf-8

{"text": "added via multi queue api"}

HTTP/1.1 200 OKcontent-type: application/json

{ "greeting": {"accum": "no"}}

Page 41: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Get any APIGET /messages?qre=:regexp

パターンにマッチするいずれかのキューから取得

GET /messages?qre=.* HTTP/1.1

HTTP/1.1 200 OKcontent-type: application/json; charset=utf-8x-lmq-message-id: 7cdfc909-ae9c-4704-bfa2-fd99612103e8x-lmq-message-type: normalx-lmq-queue-name: greeting

{"text": "added via multi queue api"}

Page 42: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

ステータス

Page 43: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

ステータス確認

$ rel/lmq/bin/lmq-admin status All nodes: [email protected] nodes: [email protected]

greeting 1 messages 968 bytes accum: 0.0, retry: 2, timeout: 30.0

統計情報

$ rel/lmq/bin/lmq-admin statsgreeting push rate: 1min 0.00, 5min 0.00, 15min 0.02, 1day 0.20 pull rate: 1min 0.00, 5min 0.00, 15min 0.00, 1day 0.00 retention time: min 0.000, max 0.000, mean 0.000, median 0.000

Page 44: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

StatsD / Graphite / InfluxDB

StatsD へのメトリクス送信に対応

Graphite や InfluxDB に統計情報を集約することが可能

Page 45: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

タイムアウト

Page 46: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

タイムアウト

LMQ はメッセージが Get されてからの時間を管理している。

timeout 値を超えると、そのメッセージが正しく処理できなかったとみなしてキューに戻す。

キューに戻ったメッセージは、他のクライアントから Get できるようになる。

Page 47: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発
Page 48: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

メッセージの集約

Page 49: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

メッセージの集約

一定時間内に特定のキューに Put された全てのメッセージを集約して、時間経過後に1つのメッセージとして Get できるようにする機能のこと。

複数のコンテンツを含む以外は、通常のメッセージと変わらない。

キューのプロパティを設定して有効化。

Page 50: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発
Page 51: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

メッセージの集約

POST /messages/accum:seq HTTP/1.1Content-Type: application/json; charset=utf-8

{"id": 1}

HTTP/1.1 200 OKcontent-type: application/json

{"accum": "new"}

POST /messages/accum:seq HTTP/1.1{"id": 2}

HTTP/1.1 200 OKcontent-type: application/json

{"accum": "yes"}

Page 52: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

メッセージの集約

GET /messages/accum:seq HTTP/1.1

HTTP/1.1 200 OKcontent-type: multipart/mixed; boundary=fdaef3d8-934e-4272-b886-3f3212942f3bx-lmq-message-id: fdaef3d8-934e-4272-b886-3f3212942f3bx-lmq-message-type: compoundx-lmq-queue-name: accum:seq

--fdaef3d8-934e-4272-b886-3f3212942f3bContent-Type: application/json; charset=utf-8

{"id": 1}

--fdaef3d8-934e-4272-b886-3f3212942f3bContent-Type: application/json; charset=utf-8

{"id": 2}

--fdaef3d8-934e-4272-b886-3f3212942f3b--

Page 53: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

メッセージの集約

GET /messages/accum:seq?cf=msgpack HTTP/1.1

HTTP/1.1 200 OKcontent-type: application/x-msgpackx-lmq-message-id: e227d532-01e7-42a0-b1bc-bea8efc710e4x-lmq-message-type: compoundx-lmq-queue-name: accum:seq

����content-type�application/json; charset=utf-8�{"id": 1}���content-type�application/json; charset=utf-8�{"id": 2}

Page 54: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

キューのプロパティ

Page 55: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

キューのプロパティ

各キュー毎に動作をカスタマイズする仕組み。

— timeout: メッセージが再送されるまでの時間

— retry: メッセージの再送回数— accum: メッセージを集約する時間

Page 56: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

デフォルトプロパティ

パターンにマッチするキューのプロパティをまとめて設定する仕組み。

大量のキューを使い分ける時に、個別に設定しなくてすむ。

パターンは正規表現で記述する。

Page 57: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Property API

Page 58: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Get Queue PropertyGET /properties/:name

GET /properties/greeting HTTP/1.1

HTTP/1.1 200 OKcontent-type: application/json

{ "accum": 0, "retry": 2, "timeout": 30}

Page 59: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Update Queue PropertyPATCH /properties/:name

PATCH /properties/greeting HTTP/1.1Content-Type: application/json; charset=utf-8

{"accum": 30}

HTTP/1.1 204 No Content

Page 60: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Reset Queue PropertyDELETE /properties/:name

DELETE /properties/greeting HTTP/1.1

HTTP/1.1 204 No Content

Page 61: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Get Default PropertiesGET /properties

GET /properties HTTP/1.1

HTTP/1.1 200 OKcontent-type: application/json

[ ["^accum:", {"accum": 30}]]

Page 62: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Set Default PropertiesPUT /properties

PUT /properties HTTP/1.1Content-Type: application/json; charset=utf-8

[ ["^accum:", {"accum": 30}]]

HTTP/1.1 204 No Content

Page 63: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Set Default PropertiesPUT /properties

GET /properties/accum:notify HTTP/1.1

HTTP/1.1 200 OKcontent-type: application/json

{ "accum": 30, "retry": 2, "timeout": 30}

Page 64: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Reset Default PropertiesDELETE /properties

DELETE /properties HTTP/1.1

HTTP/1.1 204 No Content

GET /properties HTTP/1.1

HTTP/1.1 200 OKcontent-type: application/json

[]

Page 65: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

クラスタリング

Page 66: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

クラスタリング

障害対策に2つ以上の LMQ ノードを使ってクラスタを組むことができる。

マスターレスの実装。

キューの操作毎に sync する。

Page 67: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

クラスタリングクラスタに参加

$ rel/lmq/bin/lmq-admin join [email protected]

クラスタから離脱

$ rel/lmq/bin/lmq-admin leave

Page 68: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Performance

Page 69: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Single

Page 70: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Cluster

Page 71: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発
Page 72: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Demo

Page 73: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

ユースケース

Page 74: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

プロセス間の連携

Page 75: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

プロセス間の連携

Producer と Consumer を疎結合にできる。

どちらのプロセスも、いつでも再起動できる。

Consumer をサーバのようにする必要がない。

Consumer のキャパシティを超えても、Producer に影響しない。

Page 76: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

プロセス間の連携

Producer / Consumer を自由に増減できる。

Consumer を増やすだけで負荷分散できる。

Page 77: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

PubSub 風

Page 78: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

PubSub 風

Notifier は event:.* パターンを使って1度だけ Put すればよい。

Event Handler は

event:<hostname> から

Get する。

Event Handler が一時的に

down していても取りこぼさない。

Page 79: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

バッチ処理

Page 80: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

バッチ処理

流れてくるメッセージをある程度まとめてから処理できる。

1秒間まとめるだけでも、後段の処理が 60回/分 になり、バースト時の負荷を抑えられる。

ex: メール、IRC、ElasticSearch

Page 81: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Webhook Receiver

Page 82: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Webhook Receiver

hook handler を HTTP

Server にする必要がない。

handler の数を調整するだけで、直列処理 or 並列処理を選択できる。

handler が fail しても、hook 情報を失わない。

Page 83: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Desktop 通知

Page 84: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Desktop 通知

直接疎通がなくても、LMQ に疎通があるもの同士で通信できる。

NAT 配下や動的 IP 化にあることの多い Desktop 環境で、サーバからの通知を受け取れる。

Page 85: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

まとめ

Page 86: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

まとめ

LMQ はプロセスを役割毎に分割しやすくする。

LMQ を経由するポイントでシステムを拡張しやすくなる。

複雑なシステムを、がんばって運用しなくていい。

Page 87: Developers Summit 2014 Summer 【B-4】LMQでお手軽分散システム開発

Thank youhttps://github.com/iij/lmq