ISUCON11に参加しました

こんにちは @0daryoです。

8/21に行われたISUCON11に参加してきました。

初参戦で自分たちなりに準備してきたつもりだったのですが完敗しました。 とても楽しく競技できたので運営の皆さんには感謝の気持ちでいっぱいです。

覚えているうちにやったことなど記録しておきます。

題材

ISUCONDITIONというサービスが題材でした。

椅子が擬人化(ペットに近い?)されてそのコンディションについて確認していくというような内容です。

マニュアルを読む時間を作っていたのですが、要件にあったチューニングをできる段階まで行けませんでしたorz

ISUCON11 予選問題 - YouTube

チーム

「賢者のつどい」というチーム名で大学時代の友人である @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位でした。

isucon.net

感想

実装力がないせいでなぜか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言語による並行処理

www.oreilly.co.jp

goroutineは並列ではなくて並行である。

csp(Communicating Sequential Process)の思想や、タスクスティーリングの説明など難解な部分もあるが、その分読み応えがあるのに加え、

概念的な説明のみにとどまらず、実装パターンも細かく載っている。

当時は半分も理解できなかった気がするのでまた読み直したい。

Go言語でつくるインタプリタ

www.oreilly.co.jp

いわゆる猿本。monkeyというgoをホスト言語としたインタプリタをつくる。

多少アレンジしたodyというインタプリタを作った。 GitHub - 0daryo/ody

加えて、自分はここから抽象構文木を触り始め、簡単なコードジェネレータ、静的解析くらいは作れるようになった。

コンパイラをつくる本作の続きが英語版のみ存在する。余裕がある時にやりたい。

Writing A Compiler In Go (English Edition)

アーキテクチャミドルウェア

Real World HTTP 第2版 ――歴史とコードに学ぶインターネットとウェブ技術

www.oreilly.co.jp

http/1.0,http/1.1,http/2.0といった現役のプロトコルの紹介や、ブラウザの変遷、ヘッダ・cookieSSL/TLSなど多種多様なwebに関するトピックがまとまっており、webサービス開発者は一読に値すると思う。

加えてGoでのサーバー・クライアントの実装が例示されていて、自分にとっては二度嬉しい本だった。新卒研修などにも適していそう。

もともとミニ版が無料で配布されていたのでパラパラとめくっているうちに、本編を読みたくなって購入した。

データ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計

www.oreilly.co.jp

世に存在する様々なデータ構造やその扱い方についての本。DBやstorageといったステートフルなシステムは本当に難しい。

個人的にはLSMツリーとBツリーの比較やトランザクションのレベルについての話が印象に残ってるが、はっきりいって分散アプリケーションが必要になったような経験がないので実感が湧かない部分も多々あった。

この本は特に開発者として経験に応じて違った理解度・感想になると思うので時間をおいてまた読み返したい。

におうコードの問題集 〜MySQLインデックスに立ち向かう編〜

booth.pm

自分がインデックスについて真剣に考えるようになったきっかけの同人誌。

当時はインデックスの種類すら知らず、貼っておけばとりあえず早くなる程度の理解だったが、読後には実行計画をある程度読めて、インデックスツリーの構築コストなども多少考慮に入れられるようになった。

他の本と比べてメジャーではなく、偶然技術書典で手に取った本なだけに見つけられてラッキーだった。

Docker実践ガイド 第2版 impress top gearシリーズ

book.impress.co.jp

dockerについてVMとの違いやリソース管理方法、ネットワークや永続化volumeのことまで載っている。

コマンドも詳細に載っているため、辞書がわりに良いかも。

暗号技術入門 第3版 秘密の国のアリス

www.hyuki.com

読み始めたモチベーションとしては開発時、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のようなトークン認証を加える必要がある。

書籍の図とほぼ同じものであるが書き直した f:id:plm23-ccc:20200102172642p:plain

  1. ユーザー情報を含んだリクエストを送る

  2. API Gatewayが認証管理用のサービス(例ではFTGO monolith)にルーティング

  3. 認証管理用サービスはJSESSIONIDとユーザー情報や役割・権限を含んだJWTであるUSERINFOcookieに含めて返す

図ではauth serviceとなっているが実際はモノリシックサービスを想定しており、

JSESSIONIDモノリスからの移行という文脈なので、通常のモノリスサービスで扱うセッション管理のため

以下別マイクロサービスへのアクセス

  1. クライアントはUSERINFOcookieに含めrequest

  2. API GatewayUSERINFOをvalidate、それより後ろのサービスにAuthorization headerに入れてリクエス

    マイクロサービスはtokenをデコード、validate, 情報の取得を行う

ポイント

  • 全てのリクエストはAPI Gatewayを通る ここでモノリス・マイクロ間の差異を吸収することで開発効率は上がる。

  • 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

難しすぎて理解できず印象に残った。 筆者もデザインパターンの中で一番難しかったと述べています。

感想

書いてみて基本簡単なパターンしか印象に残っていなかったことに気づき悲しいです。 最近ずっと書いているGoでは継承がないので、直接使えないパターンもいくつかあったのですが、 移譲で代用する方法なども書かれていたので、機会があれば使ってみたいです。

普段何気なく書いているコードが実はこのパターンだった、頭いい!みたいな嬉しい気持ちにも時々なれました。 感覚で理解したつもりになっていたものをしっかりパターンとして落とし込むことで多少は理解が深まった(と思いたい)です。

加えてかなり良かったのが、UMLのクラス図の記法にに慣れられたことです。 完全に副産物なんですが、今までUMLの話題になるたびにIT専科を見に行ってましたが、 23パターン分のクラス図を見たのでだいたい覚えることができたことはかなりでかい。

総じていうとやはりOOP言語を使うハイレベルな開発者でデザインパターンのことをほぼ知らない人はいないと思うので、 開発者としてレベルアップするための一つの必須項目なんだと思います。 今後のじわじわと効いてくると嬉しいなという感じです。

まとまりはないですが、これからも読み終わったらちょくちょく更新していきます。

Go Conference 2019 Autumnに参加してきました

はじめに

10/28(金)にGo Con autumnに参加してきました。 Goを仕事で使い始めてから半年ほど経ち、〇〇.goなどのミートアップには積極的に参加するようにしていましたが、GoConのようにオフィシャル?なイベントには初参加です。

やはり見応えのあるセッションが多くやる気maxになりました。

エセGopher脱却に向けて日々精進します。 以下見たセッションの紹介です。

セッション紹介

Go GC algorithm 101

speakerdeck.com

1個目からヘビー目の発表でしたが、 あまり触れたことのない人向けに説明も交えつつGOのGCの歴史について学ぶことが多かったです。

以下の本がオススメされていました。

ガベージコレクションのアルゴリズムと実装

stop the worldによりlatencyが落ちてしまう Mark and Sweep方式にて実装されていた以前のGOと

concurrent Mark and Sweep GCの違いなど、 今まで意識したことのない内容が多くとても楽しく聴くことができました。

Goにおける API Client実装パターン

speakerdeck.com

Gopher道場出身の方らしい。

begginer向けと書いてあり、わかりやすい内容だったが、実務で役立つ点・共感できる点も多かったです。

帰って早速exponential backoffについて実装してみました。

OSS Performance Tuning Tips

speakerdeck.com

まず世の中のソフトウェアは全て遅いものと考える という意識に脱帽しました。

  • 問題箇所の特定
  • benchmark
  • どう解決するかの引き出し
  • マージされるPR
  • 解決策を考えたら一度benchmark

各項目についてテクニック?を発表されていましたが、 その中を通して、すぐpprof, benchmarkと言った心がけが大事ということが伝わってきました。

avoでGoでアセンブラが書けるなど、asmの闇に飲まれかけているらしいです 笑

Accelerate Go development with Bazel

speakerdeck.com

monorepo build 辛い...などいきなり共感できる内容でした笑

gazzel, bazelの関係など今まで曖昧だったことがわかりやすく解説されていました。

以前軽く触れたことがあるのですが、学習・導入コストを考えると気軽にいれれるものではないそうで、istioもbazelをrepositoryから消したらしい...

  • gazel: goのファイルを解析してbazelファイルを生成
  • .bazelrc: option指定
  • bazelisk: bazelのバージョン管理
  • nogo: bazelの静的解析チェック

Check Container Images with Original Rules

speakerdeck.com

container imageはコントロールしやすい! 数々のdockerの脆弱性検知ツール開発者による発表で、 GKEなどマネージドオーケストレーション上ではコントロールできる部分が限られてくるということ、

docker imageは静的解析が容易だということを力説されていました。

思ったよりお手軽にできそうに見えるので挑戦してみたいと思います。

Microsoft Graph API Library for Go

speakerdeck.com

microsoft graph api SDKがGOに対応していないということで自分で作っちゃいました、という発表。

office365など自分では使っていないのですが、SDK作成のつらみ、ポイントなどが面白かったです。

Go Conference 2019 Autumn Go で超高速な 経路探索エンジンをつくる

speakerdeck.com

重み付き有向グラフ、ダイクストラ法などギリギリ聞いたことがある内容でこの発表は理解できないかもしれないと思っていましたが、

しっかり解説されており、slice, mapなど基礎的なものをいかに高パフォーマンスで使うかという内容はとても勉強になりました。

さすがD社という気持ちです。

Welcome to Linter

speakerdeck.com

linterを実際に会社で作成している方の発表。

最近静的解析に興味を持って取り組んでいるので、なんとかついていくことができました。

広く触れられている発表でしたが、実際の運用に乗せるまでのtipsなど興味深かったです。

compiler

speakerdeck.com

以前記事でみたことのある内容でしたが、やはりみたいと思ってホールへ 喋りが面白くて、何回か爆笑してしまいました(panicの実装を忘れていたなど)

目の前で実際に第二世代以降のコンパイラをビルドしたりエンターテイメント性があって面白かったです。

これだけのことを実行にうつしてしまう姿勢は見習いたいです。

まとめ

会社の仕事をほぼほったらかして参加しましたが、得たものを仕事で活かせば必ずプラスだと言えるくらい濃い内容だったと思います。

どの発表もプライベートor仕事にすぐ活かせる内容が入っており、モチベーションが爆上がりです。

初参加でしたが、敷居は全然高くなく、それでいて(自分にとっては)ハイレベルなカンファレンスだったので次も必ず行きたいです。

Linuxのしくみを読んで

読んだ本

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

https://www.amazon.co.jp/dp/477419607X/ref=cm_sw_em_r_mt_dp_U_uAxpDb2BB37CE

 

動機

文系で大学を出て、エンジニアになり実務経験はまだ一年半の自分にとって低レイヤーは未知の領域です。
 
一度転職しているのですが、前職ではシステム構築はベテランの仕事であり、自分はアプリケーション層のみ、言われた仕様通りの実装をするいわゆるコードモンキーでした。
 
オンプレシステムだったのでlinux(Cento OS)を使う機会自体はありましたが、周りに詳しい人はおらず、最低限の知識しか持っていませんでした。(上司はviを使いながら矢印キーで移動してたぐらい)
 
一年目の終わりに転職して自社サービスを作る会社でバックエンドを担当しているのですが、新しいことだらけで業務についていくのも大変でした。今もですが・・・
 
現在業務ではGCPを使っています。
cloudサービスでは直接linuxを扱う場面は少なく隠蔽されていることが大半ですが、
やっている領域はインフラに近くなってきたこと、具体的にはk8sネットワークやDNS、コンテナなど基礎知識がないと厳しい領域を扱うことが多くなり、
その辺の知識が新入社員研修レベルでは流石にやばいと思い、
大学の同期で優秀なエンジニアから薦めてもらった[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識を読むことにしました。
 

内容

冒頭でも説明されているのですが、比較的浅めの知識の方が読んでも概要は掴めるような内容だと思います。
osのカーネルモード、ユーザーモードの違いなどから始まり、プロセスの仕組み、CPU、メモリ、ストレージについて概念を説明してあります。
度々図やC言語で実装を伴った説明があり、コードを読みつつベンチマークを確認できるので、抽象度と具体度がちょうどいい本だと感じました。
全部のコードを理解できれば良いのですが、この辺に詳しくない方は概念を追うだけでも十分学ぶことは多いと思います。
 

ポイント

新卒研修で大雑把な話はわかっているつもりでしたが、
- プロセススケジューラー
- メモリキャッシュ、メモリ、ストレージの関係、特にページテーブルの考え方
などは今まで知らなかったことが多く勉強になりました。
 

感想

正直なところ今のところほぼ業務では役立っていませんが、今後表面的な策では解決できない問題が起きた時のアプローチの幅が増えるのではないかと期待しています。
あとこの本を読んでよかった点として、他の低レイヤー関連の本を読むハードルが低くなったと感じています。
現在は『

マスタリング TCP IP 

』『

30日でできる Os自作入門

』を少しずつ読みすすめています。
インフラ関連への興味がかなり湧いてきたので、今後はバックエンドよりもdevops系を優先的に学んでいきたいというお気持ちです。