2016年8月5日金曜日

スケーラブルな開発と Conway’s law

Twitter で自分が関わっているサービスの開発者の数は、この 4 年間で約 5 倍に増えた。エンジニアの数とサービスの開発・運用について考えてみたい。

2, 3 人の小さいチームが作ったサービスが徐々に複雑になり、アーキテクチャの大きな変更がないまま、複数のチームに属する数十〜数百人のエンジニアが関わるようになる、ということはよくある。このときの問題点として、次の 3 つが考えられる。

コードレビュー

数十人が関わるサービスは大抵コードが複雑で、全体像をしているのは一部のエンジニアだけという状況になる。そして、その一部のエンジニアが「コアチーム」となり、コード変更の決定権を持つ。
エンジニア全体の増加に比べて、コアチームのメンバーは増えない(システムの複雑性が上がっていくので、全体を理解しているエンジニアの数が比例しない)ので、コアチームのレビューが開発のボトルネックになる。

デプロイ・インシデントレスポンス

エンジニアが増えると、一つのデプロイに含まれる変更の数が増える。当然、デプロイが失敗する確率(機能的なバグやパフォーマンス低下など)が上がる。また、失敗した時にどの変更をロールバックすべきかの判断が難しい。デプロイできるのはコアチームだけになり、また、デプロイの頻度が下がる。

リソースプランニング

そのサービスが使用するリソースの予測が難しくなる。
一つのサービスの中にいくつもの機能が含まれるので、ダウンストリームのサービスへのリクエスト数、CPU / ネットワーク使用量、ストレージのキャパシティの見積もりが非線形になる。



これらに共通する原因は、機能・モジュールごとのアイソレーションが無いことだ。
アイソレーションのわかりやすい実装例として、micro service があるが、もしこの複雑なサービスを複数の単純なサービスに分解できるのであれば、これらの問題は解決する。
それぞれの機能を一つのサービスとして実装し、それぞれのサービスは個別のチームが運用すればよい。
難しいのは、micro service に分解するのが現実的ではないケースだ。例えば、機能間でやりとりされるデータ量が大きい場合、別のサービスに分けると、ネットワークがボトルネックになったりする。あるサービスを micro service に分解できるかどうかは、機能間のデータ量、同期処理・非同期処理の切り分け、リアルタイム性などに依存する。

Conway’s law という法則があって、意訳すると「システムの構造は組織の構造を反映する」というものだ。


組織の構造をシステムに反映させ(またはシステムの構造にあった組織を作り)、機能・モジュール間のアイソレーションを提供する。これは、エンジニアの数に対してスケーラブルな開発環境を保つために、コアチームが解決すべき重要な問題だと思う。

2016年8月4日木曜日

コードレビューで心掛けていること

Twitter の Ads チームは、これまでに働いてきた環境に比べて、コードレビューをずっと重視している。
4 年間を振り返って、自分が学んだことをまとめておきたい。

コードレビューの目的は、ソフトウェアの品質を高めることだ。品質にはいろいろな観点があるが、正しく動く、メンテナンスしやすい、設計が正しい、の 3 点でカバーできると思う。

正しく動く

この観点でのレビューには、ロジカルなバグ、テストカバレッジ、エッジケースを考慮してるかなどの確認が含まれる。
テストカバレッジのチェックやマイクロベンチマークは、理想的には自動化して、変更のマージ前にチェックできると良い・・・が現実的にはいろいろ難しいのでレビューでカバーすることになる。
具体的には、null チェックしてるか、メソッド中の条件分岐がユニットテストでカバーされてるか、無駄にオブジェクトを生成してないか、適切に例外を処理しているか、などを見る。

メンテナンスしやすい

大きなサービスだと、運用を担当するエンジニアが機能開発をするエンジニアと別(またはサブセット)ということがよくあるので、オペレーションの観点からのレビューが重要になる。
この機能がバグってたときに、サービスとしてどのように振る舞うべきかを考え、サービス全体を落とすべきなのかその機能だけを無効にするのか、その機能が動いていないことをどのように誰に通知するのか、などを考える。メンテナンスという観点では、コードの読みやすさも大切なので、長すぎるコードやおかしな変数名・クラス名は直してもらう。
これが良いことかどうかは別の機会にまとめたい(追記:まとめた)が、運用を担当するエンジニアは、リリースする機能やリリースのタイミングについて強い決定権を持つべきで、同時に、ある機能をリリースする / しないことによるリスク・ベネフィットのバランスを持たなくてはいけない。

設計が正しい

多分これが一番重要で難しいが、「この変更にバグがなくメンテナンス性も高いと仮定して、そもそもこれは正しい設計なのか」という観点が重要だ。
このレビューが難しい理由は、正しい設計を思いつくには、現在・将来のサービス設計、この機能のビジネス的な意味、どういう方向に発展していくのか、といった幅広い理解が必要だからだ。レビューワが変更のバックグラウンドを知っているケースもあるし、優れたレビューワだと「この変更を読んだところ、あなたがやりたいことは XXX だと思うのだが、だったらこのようにコードを書いた方が良いのではないか?」と、コードを読む→変更の理由を理解する→正しい設計を提案する、とリバースアセンブルしたりする。

理想的には、コードを書く前にコミッタとレビューワが議論すると良いのだが、すべての機能開発でそれができるわけではない(コミッタにとっては自明な変更でもレビューワにとってはそうではないことはよくある )ので、コードレビューの時点で差し戻されることもある。上述のとおり、コードを書き直すことのインパクトをレビューワは理解するべきで、なんでもかんでも差し戻せば良いというものでもない。ただし、「このように書き直すには X 日かかるが、リリースが X 日遅れるとビジネス上どういうインパクトがあるのか?」と聞くと「じゃあ書き直すわ」となることは経験上よくある。概算で良いので定量化(X 日)することで議論しやすくなると思う。

この観点でレビューするときに、最終形が明確に見えていないときがままある。「最終的にどういうコードになるかはっきりとはわからないけど、この方向で書き直すと良さそうだ」と感じてコメントするときもあるし、そのようなコメントをもらうときもある。結果として良い設計になることもあるし、「XXX という理由でその方向では書き直せなかった」ということもあるが、「多くの場合に、結果的に正しい設計にたどり着く方針を、最終形が明確に見えてない時点で指摘できる」レビューワは本当にすごいと思う。



何度も書いているが、コードレビューする際には、この機能をリリースすることのベネフィットを理解することが最も大切だ。バグがないこと、サービスが安定すること「だけ」を目標にすると「新しい機能は一切リリースしない」のが合理的な解になってしまう。そうすると、重箱の隅をつつくようなコードレビューになり、コミッタとレビューワが対立することになる。レビューワはコミッタと同じ方向を向いて、「この変更のどこを修正すれば、この機能をリリースできるのか」と考えると生産的なレビューになると思う。

2016年3月29日火曜日

実現可能な最小の Block chain のサンプルコード(未完成)

Block chain についての Lightning Talk を聞く機会があったので、このとても解りやすい記事を読んで、サンプルコードを書き始めてみた。

価値あるモノ(例えば貨幣)をデジタル化した時に問題になるのが double spend (二重支払い)で、Block chain はこの問題を解決しようとしている。例えば、私が $100 のデジタル貨幣(適当なバイナリデータで表現されているとする)を持っていたとして、バイナリデータは簡単に複製可能なので、この $100 を同時に 2 人(以上)に送ることができてしまう。これを P2P の世界で、中央集権的なサーバなしでどのように解決するか、というのがテーマだ。

もし参加者全員が信頼できるならば、これはいわゆる leader election 問題なので、Paxos/Raft で解決できる。しかしここでは参加者が信頼できることを仮定しない。参加者の一部は悪意あるユーザーかもしれない。Paxos/Raft は、参加者が(データをドロップすることはあっても)プロトコルには従うことを仮定しているので、参加者が悪意ある場合には適用できない。

Block chain のアイデアは、「ある命題を主張するためにコストを支払わなければならないとしたら、コストが十分に高ければ、悪意あるユーザーが偽の主張をする経済的メリットはなくなり、システムは安定する」ということだ。たとえば、「Alice は Bob に $100 あげた(ホントは Chris にあげたのに)」という偽の主張をするインセンティブが Alice にはある。もしその主張が認められれば、Bob に $100 の貸しができるからだ。しかしもし、その虚偽の主張のために $100 のコストを払わなければならないのなら、そしてもし Alice が経済合理的な人間なら、そのように主張するはずがない。

このようなシステムが設計できることを示したのが Block chain 論文だ。参加者は契約(例えばお金のやりとり)をネットワークに流し「この契約を認証した人には $1 差し上げます」という。この $1 を欲しい参加者は、proof-of-work という作業を行い「この契約は正しい」とハンコを押すことができる。もちろん悪意あるユーザーが proof-of-work を行って虚偽の主張を認証することもできるが、proof-of-work は CPU を消費する作業なのでコストがかかる。もし参加者の多くが善意のユーザーだとしたら、偽の主張を認証するためには膨大なコストを払う必要があり、そのようなインセンティブはなくなる。



もしかしたらすでに現実的な解はあるのかもしれないが、Block chain にはシステムの安定性の問題があると思う(コンピュータシステムの安定性の話ではない)。ある主張の真偽は、どれだけ工夫しても確率的にしか定まらず、「この主張は絶対に正しい」という状態には到達しない。
突き詰めて考えれば、これは中央集権的なシステムにも存在する問題だ。Alice が Bob の銀行口座に $100 振り込んだ時、もしかしたらその銀行は Bob を騙していて、実際には $100 は振り込まれていないのかもしれない。私たちは単に銀行を非常に高く信頼してるだけの話だ。
とはいっても、銀行を「誰が運営しているかもわからないコンピュータのネットワーク」で置き換えられるのか、その置き換えを心情的に受け入れられるまでどれだけの期間がかかるのか疑問だ。


というわけで、Block chain は、詐欺の被害が小さい少額決済から順に普及していくのではないかなーと思っている。
なんにせよ、この記事はとても面白かった。サンプルコードはインタラクティブな感じにして完成させたい(希望)。

2015年12月30日水曜日

2015 年を振り返って

残すところ 1 日となったので、2015 年を振り返ってみたいと思います。

仕事

インフラ関係

実りある一年でした。3 点目の experiment framework は game changer だった。コロンブスの卵というやつ。
  • tail latency(リクエスト 100 個のうち最も遅いやつの処理時間)の改善
  • アプリケーション sharding を動的に変更する
  • システムレベルの変更を実験できる experiment framework の実装

開発体制の改善

各チームの責任範囲の明確かなど。
"It's wise to structure organizations the way you'd like to structure your software architecture" という人もいるように、システムとそのシステムの開発組織との対応関係を明確にすることは開発をスケールさせるためにとても重要。どこで聞いたか忘れたけど「大規模システム開発はエントロピーとの戦いだ」という言葉もある。
マイクロアーキテクチャは一つのソリューションだろうけど、マイクロアーキテクチャにそぐわないシステムもあるので、パフォーマンス上の理由とかで。

プロダクト

(振り返ってみると意外に)プロダクトに関わってた。カルーセル、ユーザープロファイルへの広告表示、ビデオ広告、Promoted Moments などなど。


2016 年は選択と集中をもっと頑張らないと。「コードレビューは(自分がレビューしたいもの以外は)しない」とか「個人宛にきた質問はチーム全体にふる」とかやってるけど、まだまだ時間が足りないなぁ・・・。

家庭

第二子誕生

一人目の経験があるので、二人目は何かと楽ですね。とはいえ、小さいのが二人いるとプライベートな時間がなくなるね。


第一子がプリスクールに

日本語・英語環境のプリスクールに通い始めました。Montessori のプリスクールなのでいろいろ勉強(「お仕事」という)しているようです。ある日突然「南エリカ」とか言い出すから新しい友達かと思ったら「南アメリカ」のことだった。「世界地図をトレースする」という仕事があるらしい。

家を購入

メンテナンスがとてもめんどくさい。近いうちに売ってしまうかもしれない。「家をメンテナンスする」という仕事は自分に合ってないようだ・・・。

交通事故に遭う

もらい事故。保険屋と話したり、車を修理屋に持ってったり、大変だった。


2016 年は、まぁ粛々と・・・。こどもが大きくなってきたのでバケーションに時間をとるようにしたい気もするが、子供とどっか行く方がストレス大きいような・・・。

2015年11月15日日曜日

Facebook のトリコロール機能は有料にすべき

Facebook で自分のアイコンにトリコロールを重ねられる機能について。

なぜフランスだけなのかとか、フランス(を始めとする先進国)も空爆によって無差別殺人してるじゃないかとかいう指摘はもっともだと思うが、正直それを議論し始めると何も行動できないし、もっと正直に言うとこの程度のダブルスタンダードは今の所諦めるしかないと思う。世界は(まだ)公平じゃない。

私が思ったのは「この機能は有料にすべきだ」ということだ。具体的には「$10 寄付すれば、3 日間あなたのアイコンにフランス国旗を重ねて表示します」というのが良いと思う。理由は 2 つある。

まず、この機能の目的が、フランス人に対する哀悼の意であろうが、反テロリズムの意思表示であろうが、具体的な活動にはお金が必要だということだ。被害者の救済にしても、テロリズムの根本的な解決(それが何なのかわからないが)にしてもお金がないと活動できない。

そして、この機能が無料であることで、トリコロール化した人が本当に哀悼の意を表しているのか、テロ反対を表明しているのかよくわからなくなってるというのが勿体ない。「$10 もったいないから、トリコロールいらないや」という人がいたら、大して被害者のことも気にしてないし、テロ行為にも興味ないんだな、と私は思う。極端な話、テロリストだってアイコンをトリコロールにしてるかもしれない。その人が本当にある主張に賛同してるのかどうかを確認する最も確実な方法は、お金を払わせることだ。

Facebook の月間アクティブユーザーは 15 億人なので、10% が $10 寄付したら 15 億ドル。これだけあれば何か意味のあることができると思うんだけどね。少なくともアイコン変えるだけよりは、世界変えられる可能性が高いよね。


・・・というようなことは Facebook 社内でも議論されたんじゃないかと思うんだけど、なんで実装されないのかな。ちなみにこれ実装すると、ユーザーのクレジットカード情報も取れるから Facebook としても嬉しいと思うんだけど。

2015年5月24日日曜日

動物園の入場料比較

子供がいると、休日を何もせずのんびり過ごすというのが不可能になり、何かしないといけなくなる。で、今日は Oakland Zoo に行ってきた。以前に San Francisco Zoo にもいったことがあるので、この辺(SF 及び北東地域)の Zoo は制覇したことになる。


ふと気になって、動物園の入場料について調べてみた。メインの客は小学生だろうと仮定して、大人の入場料と小学生の入園料は以下のとおり。

(日本の動物園のうち、富士サファリパークは私立、他は公立)

日本の公立動物園の入園料の安さは一見して明らかだ。
誰でも入園できるようにという意図なのだろうが、赤字分は税金から補填されているはずで、それは公平な税金の使い方だとは思えない。動物園に行ったこともない納税者も多いだろうに。

そもそも動物園に行くという行動の価格弾力性は低いと思う。メインの客が子供を連れた家族だと仮定するなら、個人的な経験から言うと、入園料よりも例えば移動にかかる時間や移動の手間の方が負担だ。
子連れで(特に東京では普通であろう)電車で移動するのはとても苦痛だ。乗り換えの手間や車内で静かにさせる手間を考えれば、入園料が 600 円だろうが 1,200 円だろうが大して問題ではない。
また、「入園料が 1,200 円なら年 1 回しか行かないけど、600 円なら 2 回行く」というのも考えづらい。だったら 1,200 円に設定した方が良いだろう。受益者負担の原則にも則っている。

まぁ東京都はお金持ちなのでいいとしても、財政危機の横浜のズーラシアは入園料を見直した方が良いのでは・・・。

2015年5月23日土曜日

アメリカで交通事故にあった話(その 2)

MetLife のウェブサイトから事故のレポートをしたところ、約 3 時間後に電話がかかってきた。
簡単に事故の内容を伝えたあと、修理費用を見積もるという話に。「一番簡単な方法は、iPhone アプリで写真を撮ってこっちに送ることね」ということなので、その方法ですすめることに。
MetLife Choice Express というアプリをインストールして起動すると、「オドメーターの写真を撮れ」「故障箇所全体写真を撮れ」「ディテールの写真を 4 枚撮れ」との指示が。そのとおりすると、「24 時間以内に見積もり送るから待っとけ」というメッセージが。
修理の見積もりだって簡単に取れちゃうんです、そうアイフォーンならね。(注:android 用もあります)



2 時間後に notification があり、見積もり完了。これを修理屋に持っていって作業を依頼した。
「どのくらい時間かかるの?」「はっきりとしたことは言えないけど、今見えてる部分の修理だけでよければ、3, 4・・・」「(3, 4 時間か?)」「3, 4 日かな」「3, 4 日!!!」
そんなにかかるのかーーー。レンタカー必要じゃん。それも MetLife に連絡しなきゃ・・・。車の修理って時間かかるんだな・・・。数時間トンカンすれば直せるのかと思ってた。無知って怖いわ。

ちなみに、もし、実際の修理費用がこの見積もりを上回る場合は、修理屋が MetLife と話してくれるそうだ。まぁこれ以上面倒なことにならないよう祈るのみ。