NSQ-Centric Architecture (GoCon Autumn 2014)

35
NSQ-Centric Architecture NSQ中心の構造

description

Designing a real-time chat system using NSQ and Go

Transcript of NSQ-Centric Architecture (GoCon Autumn 2014)

Page 1: NSQ-Centric Architecture (GoCon Autumn 2014)

NSQ-Centric

ArchitectureNSQ中心の構造

Page 2: NSQ-Centric Architecture (GoCon Autumn 2014)

About me

• American

• Went to college in Japan (Waseda)

• The “Go person” at Gunosy

• アメリカ人

• 早稲田大学出身

• Gunosyの「Go担当」

Greg Roseberry

http://github.com/guregu

Page 3: NSQ-Centric Architecture (GoCon Autumn 2014)

GunosyNews aggregator / portal app

If you’re Japanese and have a TV

you already know about it

テレビを持っている日本人ならばご存知のはず

Page 4: NSQ-Centric Architecture (GoCon Autumn 2014)

Life at Gunosy

• We like Go

• The API server is all Go

• Anything else I get my hands

on will be Go

• You can use basically any

software/library/whatever you’d

like… if you’re willing to take

responsibility.

GunosyはGoが好きAPIなどで

Goを喜んで利用

責任を持てば…

好きな技術を使っていいという主義

Page 5: NSQ-Centric Architecture (GoCon Autumn 2014)

Bring it on.

かかってこい

Page 6: NSQ-Centric Architecture (GoCon Autumn 2014)

The Problem

• A chat server…

• … that’s real-time

• … and easily scalable

• … and distributed

• … and flexible, without

complex configuration

issues

• チャット

• … リアルタイム

• … スケールしやすい

• … 分散

• … 柔軟で、複雑なconfigいらず

Page 7: NSQ-Centric Architecture (GoCon Autumn 2014)

The Basics

• Go (obviously)

• In-app webview, so

WebSockets for realtime

stuff

• How can we stick our

WebSocket servers

behind a load balancer?

• Goに決まってるだろ

• アプリ内WebViewなのでリアルタム処理はWebSocket

• WebSocketはどうやってロードバランス?

Page 8: NSQ-Centric Architecture (GoCon Autumn 2014)

Enter: NSQ

“Spray some NSQ on it!”

NSQをぶっかけよう!

Page 9: NSQ-Centric Architecture (GoCon Autumn 2014)

NSQって何?

• What is NSQ?

• It’s a message queue.

• Written in Go.

• Made and used

extensively by bit.ly.

• メッセージキュー

• Goで書かれた

• bit.lyが開発している

Page 10: NSQ-Centric Architecture (GoCon Autumn 2014)

NSQ Features• Distributed, no SPOF

• Easily horizontally scalable

• Low-latency, push-based

messages

• Can do load-balanced style

and multicast style

• Data format agnostic

• etc

• 分散 SPOFなし

• 横にスケールしやすい

• レイテンシーが低く、プッシュでメッセージを送る

• ロードバランスもマルチキャストも可能

• データフォーマットは何でもOK

• 等々

Page 11: NSQ-Centric Architecture (GoCon Autumn 2014)

NSQ Guarantees• messages are not durable (by

default)

• set --mem-queue-size=0 to

persist all messages to disk

• messages are delivered at

least once

• messages received are un-

ordered

• consumers eventually find all

topic producers

• デフォルトでメッセージは耐久性がない

• --mem-queue-size=0で問題解決

• メッセージが必ず一回以上届く

• メッセージは順番がない

• consumerは少し時間かかっても結局全部のトピックを見つける

Page 12: NSQ-Centric Architecture (GoCon Autumn 2014)

Topics and Channels

トピックにメッセージを送る。そのメッセージがコピーされて各チャンネルに送られる。複数のconsumer (

消費者)の場合はランダムに届く。consumerがない場合はメッセージが保管される。

Page 13: NSQ-Centric Architecture (GoCon Autumn 2014)

nsqlookupd自動サービスディスカバリ

Page 14: NSQ-Centric Architecture (GoCon Autumn 2014)

NSQはそもそも何のために作られたの?分散統計処理とか、だが…

• What was NSQ made for?

• Distributed statics processing

• But…

Page 15: NSQ-Centric Architecture (GoCon Autumn 2014)

The Mission

WebViewでiMessage風チャットアプリ

Page 16: NSQ-Centric Architecture (GoCon Autumn 2014)

The Protocol

• KISS. JSON.

• Same for

server→server and

server→client

• Easily routable

• シンプルなJSON

• サーバー同士のやり取りとサーバーとクライアントのやり取りが一緒

• ルートしやすい

Page 17: NSQ-Centric Architecture (GoCon Autumn 2014)

Message Format

{

"type": <message-type>,

"to": <recipient-id>,

"body": {

...

}

}

オレオレRPC idを作れば完全にjson-rpc

Page 18: NSQ-Centric Architecture (GoCon Autumn 2014)

Big Picture“chat” topic

websocket-srv-1

websocket-srv-2

websocket-srv-…

archive

push

bot

Page 19: NSQ-Centric Architecture (GoCon Autumn 2014)

WebSocket Channels“chat” topic

websocket-srv-1

websocket-srv-2

websocket-srv-…

archive

push

bot

Msg A

Msg A

Msg A

Msg A

Page 20: NSQ-Centric Architecture (GoCon Autumn 2014)

WebSocket Channels• One unique channel per server

(uses hostname)

• Every server gets every

message, drops uninteresting

ones (uses message To: field

and a map/sync.RWMutex)

• NSQ will hold on to all of our

messages if we disconnect, so

we can reconnect and catch up

• Distributed (at least, multiplexed)

chat!

• サーバー1台につき、1つのチャンネル

• 全部のメッセージが全部のサーバーに行く。宛先を見て、関係ないメッセージは無視する(mapとsync.RWMutex)

• もしネットワーク障害とかあったら、NSQが届かなかったメッセージを保管してくれる。

• 分散(少なくともマルチプレックス)チャット出来上がり!

Page 21: NSQ-Centric Architecture (GoCon Autumn 2014)

Archive Channel“chat” topic

websocket-srv-1

websocket-srv-2

websocket-srv-…

archive

push

bot

Msg A

Msg B

Msg CMsg A

Msg B

Msg C

Randomly

distributed

Page 22: NSQ-Centric Architecture (GoCon Autumn 2014)

Archive Channel

• One channel, many consumers

• Consumers grab every

message, and persist relevant

ones to the database

• It’s easy to add load balancing:

just add more consumers

• You can put the archiver

processes on the same server

as a DB and messages to be

archived will be delivered directly

• 一つのチャンネルに複数のconsumer

• 全部のメッセージを見て、DBに書き込む

• ロードバランスで分散するのに、サーバーを追加するだけでOK

• アーカイブプロセスとDBを一緒にすればメッセージが直接DBサーバーへ

Page 23: NSQ-Centric Architecture (GoCon Autumn 2014)

Push Channel“chat” topic

websocket-srv-1

websocket-srv-2

websocket-srv-…

archive

push

bot

Msg A

Msg A

Msg B

Msg C

Msg BMsg C

Page 24: NSQ-Centric Architecture (GoCon Autumn 2014)

Push Channel

• One channel, one

consumer

• Receives chat messages

and read receipts,

counting unread

messages

• Sends a push message

after a message goes

unread for a certain time

• 一つのチャンネルに一つのconsumer

• チャットメッセージと既読メッセージを受けて、読まれていないメッセージを数える

• 「新着メッセージが○件あります。」をプッシュ

Page 25: NSQ-Centric Architecture (GoCon Autumn 2014)
Page 26: NSQ-Centric Architecture (GoCon Autumn 2014)

Push Problems

• 1 server is going to get

overwhelmed eventually

• Not a problem for us

right now, but could be

solved in the future (split

servers based on

message ID, etc).

• サーバー1台だけだといずれ問題が起こす

• しばらくは大丈夫だけどいつか分散化へ

Page 27: NSQ-Centric Architecture (GoCon Autumn 2014)

Microservices“chat” topic

websocket-srv-1

websocket-srv-2

websocket-srv-…

archive

push

bot

Just by adding a new channel,

we can easily add a new service.

It’s even possible to pause

topics or channels on the NSQ

web admin interface.

チャンネルを追加するだけで、新しいマイクロサービスを

追加できる。nsqadminという管理画面でトピックとチャンネルを一時停止もできる。デプロイが楽!

Page 28: NSQ-Centric Architecture (GoCon Autumn 2014)

NSQ 0.3

• Came out less like a week

ago

• Introduces ephemeral topics:

topics that disappear when

there are no consumers left

• Could completely obsolete

this architecture/the multicast

method.

• No docs, needs more

research.

• 一週間前くらいに出た

• ephemeral topicsという、consumerがいなくなったら消えるトピック

• 今日紹介した仕組みすたれちゃうかも

• ドキュメントがまだない。研究が必要。

Page 29: NSQ-Centric Architecture (GoCon Autumn 2014)

Client-side

Considerations

Page 30: NSQ-Centric Architecture (GoCon Autumn 2014)

Order

• Messages might get

delivered out of order.

• Solution: sort messages

by their date.

• Make sure your clocks

are synchronized!

• メッセージの届く順番がない

• 日付に応じてソートすればOK

• 時計を同期しましょう

Page 31: NSQ-Centric Architecture (GoCon Autumn 2014)

Duplicates

• Messages might get

delivered more than once.

• Solution: keep a list of

received messages, ignore

duplicates. UUIDs.

• You can handle message

edits by date or revision

number or something

fancier

• メッセージは2回以上届くかも

• すでに届いたメッセージのIDを記憶すればOK。UUIDが便利

• メッセージの編集は日付やバージョンで上書き

Page 32: NSQ-Centric Architecture (GoCon Autumn 2014)

Why React

• It’s easy to reason about

updating data if you

keep a single source of

truth.

• It’s easier to think about

components than

controllers, services,

factories, scope, etc.

• Virtual DOM is fast

• 情報の更新は一元化すれば捗る

• コンポーネント指向は捗る

• DOMの変更が早い

Page 33: NSQ-Centric Architecture (GoCon Autumn 2014)

Conclusion

Page 34: NSQ-Centric Architecture (GoCon Autumn 2014)

• It’s easy to make a flexible,

distributed app with an “NSQ-

first” attitude.

• … but it’s hard to make a truly

“queue-only” app that avoids

hitting the DB. Groupcache

can help.

• Nothing here is particularly

novel, but it was simple to

develop. Less than a month

for a MVP between one

programmer and one

designer. Not bad for a

distributed service.

• NSQを中心にすれば、分散でフレキシブルなサービスが作りやすい。

• しかし、ほとんどDBをたたかない「キューのみ」のサービスはちょっと難しい。Groupcacheは助かる。

• これは別に新しい技術ではないが、開発しやすい仕組みです。プログラマー1人が1ヶ月でMVP。

Page 35: NSQ-Centric Architecture (GoCon Autumn 2014)

Thank you!

「毎日Goが書きたい!NSQとやら新技術を使ってみたい!」と思っている諸君!

Gunosyはただ今、日本では数少ないGoエンジニア募集を行っています。

ぜひ、一緒にGoを書きましょう!