Tsuyoshin blog

所属団体とは関係なく、個人的なblog

キャッシュ戦略を考えた

はじめ

もっともっとキャッシュをうまく活用することでよりスケーラブルに、よりレスポンシブにしたいなーと考えていて幾つかのパターンを考えたのでまとめておこうと思う

キャッシュといえども広義になってしまうけどここではhtml全体をキャッシュさせてレスポンスさせるキャッシュを指して書きます

設計する上のでポイント

  • ユーザ毎の情報をいかにキャッシュから返すか
    • staticなデータはまぁ良いとしてユーザ毎のデータのキャッシュはしくると情報漏えいとなってしまい大事故になるので慎重に!!
  • キャッシュをさせたくないデータ(ex:ECサイトだったら在庫数とか)をどう扱うか

考えたパターン

varnishを活用した場合

f:id:tsuyoshi_nakamura:20170117142512j:plain

説明

  • varnishはpostやget、urlによってキャッシュするしないという設定が柔軟で😃
  • varnishの設定によりキャッシュさせるページ=データを設定する
  • 図の流れのように順番に上からアクセスをさばくが、varnishの部分でキャッシュが存在していればそこからレスポンスされる
  • なのでキャッシュがあればELB→Nginx→Varnishだけでレスポンスをする
  • ESI(Edge Side Includes)とvcl-hashingの機能を使えばユーザ毎のデータも部分的にキャッシュ可能で効率的にキャッシュできる😃
  • キャッシュのクリアは特定のIPからのcurlでrefreshする仕組みを作り、必要に応じてcurlする

Memcachedを活用した場合

f:id:tsuyoshi_nakamura:20170117143659j:plain

説明

  • まぁ手軽😃
  • ngx_http_memcached_moduleを活用してキャッシュが存在すればレスポンスするようになる
  • ngx_http_memcached_module自体にはキャッシュさせる仕組みは無く、どのページ、どのデータをキャッシュさせるかはバックエンド=PHP側で行い、ngx_http_memcached_moduleはキャッシュがあればそのデータをレスポンスをする
  • ただVarnishのようにユーザ毎のデータのキャッシュを作ってそれぞれにレスポンスする仕組みは整っておらず、ちょっと厳しい😂
  • キャッシュのクリアはバックエンドからkeyを特定してmemcachedのデータをdeleteする

AWS CloudFrontを活用した場合

f:id:tsuyoshi_nakamura:20170117153331j:plain

説明

  • 前の2つとはちょっと毛色がかわる
  • AWS CloudFrontを活用する
  • Nginxで特定のURLの場合にリバースプロキシ設定でCloudFrontへ飛ばす
  • CloudFrontのoriginにはバックエンドのサーバを指定してhtmlのキャッシュを作り、CDN配信する
  • ユーザ毎に必要なデータはすべてAPI経由で配信する
    • Cookieからユーザを特定してjsonで返却するイメージ
    • APIのコール元は自社で提供しているアプリ(ブラウザ)なのでCookieからユーザ特定は問題ないのでは無いかと思っている(セキュリティ的に)
    • Authorization: Bearer ヘッダあたりを使えば良いんじゃないかなぁー
      • このへんもっと調べる必要あり...
  • キャッシュのクリアはそもそもAPIから都度配信しているので考慮不要

最後

Nginx with Goのパフォーマンスを検証した

はじめに

そろそろAPIをちゃんと切り出して運用したほうが良いよなーとか、ネイティブアプリやる時に必ず必須だしなぁーとか思ってた。 でせっかくならGolangでやった場合どんな感じになるかなと思いながらかる~く調べていた。

Golang自体の書き方云々はまぁ良いとして、実際のAPIを公開して運用するときにさてどんな構成が一番良いんだろうとかちょっと疑問に思った。

んで何通りかあって、どれが一番ベストパフォーマンスが出るんだろうなーと疑問に思ったのでそのあたりのbenchmarkとったのでまとめる

検証環境

f:id:tsuyoshi_nakamura:20161222222201j:plain

  • NginxでまずはHTTP通信を受ける
    • GoのフロントにNginxを置くのはキャッシュ、Logging等々、インターネットからのアクセスを受け付ける役割としてはNginxを使ったほうが最終的に良いだとうと最終的になりそうだったので入れた
  • その後、Golangに投げて、Golangではmysqlからサンプルデータをselectしてレスポンスするという環境にしている
    • Hellow Worldでは無くて少しでも実際のパターンに近づけた😀
  • nginx version: nginx/1.10.2
    • worker_processes 1;
    • worker_connections 1024;
    • keepalive_timeout 65;
  • go version go1.7.4 darwin/amd64
  • gomaxprocs=4 いつからのバージョンからはわからないけど動かしているマシンのCPUの数がセットされる様子
  • 自身のローカルマシーンのmacで完結させている

検証ツール

GitHub - wg/wrk: Modern HTTP benchmarking tool

GitHub - tsenart/vegeta: HTTP load testing tool and library. It's over 9000!

検証パターン

NginxとGoをつなぐ方法として下記のパターンを試した

Go(http.ListenAndServe) + Nginx(proxy)

一番サンプルででてくるパターンかな

vegetaでの検証結果

echo "GET http://localhost:8081" | vegeta attack -rate=100 -duration=30s | tee results_8081.bin | vegeta report

Requests      [total, rate]            3000, 100.03
Duration      [total, attack, wait]    29.996695502s, 29.98999987s, 6.695632ms
Latencies     [mean, 50, 95, 99, max]  8.262946ms, 6.36174ms, 16.602405ms, 20.103509ms, 249.542167ms
Bytes In      [total, mean]            486000, 162.00
Bytes Out     [total, mean]            0, 0.00
Success       [ratio]                  100.00%
Status Codes  [code:count]             200:3000
Error Set:

cat results_8081.bin | vegeta report -reporter='hist[0,2ms,4ms,6ms]'

Bucket         #     %       Histogram
[0,     2ms]   0     0.00%
[2ms,   4ms]   18    0.60%
[4ms,   6ms]   1108  36.93%  ###########################
[6ms,   +Inf]  1874  62.47%  ##############################################

cat results_8081.bin | vegeta report -reporter=plot > results_8081.html f:id:tsuyoshi_nakamura:20161225170707p:plain

wrkでの検証結果

wrk -t1 -c100 -d30s http://localhost:8081/

Running 30s test @ http://localhost:8081/
  1 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   205.13ms  207.27ms   1.96s    95.27%
    Req/Sec   524.92    143.15     0.90k    72.44%
  8261 requests in 30.02s, 2.50MB read
  Socket errors: connect 0, read 0, write 0, timeout 14
Requests/sec:    275.16
Transfer/sec:     85.18KB

Go(net.tcp) + Nginx(fastcgi_pass)

fastcgiTCP通信

vegetaでの検証結果

echo "GET http://localhost:8071" | vegeta attack -rate=100 -duration=30s | tee results_8071.bin | vegeta report

Requests      [total, rate]            3000, 100.03
Duration      [total, attack, wait]    34.148993246s, 29.989999849s, 4.158993397s
Latencies     [mean, 50, 95, 99, max]  786.786891ms, 6.547174ms, 6.418549209s, 7.619790263s, 7.978296865s
Bytes In      [total, mean]            486000, 162.00
Bytes Out     [total, mean]            0, 0.00
Success       [ratio]                  100.00%
Status Codes  [code:count]             200:3000
Error Set:

cat results_8071.bin | vegeta report -reporter='hist[0,2ms,4ms,6ms]'

Bucket         #     %       Histogram
[0,     2ms]   0     0.00%
[2ms,   4ms]   31    1.03%
[4ms,   6ms]   1116  37.20%  ###########################
[6ms,   +Inf]  1853  61.77%  ##############################################

cat results_8071.bin | vegeta report -reporter=plot > results_8071.html f:id:tsuyoshi_nakamura:20161225170704p:plain

wrkでの検証結果

wrk -t1 -c100 -d30s http://localhost:8071/

Running 30s test @ http://localhost:8071/
  1 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   312.64ms  258.32ms   1.97s    83.26%
    Req/Sec   330.31    225.29     0.92k    68.49%
  9786 requests in 30.08s, 3.11MB read
  Socket errors: connect 40, read 0, write 0, timeout 21
  Non-2xx or 3xx responses: 1607
Requests/sec:    325.37
Transfer/sec:    105.89KB

Go(net.unix) + Nginx(fastcgi_pass)

fastcgiUNIXドメインソケット通信

vegetaでの検証結果

echo "GET http://localhost:8061" | vegeta attack -rate=100 -duration=30s | tee results_8061.bin | vegeta report

Requests      [total, rate]            3000, 100.03
Duration      [total, attack, wait]    29.99792736s, 29.989999868s, 7.927492ms
Latencies     [mean, 50, 95, 99, max]  7.824538ms, 5.861618ms, 16.640207ms, 29.212751ms, 231.643738ms
Bytes In      [total, mean]            486000, 162.00
Bytes Out     [total, mean]            0, 0.00
Success       [ratio]                  100.00%
Status Codes  [code:count]             200:3000
Error Set:

cat results_8061.bin | vegeta report -reporter='hist[0,2ms,4ms,6ms]'

Bucket         #     %       Histogram
[0,     2ms]   0     0.00%
[2ms,   4ms]   121   4.03%   ###
[4ms,   6ms]   1484  49.47%  #####################################
[6ms,   +Inf]  1395  46.50%  ##################################

cat results_8061.bin | vegeta report -reporter=plot > results_8061.html f:id:tsuyoshi_nakamura:20161225170701p:plain

wrkでの検証結果

wrk -t1 -c100 -d30s http://localhost:8061/

Running 30s test @ http://localhost:8061/
  1 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   221.23ms  300.71ms   1.99s    89.90%
    Req/Sec   552.81    243.08     1.09k    72.54%
  16298 requests in 30.01s, 5.20MB read
  Socket errors: connect 1, read 0, write 0, timeout 52
Requests/sec:    543.11
Transfer/sec:    177.28KB

vegetaでの検証結果のまとめ

  • レイテンシーのグラフではぱっと見ちょっと良くわからなかった。ちゃんと追うと少し差異があるのがわかるんだけど...
  • Go(http.ListenAndServe) + Nginx(proxy)Go(net.tcp) + Nginx(fastcgi_pass)の比較はだいたい同じかんじ
  • Go(net.unix) + Nginx(fastcgi_pass)との比較ではちょっと差異がでた

少し差異がでた部分のLatency比較

4ms, 6ms 6ms, +Inf
Go(net.tcp) + Nginx(fastcgi_pass) 37.20% 61.77%
Go(net.unix) + Nginx(fastcgi_pass) 49.47% 46.50%

Go(net.unix) + Nginx(fastcgi_pass)ではレイテンシーが少々いいのかな😀

wrkでの検証結果のまとめ

Req/Sec
Go(http.ListenAndServe) + Nginx(proxy) Requests/sec: 275.16
Go(net.tcp) + Nginx(fastcgi_pass) Requests/sec: 325.37
Go(net.unix) + Nginx(fastcgi_pass) Requests/sec: 543.11

秒間でさばけるリクエストはGo(net.unix) + Nginx(fastcgi_pass)は一番良かった😀

まとめ的な

  • Golangをメイン言語にしてフルスタックなFWを使うパターンよりはバッチやAPIに使う場合が結構あると思う
    • そのときに https://github.com/gin-gonic/ginのうなFWは使わずに内包されてるnet/httpで作ってしまってパフォーマンスを優先するパターンが結構あるんだなーと色々と調べて感じた😁
  • 今回の検証結果的にはnet/httpGo(net.unix) + Nginx(fastcgi_pass)でやると一番良いんじゃないかという結果になった
  • 今回は対象外にしたけど grpc / grpc.ioあたりも触ってみたいなーと余談💪🏽
  • AWS gatewayを利用するけどヘッダー認証系やスロットリングAPIキー認証、レスポンスキャッシュなどが低コストでさくっと実装できたりできるので組み合わせるとなお良いかなーっと思ったけど内部のAPIサーバには使えなかったり...うーんおしい😅
    • 使い勝手良く改善されることを願う
  • golangでgraceful-restartも運用を考えると必要だなぁと感じたけどAPIの上位にロードバランサがいればいらないかもって感じてる。どうなんだろう🤔

Google データスタジオを試してみた

はじめに

日々色々な情報が流れてきますが、たまたま目に止まったのがGoogle データスタジオ。Google Analyticsは日々使ってるし、アクセス分析に関連した分析データをサクッと簡単に且つなるべく横断的に見れるのは求めてたし、使ってみた。それなりに良かったので使用感レポートとして残し置く

Google データスタジオとは

www.youtube.com www.google.com

  • もともと有償版であるGoogleアナリティクス360スイートがあってそのうちのGoogleオプティマイズ360Googleデータスタジオ360がある
  • そのGoogleオプティマイズ360Googleデータスタジオ360を無償版としてGoogleオプティマイズGoogleデータスタジオを発表された
  • MicrosofltのPowerBIという同様のツールの対抗として発表された模様

主な特徴

データソースは下記が選択できる

実際の画面の使い方は下記のサイトが詳しい

Googleデータスタジオの使い方 #GoogleDataStudio

速報!Google Data Studio(グーグル・データ・スタジオ)使用感レポート | 株式会社プリンシプル

実際に使ってみた

データソースはGoogle Analyticを活用 f:id:tsuyoshi_nakamura:20161207161843p:plain

所感。良いところ

  • サクッとできた😃
  • グラフがキレイ😃
  • 印刷ボタンがないところが良い😄
    • 印刷した瞬間からどんどんゴミになっていきますからね...
    • 常にこのレポートで最新を見る。過去を見たければカレンダーを操作する💪🏽
  • データソースが豊富😃
  • 広告のデータも一緒に出せるので費用対効果が一発で見れる😃
    • 今回は使ってないけど
  • フィルターが使えるので色々な視点で絞って分析が可能😃
  • 前年比とかできて良い😃

イマイチなところ

  • データスタジオ上で数式計算とかはできない😢
  • CV系のデータはBigQueryに入れてそこから引いたほうが良さげ😢
    • Google AnalyticsにもCVデータ保存できるけど、正しい数値とはちょっとズレが生じるので別口でBigQueryにデータを入れて引いたほうがデータが正確になる

まとめ

この手軽さからしてまず良い!!GCPにあるデータとかと繋げられたらまた広がるなぁーと感じた

社内勉強会でキャッシュサーバのVarnishのベンチマークをレポートした

久しぶりに毎週金曜日にやっている社内の勉強会で話す機会を得たので発表した内容を残しておく

発表資料

speakerdeck.com

ざっくり感想

  • memcachedとvarnishの単純なキャッシュ性能を計測した。恐らくvarnishのが良いんだろうなーと思ってたけどその通りの結果になった😅
  • Benchmarkの数値を集計して評価するのに色々と設定が面倒で今回はレイテンシーのみを Vegeta(https://github.com/tsenart/vegeta)見てた😃
  • これからも定期的に発表していこうと思います💪🏽

弁護士ドットコム×みんなのウェディング ライフイベントメディアの成長を支える技術勉強会に参加してきた

久しぶりに勉強会に参加させてもらったのでまとめておく

勉強会概要

mwed.connpass.com

Time Table

みんなのウェディング 「爆速開発のために独自フレームワークからRails に移行した話」 @松久 浩伸

speakerdeck.com

感想とか

  • RailsActiveRecordの命名ルールとか既存のDBのschema設定に依存してしまい、どう対応していったのかと気になってた
    • 結果的にはこのあたりは別扱いというかまずはRailsに乗り換える事を優先していったという感じ
    • ActiveRecordをもっとフル活用できるとより爆速開発につながるんだろなーと勝手に思った
  • リバースプロキシで移行期間を設けてというのは良いと思うが、この移行期間はダブル運用になるので運用コストも見逃せないと思う。最短で切り替えていく計画が必要だろうと感じた。(おそらくやられているかと思いますが)
    • 場合によってはアクセスがスパイクした時とか、裏側で2つのシステムをみて対応していかないといけないし...

弁護士ドットコム 「CloudSignでのGo言語でのサービス開発」@和田 浩一

speakerdeck.com

  • サーバ側の実装はGo,Revel
  • もともとはPHPで実装されていた
  • なぜ、Goを採用したのか
    • 開発するサービスが独立している分自由度があったので新しい言語、FWを採用しやすかった
    • サービスの特性上、堅牢性が重要でその観点からも静的型付言語でコンパイル時に初歩的なエラーを発見できるのは良かったと

みんなのウェディングのデータ分析基盤の作り方 @小室 直

www.slideshare.net

  • 月刊1000万行のログ。日々増え続ける 以前は

  • mysql,modgo,内製ログツールにcron,scp,perl,grepとかとか

  • 課題
    • データストアの分断
    • 横断分析が面倒

解決は

分析には

感想とか

  • 布教活動は重要だなと同じく感じた
    • 全てエンジニアのバックボーンがあるならそこまで要らないかもしれないけど
  • 技術のわからない人向けにデータ分析関連(SQLとか)を覚えて活用すると自分の目標にどう活かしていくことができるかをセットで教えられるとより身につくだろうなと思った

弁護士ドットコム 「Yahoo砲にも耐えるインフラ設計」@薄井 敏臣

speakerdeck.com

おこなった対策

  • htmlをキャッシュしてCloudfrontでレスポンス
    • けどダメだった
  • AWSのauto scaling
    • けどダメだった(ELBのスケールアップやオートスケールは間に合わない)

最終的には

  • varnishを前方に配置
    • Cloudfrontから切り替え

感想とか

  • うちも今同じようにキャッシュでhtmlをレスポンスしている仕組みがある。Varnishの性能とベンチマークしてみたいなーと思った
  • 自分も取り急ぎの基準値としてGoogle Analyticsのリアルタイムセッション数は参考にするけど、正しくは秒間のリクエスト数になるのでそのあたりをスパイクしている時に瞬時に把握できる仕組みが必要だなと思った
  • AWS側のスケール対応が間に合わないって話はちょこちょこ聞くなぁ〜

みんなのウェディング 「サービスを支える監視運用の工夫」@坪井 昭憲

www.slideshare.net

以前は

現在は

  • zabbix,cloudwatch,twillo

感想とか

  • AWSのEC2インスタンス追加時に自動でzabbixの開始対象へする設定は確かに良い(zabbixの監視テンプレートも自動で割り当て)
  • 最近は監視内容、項目のバージョン管理していく流れ(code化される)があると思っていてそのあたりの考えとかザックばらんに話聞ければが良かったけど時間が無くて残念
    • AWS Configとか検証してたりしないかなーと思ったけど

弁護士ドットコム 「スケールする会社を支える開発組織のマネジメント」@市橋 立

  • カウボーイスタイル開発
    • スタイルなし
  • テストサーバ1台でみんで開発。かなりの初期感がある

結局スケール対応するマネージメントとは

  • ライフサイクル
    • ステージ別に考えて重点をどこにおいて対応していくかを考える

重要なのは下記

  1. 問題の見極め
  2. アンテナを張る
    • ノイズなのかシグナルなのか
    • 3回ルール(3回同じ事が起きたらノイズではなくシグナル)
  3. 引き出しを増やす
    • 他の事例を参考にインプット

みんなのウェディング 「職種を超えたスキル育成でキャリアをつくる」@中村 修治

www.slideshare.net

自分で勝ってに学べよは基本としてあるけどそれだけではダメでチームとして行うこと自分にもメリットは返ってくる。例えば下記

  • 他の職種の人との共有言語ができる
  • 組織として学びの文化形成(環境変化への対応)
  • チャレンジングな部署移動を積極的にできる

組織、社会、自身が変わっても十分に力を発揮するようにするために少しづつ着実に自分のできることを増やす事が大切!!

この方の歩んできた経歴がとても面白くて一度フランクに話聞きたいなーと思った!!

頻繁にdeployしながらCDN(CloudFront)化のキャッシュclear,lifecycleの付き合い方

静的コンテンツ(CSS,Image,JS)をCDNから配信するとサイトの表示スピードが格段にあがるよってゆう話はかなり今更感ですが、それは前提として1日何回もデプロイを繰り返すサービスを考慮するとCDNのキャッシュとライフサイクルにどううまく付き合うかが結構課題になってきたりします。

そんな課題にどうやって対処したかをまとめておこうと思います

全体説明

f:id:tsuyoshi_nakamura:20160926142134p:plain

  • 静的コンテンツ(CSS,Image,JS)はすべてS3に格納
    • S3を通常のバケットとして設定
  • 以前は直接S3のURLを参照してコンテンツを配信していたが、パフォーマンス的にNGなので今はCloudFrontから配信している
  • 静的コンテンツ以外はELBにアプリケーションサーバ群が存在、その先にDB等がある。storage系は今回省略

抱えていた・想定された課題

  1. CDN(CloudFront)からコンテンツを配信した場合、キャッシュの更新が全世界のエッジロケーションに行き渡るまで最大20分程度かかってしまう
    • 即時反映させないとサービス運用上厳しい時があって困った 😩
  2. 静的ファイルのrevision管理(ハッシュプレフィックス)を行ってもリリースのたびに過去のゴミファイルが増えて続けてしまう
    • S3のアクセスログからアクセスが無くなったタイミングでdeleteする運用すれば良いかもしれんが面倒すぎる 😰
  3. 通常のリリース中に表示の不具合等が起こってた
    • リリースは①〜③で順にELBからサービスアウト、ソースの更新、サービスイン。④で静的コンテンツ(S3)に世代管理もしていなく、アクセスを受けているディレクトリにゴリっとデータをSync
    • リリース時間中は新旧のソースが入り混じる状態でアクセスを受けてレスポンスしている為に表示の不具合が発生....なんどもデプロイすると問題が表面化してくる😱
    • 詳細
      1. ソースがまだ古い旧アプリサーバがレスポンスを返す時は旧versionのhtmlを
      2. ソースが更新された新アプリサーバがレスポンスを返す時は新versionのhtmlを
      3. 静的コンテンツはあるタイミングでゴリっと変わる
      4. 2のhtmlでSync前の静的コンテンツを呼び出してレンダリングした場合、表示が壊れる... 😰
    • BlueGreenDeployment的な思考が必要...だ

取り組んだ内容

  • S3に配置するファイルをリリースをする度に世代管理した。リリースをする度にyyyyより下層ディレクトリが増えていく
    • 時間軸を世代管理に利用したのはCDNのキャッシュを考慮した為
      • 毎度新しいstatic fileのpathにする事で一回目のアクセスで必ずoriginサーバからキャッシュにのり、最新のデータが配信できる
      • AWS S3のライフサイクル設定(ルールターゲット)で引っ掛けて不要ファイルがdeleteしやすい
        • 何度もデプロイを繰り返す上で数日前のversionのstatic fileとかはもはやゴミ
└── bucket_name
    └── revision
        └── yyyy
            └── mm
                └── dd
                    └── His
                        ├── css
                        ├── image
                        └── js

  * yyyyはリリースをした年
  * mmはリリースをした月
  * ddはリリースをした日
  * Hisはリリースをした時間(secまで)
  • リリーススクリプトからリリース時にアプリケージョンサーバが参照する静的コンテンツを指定できるようにした。課題3のクリア😀
    • Shell職人気味だけど
    • アプリケーションは必ず上記で指定された静的コンテンツを参照するようにした
    • リリース時間中でもアプリケーションと静的コンテンツのversionがずれる事なく参照できるようなったので表示不具合は無くなった😬
    • これで1日なんども安心してデプロイできるようになった😆
    • リリースの度に新しく世代管理された静的コンテンツを参照する為、必ず新しいURL参照になるのでCDNのキャッシュクリアを気にする事なく即時反映を実現できた。課題1のクリア🙂
  • ライフサイクル設定でリリース日から前月のコンテンツをdeleteした docs.aws.amazon.com
    • 無駄なゴミファイルを削除が実現できた。一ヶ月前のリリースのバージョンの静的ファイルは確実に要らないと断言できたので。課題2のクリア😀

ついでに改善した点

  • キャッシュの有効時間設定をheaderオプションを使って設定した docs.aws.amazon.com
    • CloudFrontの管理画面でも設定できるけどユーザのブラウザキャッシュも有効に活用したいのでheaderオプションを活用

最後

  • AWSのライフサイクル設定はもっと早いサイクルでも全く問題ないと思った
  • S3自体でもバージョニング機能が存在するけど結論、オペミスによるファイルの復活させるレベルの使い方になると理解した docs.aws.amazon.com
  • これで安心して何度もデプロイしてリリースするまでの改善スピードをあげていける
  • 今回はgitにcommitしてあるCSS,Image,JSが対象とした話
    • Imageだとユーザがアップロードするものもある。更新されるタイミングが異なるので今回とはまた別の話
  • 各static fileの名前をハッシュプレフィックスをつけておくとS3上のI/Oが良くなってリリース時間が短縮できるっぽい docs.aws.amazon.com

PM Meetup #2 に参加させてもらった時のメモ

自分はPMではないけど、PMとはという事を色々と考える機会があり且つ運良く抽選にあたったので今回参加させてもらいました。

その時のメモ的なものです。

勉強会概要

connpass.com

Time Table

PM Talk by takoratta

  • IncrementsにおけるPMのお話
    • 理想的に言うと多種多様(QAやPR、legalなどの)な職種が必要だけど現実はPM,ENG,デザイナーしかいない
  • PM,ENG,デザイナーはすべて対等な立場である
    • 最終決定はチーム内の合意を取りながらPMが進めていく
  • What,When,WhyをつくるのがPMの仕事であり、そこでPRDを用いる
  • ENGはHowの部分を担う。Githubでコンテキストに残しながら議論をして技術選定をしていく
  • デザイナーはフロントエンドエンジニア部分も担う。またPMと一緒にWhatの部分も担っていく
  • 自明の事でも文字にして残すことで自分には当たり前のことが他者は違う解釈がわかる時がある
  • あえて文字起こしすることの重要性。自分の考えもクリアになる
  • PMはMTGで合意を取ることがメインの仕事となるのでリモートワークにおいては一番工夫をする必要がある
    • 非同期コミニュケーションでいいのか?同期コミュニケーションがよいのか?
  • QAの役割をどの役職が担うかが議論中

PM Talk by yaotti

  • 絵文字リアクション機能を例にPRDの話
  • Qiita:Team のPM
    • プロダクトのコンセプト、主要ストーリの設定やブラッシュアップ
    • issueの立ち上げ、進行サポート
    • ユーザーヒアリングやアンケート
    • プロダクトチームマネジメント
      • 1on1
      • マイクロマネジメントはせずに自律的に動きやすい環境をつくりをする
      • よりやり方を求めて改善し続ける
  • 使っているtool
    • qiita:team
    • zenhub
    • slack
    • google spreadsheet,Re:dash
    • trello,mural
  • リモートワークで一番工夫する必要があるのはPM
    • ビデオ・テキスト
    • 同期的・非同期
      • 人の集中時間を無駄に奪ってはいけないのでうまく使い分ける

質疑応答 + フリーディスカッション

メンバーのモチベーション維持にはどうしているか?

  • 毎日スタンドアップMTGしている
    • 昼会、夕会で課題洗い出しで解決していく
  • 1on1で吸い上げる
  • 物怖じしないでどんどん発言するエンジニア文化が良い気がする

    Trello,Zenhub使い分けは?

  • 採用系、バックオフィス系でTrelloを使ってる
  • 開発系はZenhubで完結

    プロジェクトマネジメント・プロジェクトマネージメントの違いや捉え方にかんして

  • あまり区別なく、取り組んでいる
  • 小さいチームにはスクラムとか教科書どおりにいかない
  • ユーザに愛されるサービス開発からブラさないのでいつまでに出すといったスケジュールのプレッシャーは少ない

    PMソースコードはどの程度把握しているか?

  • 小さい修正はcommitしている by yaotti
  • ほぼわからない。というかrubyあまりわからないw by takoratta

    PRDに経営判断がどの程度入れているのか?

  • qiitaはもともとマネタイズしてなかったので最初は考えていなかったが、健全な成長を促す為に広告を貼りやすいといった要件はある
  • ユーザの使い勝手とセットでなければ、経営的な判断は入れない。あくまでユーザに愛されることから軸足ををずらさない

感想等

  • エンジニアの為の情報共有のプロダクトなので、作るのもエンジニア、使うのもエンジニアという形なので方向性が割とまとまりやすい気がした
  • 完全リモートワークの中でのPMの立ち回りはより重要だと思った
  • 自明の事でもしっかりテキストに残して共有する事の重要性を改めて感じました
    • ついつい忙しいとスキップしてしまいがちな自分を反省しました
    • あとで振り返った時にチームのノウハウ?学習を積み上げていく作業である
  • チーム全員がよりよりプロダクト作りに集中していて楽しそうに見えた
  • PMって偉い?立場の人ってなりそうだけど、全員が対等な立場であって正しい発言・行動をした人が正しい(偉い)文化
    • お二方の話っぷりや姿勢を見ていると納得できた
  • マイクロマネジメントはしない。賛成!! 信頼で成り立たせる
  • お疲れ様でした

過去の参考記事

PMについて思った事 - Tsuyoshin blog