ISUCON11に参加しました
こんにちは @0daryoです。
8/21に行われたISUCON11に参加してきました。
初参戦で自分たちなりに準備してきたつもりだったのですが完敗しました。 とても楽しく競技できたので運営の皆さんには感謝の気持ちでいっぱいです。
覚えているうちにやったことなど記録しておきます。
題材
ISUCONDITIONというサービスが題材でした。
椅子が擬人化(ペットに近い?)されてそのコンディションについて確認していくというような内容です。
マニュアルを読む時間を作っていたのですが、要件にあったチューニングをできる段階まで行けませんでしたorz
チーム
「賢者のつどい」というチーム名で大学時代の友人である @Panda_Programと参加しました。 主に分担として以下のような形で考えていました。 僕自身は仕事でもサーバーサイドをやっているのですが、Pandaさんはフロントメインであるためこんな感じです。
- 僕: Goアプリ, DB
- Panda: nginx, 監視
その他二人で適宜担当
事前準備
7月と8月に一度ずつ事前準備をしました。 主にISUCON9予選問題の環境を再現して練習していた気がします。 やったこととしては
- MySQL
- slow query
- index
- nginx
- log解析
- gzip圧縮
- キャッシュヘッダ調整
- 監視
- netdata
- htop
- new relic
- trace
- appとnew relic繋ぎ込み
- app
- pprof
この時主に監視などサーバー・アプリの状態を知る練習はかなり行っていたのですが、そこから次のアクションをどうするかという練習があまりできていませんでした。 それがもろに予選で何もできなかったことにつながったので来年こそは実装力を高めて臨みたいです。
当日
9:00~
- 集合
- オープニング動画を見る
10:00~
- マニュアルを読む
- 最初のベンチを回す
3500台でこの値がしばらく最高値となり苦しめられることになります
11:00~
- New relicでの外形監視・トレースを設定する
- POSTリクエストが支配的になっていることを確認
- slow query logの設定
- htopでリソース状況の確認
- ボトルネックになる部分確認
- deployフローの確認
いろいろなモジュールを入れたのでスコアが1000台になりました
ここまでは練習の通りにできているつもりでした。
12:00~
- nginx関連の設定を入れる
POST /api/condition/:jia_isu_uuid
がボトルネックになっていそうなので確認- insertを一括でできるように変更
- 遅延が許されるため非同期書き込みに変更
13:00~17:00
GET /api/trend
GET /api/isu
- N+1クエリを解消しようと試みるもfail連発
- transactionが必要ない場所を消す
- indexを貼る
- isu_condition.jia_isu_uuid
- isu_condition.timestamp
- isu_condition.jia_user_id
アプリ側で考えている実装を入れ切れることができず、焦り他の施策を考えたり実行する余裕がありませんでした。 圧倒的な実装力不足です。
17:00 ~
- 相変わらずスコアは1000台で敗北ムードが漂う
- 監視系モジュールを外し終了に備える
このタイミングでベンチマーカーが503を返すようになったため競技時間が延長となりました。 ベンチーマーカー復活後終戦感が漂っていたのですが、一応最後に回してみると個々の施策はある程度効いていたようで、17000台のスコアが出てテンション爆上がりしました。 (ちなみに16時台で10万超えているチームもいる状況ですw)
どうやらnew relicへのpushを毎APIで行っていたことがスコア低迷に大きく影響していたようです。
~19:00
競技終了まで相変わらずアプリ側の修正を行っていたのですが、決定打もなく最高スコア17900くらいでフィニッシュしました。
8/22 14:00
結果発表 最終スコアは16680で249位でした。
感想
実装力がないせいでなぜかfailするという状況を抜け出せず、 こだわり続けてしまったせいで他に思いついていた施策を一切試せませんでした。 特にsqlxなど生に近いクエリを書く練習が特に足りていなかったと感じています。 インフラ面についてもぱっと3台のサーバーを活かせるような構成を撮れればよかったのですが、CPUがパツっていることを確認しつつもアクションには移せなかったので反省です。
逆に準備していた監視・ボトルネックの特定についてはある程度できたのかなと感じています。
総じて準備が超大切ということを身をもって実感しました。 9時間近くめちゃくちゃ集中して楽しい時間だったので、運営の皆さんへは感謝の気持ちでいっぱいです。 また来年修行して出直してこようと思います。 @Panda_Programお疲れ様でした!
2021のOKR
Objective
- 技術者としてのレベルアップ
- プロジェクト推進能力
KeyResult
技術者としてのレベルアップ
Kubernetes
- Certified Kubernetes Application Developer (CKAD)の取得
- Certified Kubernetes Administrator (CKA)の取得
Cloud
- Google Cloud Certified Professional Cloud Architectの取得
Go
- OSSへの機能PR5つ
ネットワーク
- OS関連の勉強
書籍
- 月技術書2冊
- WEBDB Press/Software Designの購読
プロジェクト推進能力
- 仕事上のグレード2ランクアップ
- システム移行を2つ成功させる
- 高可用性を意識した提案を3つ行う
- トレーニーのレベルアップを実感してもらう
ここ1年で読んだ技術書まとめ
概要
この1年くらいで読んだ本のうち特に印象に残っている技術書を備忘録兼これから学んでいきたい人のために記録する。
現状
サーバーサイドエンジニアとして3年目。
Goでアプリケーション設計・実装をし始めて1年以上経ち、 開発メンバーに加えて多少責任ある立場は任せてもらっている状態。
技術書(同人誌含む)
Go
Goならわかるシステムプログラミング
Goならわかるシステムプログラミング(紙書籍+PDF版)www.lambdanote.com
システムコールの抽象化や通信プロトコル、並行処理など、webサービスをつくる場合使用するパッケージの隠蔽されている部分にフォーカスした内容。
Goを初めて半年ほど経った時に読み、ioの扱いへの抵抗がだいぶ減った。それに伴ってGo製ライブラリを読む能力も上がった気がする。
webエンジニアなら必要ないとの声もあるが、読んで損はない。
Go言語による並行処理
goroutineは並列ではなくて並行である。
csp(Communicating Sequential Process)の思想や、タスクスティーリングの説明など難解な部分もあるが、その分読み応えがあるのに加え、
概念的な説明のみにとどまらず、実装パターンも細かく載っている。
当時は半分も理解できなかった気がするのでまた読み直したい。
Go言語でつくるインタプリタ
いわゆる猿本。monkeyというgoをホスト言語としたインタプリタをつくる。
多少アレンジしたodyというインタプリタを作った。 GitHub - 0daryo/ody
加えて、自分はここから抽象構文木を触り始め、簡単なコードジェネレータ、静的解析くらいは作れるようになった。
コンパイラをつくる本作の続きが英語版のみ存在する。余裕がある時にやりたい。
Writing A Compiler In Go (English Edition)
アーキテクチャ・ミドルウェア
Real World HTTP 第2版 ――歴史とコードに学ぶインターネットとウェブ技術
http/1.0,http/1.1,http/2.0といった現役のプロトコルの紹介や、ブラウザの変遷、ヘッダ・cookie・SSL/TLSなど多種多様なwebに関するトピックがまとまっており、webサービス開発者は一読に値すると思う。
加えてGoでのサーバー・クライアントの実装が例示されていて、自分にとっては二度嬉しい本だった。新卒研修などにも適していそう。
もともとミニ版が無料で配布されていたのでパラパラとめくっているうちに、本編を読みたくなって購入した。
データ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計
世に存在する様々なデータ構造やその扱い方についての本。DBやstorageといったステートフルなシステムは本当に難しい。
個人的にはLSMツリーとBツリーの比較やトランザクションのレベルについての話が印象に残ってるが、はっきりいって分散アプリケーションが必要になったような経験がないので実感が湧かない部分も多々あった。
この本は特に開発者として経験に応じて違った理解度・感想になると思うので時間をおいてまた読み返したい。
におうコードの問題集 〜MySQLインデックスに立ち向かう編〜
自分がインデックスについて真剣に考えるようになったきっかけの同人誌。
当時はインデックスの種類すら知らず、貼っておけばとりあえず早くなる程度の理解だったが、読後には実行計画をある程度読めて、インデックスツリーの構築コストなども多少考慮に入れられるようになった。
他の本と比べてメジャーではなく、偶然技術書典で手に取った本なだけに見つけられてラッキーだった。
Docker実践ガイド 第2版 impress top gearシリーズ
dockerについてVMとの違いやリソース管理方法、ネットワークや永続化volumeのことまで載っている。
コマンドも詳細に載っているため、辞書がわりに良いかも。
暗号技術入門 第3版 秘密の国のアリス
読み始めたモチベーションとしては開発時、SDKに乗るだけのJWT認証など行なっているものの、少し想定パターンから外れると手も足も出なくなるので仕組みを知りたいと思ったため。
暗号学者の道具箱(対象暗号・公開鍵暗号・一方向ハッシュ関数・メッセージ認証コード・デジタル署名・擬似乱数生成器)はある程度のwebアプリケーション開発者なら知っていて当然?の内容がまとまっている。
実際に自分は今まで公開鍵暗号とデジタル署名を混同していたなど、理解が曖昧だった部分が浮き彫りになった。
体系的にわかりやすく暗号について学ぶ機会はなかなかないので、初~中級者にとってはものすごくいい教材になると感じた。
楕円曲線暗号や公開鍵暗号の仕組みなど数強でも十分に楽しめそう。(自分は理解していません)
まとめ
実務経験や読書量が増えたため、以前と比べてオライリーなど割とゴツめの本が多くなっている気がする。
一方で完全に理解できていないと感じる内容も多々あるので、時間をおいて読み直したい。
本のリストからもわかる通り、基礎的な内容はカバーして弱点をなくすという戦略を取っていたため、逆に自分の強みは何かと聞かれると答えられない。
サーバーサイドエンジニアとして3年目に入ったので、そろそろ今後のキャリアなど考えつつ何か強みを作っていきたい。
ちなみに今はSRE本をちまちま読んでいる。また定期的にまとめていきたい。
Handling authentication and authorization
読んだ本
Microservices Patterns: With examples in Java の13.3.3 Handling authentication and authorization
FTGO社のモノリシックサービスをマイクロサービスに置き換えるというシチュエーションを例にしてマイクロサービスの設計を解説
monolithic と micro serviceでの認証・認可
in-memory sessionでthread localな認証・認可を扱うだけでよかったモノリシックサービスに、 マイクロサービスを加えようとするときJWTのようなトークン認証を加える必要がある。
書籍の図とほぼ同じものであるが書き直した
図ではauth serviceとなっているが実際はモノリシックサービスを想定しており、
JSESSIONID
はモノリスからの移行という文脈なので、通常のモノリスサービスで扱うセッション管理のため
以下別マイクロサービスへのアクセス
クライアントは
USERINFO
をcookieに含めrequestAPI Gatewayは
USERINFO
をvalidate、それより後ろのサービスにAuthorization headerに入れてリクエストマイクロサービスはtokenをデコード、validate, 情報の取得を行う
ポイント
session_idとJWT両方を扱う この解説書自体モノリシックからマイクロサービスへの移行を前提としているので依然としてサーバーローカルでのセッション管理を用いている。
マイクロサービス前提ならJWTだけで良さそう。
USERINFOはAPI Gatewayより前ではcookieに入れて扱う
ブラウザベースのクライアントとサーバー間の部分ではcookieを使い、サーバー間通信の場合はAuthorization Headerにtokenを入れる。
ローカルのストアに保存などでも良いと思うが、ブラウザがクライアントであればcookieに乗るのが安全。
マイクロサービスにリクエストがついた時点でtokenのvalidateを行う
tokenの有効期限やroleによる認可、サービス間の疎結合などの観点からGatewayだけでなく各マイクロサービスでもtokenのhandlingが必要
感想
まずマイクロサービスで作る時はAPI Gatewayが大事!! それほど大きな発見はなかったが、なんとなく実装していたパターンの意味や重要性を考え直せたのでよかった。
余談ですが、この本は無限に時間が潰せます。
Java言語で学ぶデザインパターン入門 読了
概要
『Java言語で学ぶデザインパターン入門』を読み終えました。
モチベーション
主にこれを読もうと思ったのは、最近仕事中にやたらとアーキテクチャ系の疑問が出てきたり、議論しつつ決着がつかないということが多く、 自分の設計への理解不足を痛感したからです。(エンジニアリングむずすぎる)
デザインパターンは銀の弾丸だと思って、読み進めたのですが、結論から言うと今の所直接的には何も役になっていません
ちなみに業務ではGoを使っているのですが、一年ほど前まではJavaのエンジニアだったのでコード自体の理解はなんとか大丈夫でした。
印象に残ったパターン
Template method Pattern
public abstract class AbstractDisplay { // 抽象クラスAbstractDisplay public abstract void open(); // サブクラスに実装をまかせる抽象メソッド(1) open public abstract void print(); // サブクラスに実装をまかせる抽象メソッド(2) print public abstract void close(); // サブクラスに実装をまかせる抽象メソッド(3) close public final void display() { // この抽象クラスで実装しているメソッドdisplay open(); // まずopenして… for (int i = 0; i < 5; i++) { // 5回printを繰り返して… print(); } close(); // …最後にcloseする。これがdisplayメソッドで実装されている内容。 } }
上記のような構成でこのクラスを継承させた先に各メソッドの実装は任せつつ大元の処理の流れを決めるというもの。 綺麗だな〜頭いいな〜と思いました。
これが後から色々なパターンで出てくるので重要らしいです。 多分Goでは抽象メソッドがないのでできない。
Strategy Pattern
インターフェースの型に対して、パターンに合わせて実装を注入するというもの。 DIがやってることと同じ?という感想でした。
State Pattern
これぞOOPというような、オブジェクトによって振る舞いを変えるというもの。
Abstract Factory Pattern
難しすぎて理解できず印象に残った。 筆者もデザインパターンの中で一番難しかったと述べています。
abstract fatoryパターン一生理解できなそうだった
— odaryo (@0daryo) November 29, 2019
感想
書いてみて基本簡単なパターンしか印象に残っていなかったことに気づき悲しいです。 最近ずっと書いているGoでは継承がないので、直接使えないパターンもいくつかあったのですが、 移譲で代用する方法なども書かれていたので、機会があれば使ってみたいです。
普段何気なく書いているコードが実はこのパターンだった、頭いい!みたいな嬉しい気持ちにも時々なれました。 感覚で理解したつもりになっていたものをしっかりパターンとして落とし込むことで多少は理解が深まった(と思いたい)です。
加えてかなり良かったのが、UMLのクラス図の記法にに慣れられたことです。 完全に副産物なんですが、今までUMLの話題になるたびにIT専科を見に行ってましたが、 23パターン分のクラス図を見たのでだいたい覚えることができたことはかなりでかい。
総じていうとやはりOOP言語を使うハイレベルな開発者でデザインパターンのことをほぼ知らない人はいないと思うので、 開発者としてレベルアップするための一つの必須項目なんだと思います。 今後のじわじわと効いてくると嬉しいなという感じです。
まとまりはないですが、これからも読み終わったらちょくちょく更新していきます。
Go Conference 2019 Autumnに参加してきました
はじめに
10/28(金)にGo Con autumnに参加してきました。 Goを仕事で使い始めてから半年ほど経ち、〇〇.goなどのミートアップには積極的に参加するようにしていましたが、GoConのようにオフィシャル?なイベントには初参加です。
やはり見応えのあるセッションが多くやる気maxになりました。
エセGopher脱却に向けて日々精進します。 以下見たセッションの紹介です。
セッション紹介
Go GC algorithm 101
1個目からヘビー目の発表でしたが、 あまり触れたことのない人向けに説明も交えつつGOのGCの歴史について学ぶことが多かったです。
以下の本がオススメされていました。
stop the worldによりlatencyが落ちてしまう Mark and Sweep方式にて実装されていた以前のGOと
concurrent Mark and Sweep GCの違いなど、 今まで意識したことのない内容が多くとても楽しく聴くことができました。
Goにおける API Client実装パターン
Gopher道場出身の方らしい。
begginer向けと書いてあり、わかりやすい内容だったが、実務で役立つ点・共感できる点も多かったです。
帰って早速exponential backoffについて実装してみました。
OSS Performance Tuning Tips
まず世の中のソフトウェアは全て遅いものと考える という意識に脱帽しました。
- 問題箇所の特定
- benchmark
- どう解決するかの引き出し
- マージされるPR
- 解決策を考えたら一度benchmark
各項目についてテクニック?を発表されていましたが、 その中を通して、すぐpprof, benchmarkと言った心がけが大事ということが伝わってきました。
avoでGoでアセンブラが書けるなど、asmの闇に飲まれかけているらしいです 笑
Accelerate Go development with Bazel
monorepo build 辛い...などいきなり共感できる内容でした笑
gazzel, bazelの関係など今まで曖昧だったことがわかりやすく解説されていました。
以前軽く触れたことがあるのですが、学習・導入コストを考えると気軽にいれれるものではないそうで、istioもbazelをrepositoryから消したらしい...
- gazel: goのファイルを解析してbazelファイルを生成
- .bazelrc: option指定
- bazelisk: bazelのバージョン管理
- nogo: bazelの静的解析チェック
Check Container Images with Original Rules
container imageはコントロールしやすい! 数々のdockerの脆弱性検知ツール開発者による発表で、 GKEなどマネージドオーケストレーション上ではコントロールできる部分が限られてくるということ、
docker imageは静的解析が容易だということを力説されていました。
思ったよりお手軽にできそうに見えるので挑戦してみたいと思います。
Microsoft Graph API Library for Go
microsoft graph api SDKがGOに対応していないということで自分で作っちゃいました、という発表。
office365など自分では使っていないのですが、SDK作成のつらみ、ポイントなどが面白かったです。
Go Conference 2019 Autumn Go で超高速な 経路探索エンジンをつくる
重み付き有向グラフ、ダイクストラ法などギリギリ聞いたことがある内容でこの発表は理解できないかもしれないと思っていましたが、
しっかり解説されており、slice, mapなど基礎的なものをいかに高パフォーマンスで使うかという内容はとても勉強になりました。
さすがD社という気持ちです。
Welcome to Linter
linterを実際に会社で作成している方の発表。
最近静的解析に興味を持って取り組んでいるので、なんとかついていくことができました。
広く触れられている発表でしたが、実際の運用に乗せるまでのtipsなど興味深かったです。
compiler
以前記事でみたことのある内容でしたが、やはりみたいと思ってホールへ 喋りが面白くて、何回か爆笑してしまいました(panicの実装を忘れていたなど)
目の前で実際に第二世代以降のコンパイラをビルドしたりエンターテイメント性があって面白かったです。
これだけのことを実行にうつしてしまう姿勢は見習いたいです。
まとめ
会社の仕事をほぼほったらかして参加しましたが、得たものを仕事で活かせば必ずプラスだと言えるくらい濃い内容だったと思います。
どの発表もプライベートor仕事にすぐ活かせる内容が入っており、モチベーションが爆上がりです。
初参加でしたが、敷居は全然高くなく、それでいて(自分にとっては)ハイレベルなカンファレンスだったので次も必ず行きたいです。
Linuxのしくみを読んで
読んだ本
[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識
https://www.amazon.co.jp/dp/477419607X/ref=cm_sw_em_r_mt_dp_U_uAxpDb2BB37CE