第155回天皇賞(春)の写真を撮ってきた

この間、そうだ Go、京都。に行ったエントリ で書いたとおり、天皇賞のついでに京都に行ったわけですがそこで撮った写真を雑に貼ってみる。

f:id:a-yamada:20170513233710j:plain f:id:a-yamada:20170513233718j:plain f:id:a-yamada:20170513233727j:plain f:id:a-yamada:20170513233745j:plain f:id:a-yamada:20170513233749j:plain f:id:a-yamada:20170513233755j:plain f:id:a-yamada:20170513233802j:plain f:id:a-yamada:20170513233813j:plain f:id:a-yamada:20170513233823j:plain f:id:a-yamada:20170513233834j:plain f:id:a-yamada:20170513233846j:plain f:id:a-yamada:20170513233853j:plain

どうやって撮ったか

以前の残材エントリで書いたが、カメラはCanonEOS 7D Mark IIを利用してる。

APS-Cサイズのカメラだが10枚/secの撮影が可能なので、基本的に動的コンテンツを主に被写体としている自分にとっては非常に役に立ってる。

撮影場所は京都競馬場の7Fのi-Seat指定席付近のテラス。JRAの指定席には競馬場によって色々な形式があり、例えば東京競馬場のメモリアルスタンド(S指定席・i-Seat)ではガラス張りになっているので京都のようなテラスは無い。京都競馬場は指定席ながらも、このような写真を取ることができる。肉眼では結構遠いのだが、300mm砲を使えばスタンド前を走る馬をこれくらいの大きさで捉えることができる。

GIレースになるとガチのプロカメラマン勢が開門ダッシュで芝コース前最前列に陣取っているので、自分みたいに写真ガチ勢ではないクラスタにとってはなかなか厳しいものがある。GIでなければそこそこのポジションで写真が撮ることができるので、臨場感ある写真を取りたい人は試してみて欲しい。基本的に直線が長い競馬場の方が競争率は落ちるので、東京・中山・京都・阪神においては中山が一番しんどい。それ以外では新潟や中京は結構写真撮りやすい。新潟は直千のレースがあって、基本的に外ラチに寄って走ってくるので臨場感のある写真が撮りやすいと思う。

ところでレースは

キタサンブラックが連覇を果たしたわけだが、長距離レースとしてはここ20年で1番といっていいくらいの素晴らしいレースだった。淀みのないラップを刻んでなし崩し的に後続の脚を削るという、90年代前半の長距離戦を現代の高速馬場でやるとこうなるという感じ。メジロマックイーンが故障しなかったらキタサンブラックのようなキャリアを進んでいたんでしょうねぇ。

microservices間でデータ変更をReactiveに伝搬させる

microservices構成なものを運用していると、更新頻度が少ないデータなのに別のmicroservicesに都度リクエストをするということがよくあると思う。

例えば、Userのドメインを扱うサービスがいた場合、他のサービスはUserのデータを取得するためにUserサービスをHTTP(S)ないし、何らかのRPC的手段によって取得することになる。以下の図をイメージしてもらえるとよい。

f:id:a-yamada:20170503161220p:plain

UserサービスがUserドメインを担当する層なのでこのようになる。

データの更新頻度が少ないという現実

実際に運用してみると取得対象のデータ更新頻度が少ないというケースがあるので、Userサービスへのリクエストを減らしてキャッシュを活用したくなるところである。microservices間の通信を減らすこともできるし、対象のサービスにとってはデータストアへのクエリを減らすことにも繋がる。

というわけで以下のようにUserデータに依存したサービス毎にキャッシュを持たせる。

f:id:a-yamada:20170503175045p:plain

キャッシュストアについては、Redisやmemcached等を配置するのも良いし、サービスにインメモリに持たせるでも良い。コスト感を考えると後者の方が安上がりだが、サービスを跨いでキャッシュを共有しても良いという方針にするならば前者も選択肢に入ってくる。

キャッシュデータに関しては適切にTTLを設定し、expireした場合には対象にサービスに再度リクエストをしてキャッシュを更新するといった制御になる。

キャッシュを持つ分大きくリクエストを減らすことができるが、この方式の弱点はTTLの長さによってはキャッシュが長く滞留してしまい、キャッシュの更新に時間がかかってしまうということにある。

データ変更をトリガーに、依存サービスに変更データをばらまく

できることならばデータの変更をトリガーに、複数のmicroservicesに散らばっているキャッシュを更新したい。そこで、Server Push型ミドルウェアであるPlasmaを用いる。

github.com

Plasmaの特性については、以前にエントリを参照してほしい。

blog.stormcat.io

PlasmaはPublisherが複数のSubscriberに対して同じイベントデータをばらまくといった用途に向いている。今回の例でいうと、User ServiceがPublisherであり依存サービスがSubscriberとなる。この特性を利用して、Userデータの変更タイミングで依存サービスに対して新しいUserデータを伝搬させ、キャッシュを更新させる。

f:id:a-yamada:20170503183303p:plain

UserサービスはDBと共に、Plasma用RedisにデータをPublishするようにする。各microservicesがUserデータ変更イベントをSubscribeしていれば、データ変更後程なくして更新データをPlasma経由で受け取ることが出来る。受け取り次第キャッシュを更新すれば、キャッシュの良さを活かしつつも"ほぼ即時"に依存サービスへのリクエスト無しでキャッシュを更新することが可能。microservicesを跨いだ、Reactiveなデータ伝搬といった表現ができるかなと思っている。

このようなデータ伝搬の仕組みは、Plasmaのようなものを使わずとも用意せずにも可能ではある。例えば、各microservicesがキャッシュ更新用のエンドポイントを用意しておいて、Publisherがそこにリクエストをするといった形式だが、この場合は自分に依存しているサービスがどこにあるかを把握しておかなくてはならないのでService Discoveryが必要になってしまう。また、相互参照も避けた方がシンプル。

Plasmaを使わずにRedisのPubSubを使っても同じことが実現できる(Plasma-Redis間がそもそもPubSub)が、Plasmaの利点としてはgRPCやSSEでSubscribeが可能な点なので、RedisへのSubscirbe処理を色んなところで書くよりも、Plasmaのprotoから生成するgRPCのインタフェースに頼ったほうがいいし、SSEを利用すればWebフロントエンドからの利用も可能になるので何かと良いと考えている。

まとめ

PubSub型の特性を活かしたMicroservices間のデータ伝搬のパターンはWeb上文献でもちらほら散見される。microservicesは疎結合や障害の局所化を得やすい反面、どうしても通信は増えがちになるのでパフォーマンスをケアした仕組みというのがこれからもっと重要になるなーという感想。

そうだ Go、京都。に参加してきた #golangkyoto

4/29に京都の株式会社はてなさんで開催されたそうだ Go、京都。に参加してきた。

go-kyoto.connpass.com

この為に上洛した、というわけではなく翌日に開催された春の天皇賞のついでの意味合いが強い。 

雑多な感想

  • 関西圏の勉強会に初めて参加したので、雰囲気が把握できてよかった
  • はてなエンジニア勢がGoをどう使ってるのかの雰囲気を知れた 
  • やっぱりエラー処理は皆ツラミを感じてた。github.com/pkg/errors 不可避ですよねー
  • gRPCの高まりを関西でも感じた
  • 雰囲気もいいので、時間がある人は何か喋ってくるといいと思う

自分のスライド

せっかく来たので自分も喋ってきた。まあPlasmaの営業的トークだけど。

speakerdeck.com

京都いるときに開催されたらまた行くかも。キタサンブラック強すぎワロタ