しんぶんぶん

しんぶんぶんのブログ

強迫観念駆動人生の末路

はじめに

以前、以下のようなブログを書いた。

shinbunbun.hatenablog.jp

私はこのブログがそこまで広がる想定ではなく、あくまで私のコンテキストを知っている身内に向けて書いたものであった。しかし予想外に拡散されてしまい(たくさんの方に読んでいただけたのはとても嬉しく思っているが)、自分の意図とは違う意味で「強迫観念駆動人生」という言葉が広まってしまった気がしている。 文章を書いてインターネットで公開すると、自分の意図しない受け取り方をされてしまうことがあるのは理解しつつ、私の中で「強迫観念駆動人生」はそのままの意味でここ数年の私の人生そのものであるため、自分のコンテキストを付与して(それでも伝わり切らない部分の方が多いとは理解しつつ)、この文章を遺そうと思う。 また、あのブログは公開するにあたって婉曲や一般化をしている部分もあるため、この文章はその修正も兼ねている。

このブログは有料公開にしている。 記述している内容に私の個人的な思いや人生の話などが多く、「強迫観念駆動人生へ愛を込めて」ほど広がってほしくはないという思いがある。あまり気持ちの良い内容でもないし、一般化もしていないため共感を得れるものでもない。このブログを読んでも何か学びがある人の方が少ないと思っている。

お金を取りたいという意図は全くなく、あくまで本当に読みたい人にだけ読んでほしいという思いからこの形をとっていることはご理解いただきたい。

目次

  • 今までのコンピュータ人生
  • 生ける屍
  • 強迫観念駆動人生とはなんだったのか
  • おわりに

全4525文字

この続きを読むには
購入して全文を読む

セキュリティ・キャンプ2024 ネクスト 応募課題晒し

はじめに

セキュリティ・キャンプ 2024 ネクストに合格しました!

セキュキャンには応募課題晒しなる文化があると聞いたので、駄文ではありますが、今後応募する方々の参考になればと思い公開します。

※この応募課題にはかなり不正確な記述が含まれている可能性が大いにあります。中身云々ではなく、ネクストの課題ってこんな感じで書くんだなという見方をしていただけると助かります。

課題

www.ipa.go.jp

セキュリティ・キャンプ ネクストでは、広範囲な分野を深く理解し、新たな攻撃をいち早く見つけ、理解し、基盤から根本的な対策を講ずるために新たな価値を生み出していけるトップオブトップの人材、フルスタック・エンジニアと呼ばれる人材を発掘・育成することを目的とします。 またその修了後には、既存の受け皿に納まるのではなく、多くの人や技術を巻き込んで活躍することを期待しています。 このため自身の技術力だけでなく、新たな技術や未知の分野に抵抗感無く踏み出せるか、新たな発想や価値観を生み出せる素養があるか、といった点を評価します。 課題に対する回答の正否でなく、そうした点を見て総合的に判断します。 ぜひ、そのような視点で応募にのぞんでみてください。

(注意:過去のセキュリティ・キャンプ全国大会への参加の有無にかかわらず、応募が可能です。但し、セキュリティ・キャンプ全国大会との併願はできません。)

選考のポイント

基本として、加点法で判断します。 自身の技術力ややってきたこと、発信してきたこと、何ができるかといったことなど、アピールしたい点を存分に記述してください。 多く書くことにより、「文章が長過ぎる・まとまりが無い・重複している・冗長」などとして減点するようなことはありません。失敗した経験や落選の結果を書くことや、「文章が洗練されていない」「誤字脱字がある」などによる減点もありません(文章や作文のテストではありません。内容を見ます)。アピールをいっぱい書いて、得をすることはあっても、損をすることはありません。自身がアピールしたいことを思い付くままにいっぱい書いて、アピールしてください。 いかにやる気があるか、参加できたらいかに頑張ることができるか、ということを「示して」ください。「やる気があり、今までこうしたことをやってきています」「このようにいままでずっと手を動かしてきています」「こういったものを作ったことがあります」「今までこんな活動を継続してきています」ということを書くといいでしょう。それが、やる気を証明することになります。

課題については、課題が解決できたかどうかや正誤で判断するのではなく、いかに自身で疑問を持ち課題設定するか、その課題を解決しようとする過程や未知のことにどのように取り組むか、新たなことに挑戦しようとする姿勢を見ます。 このため課題は解決できなくても構いませんし、正答にたどりつけなくても構いません。課題に対する正答を求めているわけではありません。途中経過でも構いませんし、自分なりの考えでも構いませんので、いかに取り組んだか、難しい課題にこのように取り組んでこの辺りまではわかった、自分なりにこう考え、こういうことを調べた・試した、自分はこう考えこう思ったという、その過程を書いてください。自身のできる範囲で課題設定して回答するのでなく、ぜひ今まで知らなかったものに挑戦して、その挑戦の過程を書いてみてください。その結果正答でないとしても、それは挑戦しているためとして判断します。

手を動かしてみてください。ネット検索で調べたことを張り付けるだけではなく、本当にそうなのかという疑問を持ち、自分で手を動かして、見て、試し、調べ、確認し、本当にそうなのかと深堀りして考えてみてください。ネット検索で出てきたことは、はたして本当なのでしょうか︖深堀りして理解し納得できているでしょうか︖疑問点や矛盾は無いでしょうか(矛盾があるとしたら、その原因はどこでしょうか)︖自分の眼や手で確認したでしょうか︖他人に説明できるでしょうか︖そして、そうしたことを書いてください。課題解決に対する、そのような姿勢を見ます。

自分の提出したもの

※スライドは公開リンクに差し替えてあります

■ あなたに関する問い

あなたは今までどのようなことをやってきましたか.どのようなことができて,どのようなことが得意で,どのようなことに自信がありますか. どのようなものを作りましたか.どのような情報を発信してきましたか. どのようにしてそうしたことをやってきましたか.なぜ,そのようなことをやってきましたか.やってきてどう思いましたか. 参加できた場合,セキュリティ・キャンプ ネクストにどのようなことを期待し,どのようなことをやってみたいですか.

私は今まで、Web開発を中心にコンピュータへ触れてきました。インターンシップや業務委託などでフロントエンド/バックエンド/インフラそれぞれ一通り触っており、自分の得意分野といえばWeb開発だと思います。最近はシステムプログラミングにも手を出して、主にRustを中心に書いています。Rustを最初に書いて以来、その書きやすさに感動してずっとRustを書いています。特に感動したのがEnumとパターンマッチングで、Option型、Result型を最初に使った時は新鮮でとても驚きました。それまではNode.jsをメインで書いていたため、Option型でNull安全に書けるのはとても気持ち良いものでした。また、Result型とquestion mark operatorを使ったエラーハンドリングの綺麗さがとても好きです。Rustは得意と言えるレベルかはわかりませんが、大好きな言語です。

私が取り組んできたことはポートフォリオhttps://shinbunbun.info/ )に記載していますが、その中から抜粋して(また、それに加えて)以下に私が今まで取り組んできたことを紹介します。

Rust製コンテナランタイム

github.com

【未公開スライドのため割愛】

コンテナの仕組みに興味があり、低レベルコンテナランタイムをRustで自作しました。Linuxシステムコールまわりへの知識や、どのようにプロセスを分離しているかなどの理解が深まりました。

RustでMerkle-CRDTの実装

github.com

【未公開スライドのため割愛】

サイボウズ・ラボユースのシステムソフトウェア研究開発コースで、Merkle-CRDTというアルゴリズムを用いて分散KVSの実装に挑戦しました。いくつかの論文を参考に実装したため、そういった文献を読む力や、自分の知らないアルゴリズムを理解する力がつきました。結局KVSの実装までは至りませんでしたが、Merkle-CRDT上で動くG-Setの実装まではできました。

Hands-on LINE botの執筆

github.com

nextpublishing.jp

インプレス技術の泉シリーズからHands-on LINE botというLINEBotの入門書を出版しました。言語はNode.jsで書かれており、AWS LambdaへのデプロイやDynamoDBとの接続まで対応しています。この書籍を執筆するにあたっては、如何に初心者が自分の作りたいLINEBotを作れるようになるかという部分に焦点をおきました。リポジトリのコードは自分なりに改造がしやすいようになっており、このリポジトリをテンプレートにしてたいていのLINEBotを作れるように執筆しました。

Raftの実装

github.com

セキュリティ・キャンプ全国大会2023で分散合意アルゴリズムであるRaftをGoで実装しました。複数のレプリカがある分散システムにおいてどのように合意形成をとっていくかという部分の理解が深まりました。

Rust製LINEBotSDKの自作

github.com

RustでLINEBotを作る環境がなかったため、SDKから自作しました。自分が今まで触ったことのなかった型レベルビルダーパターンに挑戦し、開発しやすいSDKを作れました。

Rust製SNSアプリケーションの自作

github.com

株式会社ゆめみのインターンシップで、Rust製のSNSを実装しました。この時はRustに触るのが初めてだったため、Enumとパターンマッチングなど、関数型パラダイム特有の考え方をたくさん学習できました。また、actix-webなどを使ったRustでのWeb開発方法についても学習できました。

分散型台帳を使ったイベント参加者募集プラットフォーム

github.com

protopedia.net

IOTAという分散型台帳を使って、Decentralized Identifiers(DIDs)とVerifiable Credentials(VCs)を使ったイベント参加者募集プラットフォームを作りました。3人で制作し、自分はVCsの発行周りを担当しました。DIDsやVCs、IOTAの仕様書を読みながら実装したため、仕様書の読み方などを学習できました。

secp256k1をフルスクラッチ実装

github.com

ビットコインなどに使われているsecp256k1という楕円曲線暗号の署名アルゴリズムをRustを使ってフルスクラッチで実装しました。暗号は元から興味があり、高校生の頃から耐量子計算機暗号などについて学んでいたので、気付けば割と長い間触っている分野です。有限体の定義などから全て実装したため、署名アルゴリズムの理解につながりました。また、有限体、楕円曲線、それを用いた署名アルゴリズムをなるべく疎結合に実装し、再利用性を上げました。

自宅k8sサーバを立てる

NixOSが載っている自宅サーバk8sを導入してmisskeyのサーバをたてました。クラウドk8sを使ったことは何回かあったのですが、オンプレは初めてだったため、最初の構築の部分から学習できました。

ユーザースペースで事前に学習したニューラルネットワークの推論をeBPFプログラム(XDP)で実行し、カーネルレベルでIDSを実装する

【未公開スライドのため割愛】

NAISTの研究室インターンで、教授の研究に関する実験を行いました。eBPFも機械学習もあまり触ったことがなかったため、基本技術に関する勉強になりました。また、カーネルスペースで推論を動かすために量子化などの工夫を行う必要があるため、その点についてもとても勉強になりました。

WebAuthenticationの実装

ヤフー株式会社のインターンでGo言語を使ってWebAuthenticationのフルスクラッチ実装を行いました。こちらも仕様書をかなり読む必要があるタイプの開発でした。Go言語もWebAuthnも初めてだったため、その点でも勉強になりました。また、ペアを組んでのチーム開発だったため、どのようにコミュニケーションをとりながら開発を進めるかなども勉強になりました。

Agones上に作るQUICを使った音声通信機能に関する検証と開発

shinbunbun.hatenablog.jp

株式会社MIXIインターンシップで、Agones上に作るQUICを使った音声通信機能に関する検証と開発を行いました。 このインターンではRustやGo、gRPC、Agonesなど様々な技術を学習できました。また、sendmsg, resvmsgなどのネットワーク系システムコールについて理解を深めることもできました。

自宅インフラ構築

上記のスライドにあるのは高校生の頃から学部1年までの記録です。PKIやL2VPNの構築など、私のネットワークに関する知識はここから得られた部分がかなり大きいです。現在は引っ越してNAT越えする必要がなくなったため、Rustビルド専用として買った12900kを積んだマシンを自宅においており、ポート解放&DDNSの設定をして外からSSHできるようにし、開発マシンにしています。

なぜ、そのようなことをやってきたかといえば、知的好奇心とコンピュータが好きな気持ちが大きかったと思います。基本的に技術は好奇心駆動で触ってきました。コンピュータは何を触っても楽しいし、面白そうなことが多すぎるので一生退屈しなさそうで嬉しいです。

ネクストキャンプに参加できた場合、私はシステムソフトウェア/低レイヤーに関してもっと知識をつけたいと考えています。今までWeb系を中心に触ってきたため、最近システムソフトウェアの領域に手を出しつつはありますが、まだそこまでしっかりさわれているわけではないのが現状です。そのため、そのあたりの知識や技能をつける一歩目にしたいです。ネクストの講義はFPGAやネットワーク周りなど、自分が興味があったり触っている分野ばかりなため、その辺りに関する知識/技能を身につけたいです。

■ 課題への姿勢に関する問い

自身で何らかの技術的な疑問を設定し,その疑問を解決しようと取り組み,その過程を示すことで,自身の技術力や課題に取り組むやりかたを説明してください. (疑問の例:実行ファイルはどのような構造になっているのだろう? pingコマンドを実行すると何が起きるんだろう? オンラインゲームはどうやって通信対戦を実現しているのだろう? といったようなことです) 設定する疑問は何でも構いませんし,解決しなくても構いません. 解決できたかどうかではなく,いかに課題に取り組むかという点を評価します.

課題: AWSのDynamoDBはどのような目的で作られてどのような仕組みになっているのか

私は触りたい技術があった場合、論文や仕様書(RFCなど)がある場合はそれを参照しにいくことが多いです。最初のとっかかりとしてQiitaなどのブログ記事を読むことは多々ありますが、色々開発をする中で一次情報をあたる重要性に気付き、しっかりと理解したい技術はできるだけ一次情報をあたるようにしています。査読論文や仕様書というものは色々な人のレビューが入った上で高い完成度の文書として公開されています。多少読むのが辛くても、最後はそこを参照するのが理解への近道だと思っています(とはいえ今回は時間の関係上、一部の技術に関しては一次情報をあたることができなかったことが悔やまれます)。

課題に関しては、論文[1]をベースに周辺知識を含めて調査しました。特に参照の記載がない場合は基本的に[1]を参照しています。

まずDynamoが開発された背景を整理します。 例えば、Amazonのショッピングカートサービスでは、ネットワークやサーバーの障害の中でも、顧客がショッピングカートにアイテムを追加したり削除したりできるようにする必要があります。しかし、従来のデータストアではこの要件を満たせていません。従来の多くのデータストアは、書き込み中に競合解決を実行し、読み取り処理が複雑にならないようにしています。しかし、そのようなシステムでは、データストアがある時点でレプリカのすべて(または大多数)に到達できない場合、書き込みを拒否することがあります。一方Dynamoは、書き込みが決して拒否されないようにするために「常に書き込み可能な」データストア(すなわち、書き込みに高い可用性を持つデータストア)として設計されています。 上記のようなユースケースに対応するためにDynamoは作られました。

また、Dynamoの設計において個人的に興味深かった点としてビザンチン耐性がないことがあげられます。 ビザンチン耐性のあるシステムとは、分散システムにおいてノードが悪意を持って偽の情報を伝達する・故障して誤った情報を伝達するなどの事象が起こった際に、全てのノードで合意を形成できることを指します。Dynamoは、そのようなデータの完全性やセキュリティの問題に焦点を当てずに、信頼できる環境を前提に設計されています。例えばブロックチェーンなどは悪意のある人間による市場に対する攻撃が行われる危険性があるためビザンチン耐性が必要ですが、Dynamoの場合はAWSというある程度信頼性の高い環境で動くことが想定されているため、あえて設計や運用が複雑になるビザンチン耐性の性質を持たせる必要がなかったのではと私は考えました。

次に、従来のreplicated relational databaseとの違いについて述べます。 従来のreplicated relational databaseはStrong Consistencyという一貫性に焦点を当てています。 Strong Consistencyとは、すべてのクライアントから見たすべての操作が何らかの順序で一貫しているというものです。[2] 私は、書き込みが行われた後に読み出しをした際、最新の更新が必ず反映されているものという解釈をしています。 このようなシステムはスケーラビリティと可用性に限界があり、例えばネットワークパーティションを処理することができないと[1]では述べられています。 ネットワークパーティションは、クラスターサーバー間の通信路に障害が発生し、クラスターサーバーがネットワーク的に分断されてしまう状態のことです。[3] この場合、Strong Consistencyなシステムでは一貫性を保つために可用性を犠牲にする必要があると私は考えています。パーティションが解決されない状態でシステムがリクエストを受理すると、ノード間でのデータの整合性がとれなくなる可能性があるため、解決されるまでリクエストを受理することができず、可用性が低下します。 一方、DynamoはEventual Consistencyという一貫性を採用しています。 Eventual Consistencyは、あるデータ項目に新たな更新が行われなかった場合、最終的に(結果的に)その項目へのすべてのアクセスが最後に更新された値を返すことを非公式に保証するものです。[4] 書き込み(更新)は(1つ以上のノードが生きている場合)常に受理されるが、その後に読み出しをしてもその更新が反映されている保証はなく、しかし最終的には全てのノードの状態が収束して整合性が取れるようなものだと私は解釈しています。 このようなシステムでは、ノード間が同期される前に複数箇所で更新が起こった場合にコンフリクトが起こりうるため、収束させるためになんらかの競合解決メカニズムを実装する必要があります。DynamoではVector Clockという論理クロックの一種である手法が使われています。 このように、一般的にEventual Consistencyなシステムは一貫性を犠牲にする代わりに強い可用性を手に入れていると私は考えています。 ただし、Dynamoはquorum systemsを採用することで一貫性と可用性のバランスをとっています。 以下にquorum systemsに関する説明を記述します。以下は[1]に加えて[5]を参考に記述しています。 まず、R: 読み取り操作に参加しなければならない最小限のノード数、W: 書き込み操作に参加しなければならないノードの最小数、N: データが複製されるノードの総数とした時、R + W > Nの関係が成り立つようにRとWが設定されます。これにより読み取り操作と書き込み操作の間に少なくとも1つの共通ノードが存在することが保証されるため、最新のデータを読み込むことが可能になります。 RとWの値を調整することによって一貫性と可用性のバランスを調整することができます。例えばWを1に設定した場合、システム内に少なくとも1つのノードがあり、書き込み要求を正常に処理できる限り、システムは書き込み要求を拒否することはありません。これは可用性が高いと言えます。しかし、WとRの値が低いと、大多数のノードで処理されていない場合でも書き込み要求が成功とみなされ、不整合のリスクが高くなる(一貫性が損なわれる)と言えます。 Dynamoは上記のような形で、Eventual Consistencyを採用しつつ、一貫性が求められる場面ではそこを強化するといった調整ができるようになっています。

他にもDynamoに施されている工夫はたくさんありますが、私が興味を惹かれ、かつある程度理解できた範囲で上記にまとめました。一通り論文を読んでみた所感としては、そもそも作られた目的からしてかなり限られたユースケースで使われることを前提としているシステムだと感じました。一般的なアプリケーション開発では、Strong Consistencyが採用されているDBを使い、読み込み整合性が保証されている方が嬉しいのかなと思います。ただ、例にあげられていたショッピングカートのように、「常に書き込み可能」という制約がある状況においては、とても有益なシステムだと感じています。アプリケーション開発をする場面において、満たさなければいけない要件をきちんと考え、それに適したものを採用していく必要があるということに気付かされました。今まで分散システムの分野についてちょっとずつ勉強はしてきましたが、Dynamoについてちゃんと調査するのは初めてだったので、とても良い機会になりました。

参考文献

[1] DeCandia, G. et al. (2007) ‘Dynamo: Amazon’s Highly Available Key-value Store ’, Proceedings of twenty-first ACM SIGOPS symposium on Operating systems principles [Preprint]. doi:10.1145/1294261.1294281.

[2] Eventual consistencyまでの一貫性図解大全 (no date) Qiita. Available at: https://qiita.com/kumagi/items/3867862c6be65328f89c (Accessed: 20 May 2024).

[3] HAクラスター入門 ~用語解説3~ (no date) NEC. Available at: https://jpn.nec.com/clusterpro/blog/20171016.html (Accessed: 20 May 2024).

[4] 結果整合性 (no date) Wikipedia. Available at: https://ja.wikipedia.org/wiki/%E7%B5%90%E6%9E%9C%E6%95%B4%E5%90%88%E6%80%A7#cite_note-Vogels-1 (Accessed: 20 May 2024).

[5] 最近よく聞くQuorumは過半数(多数決)よりも一般的でパワフルな概念だった (no date) Qiita. Available at: https://qiita.com/everpeace/items/632831371da5ff215995 (Accessed: 20 May 2024).

■ 興味ある分野に関する問い

セキュリティ・キャンプ ネクストの講義の一覧を見て,その中から興味のある講義を選び,その講義で扱うテーマに対して自分が考えること,興味,疑問,課題,自分なりの考察などを説明してください. その分野について知識があるかどうかではなく,いかに興味や疑問を持ち,課題を考え,自分なりに調べて考察するかといった点を評価します.

興味のある講義: Content Delivery Network を自作してみよう

CDNは普段Web開発をする時にたまに使っているので興味があります。以下に、CDNについて何も調べない状態で自分が考えていることを記述します。 自分が使ったことのあるCDNはCloudflareとAWSのCloudFrontです。例えばCloudFrontは高校生の時によく使っていたのですが、S3を使って静的ホスティングをした際に、S3を直接公開するよりもコストが安い、ACMで発行したサーバ証明書を無料でアタッチしてhttps対応ができるなどの理由だけで使っていました。私は、CDNの本来の利点はキャッシュができることとエッジ対応できることだと思っているので、あまり活かした使い方は出来ていないと感じています。この状態で自分が疑問に思っていることを以下に箇条書きします。

  • どのようなアプリケーションであればCDNの利点をきちんと活用できるか
  • DNSまわりがどのような仕組みになっているのか(例えばCDNを使わない場合はAレコードに自分のサーバのIPアドレスを記述しますが、CDNを使ってエッジする場合はアクセス元の地域によってアクセス先のIPアドレスが変わると思います。そのようなケースでどのようにDNSまわりが動いているのかが気になります。)
  • 高速にレスポンスを返すためにどのような処理が内部的に行われているのか(サーバからそのまま返すよりもCDNから返した方が速いというイメージがあります。それが正しければ、どのような仕組みになっているのかが気になります。)
  • DoS攻撃などに対する対策はどのように行われているのか(昨今だと機械学習を使って不審なパケットを分類する手法もあるため、CDNでそういったものが実装されているのか、他にもどのような手法で対策が行われているのかが気になります。)

以下は、上記の文章を書いた後に実際調べてみたことや考えたことをまとめています。

まず自分が感じた疑問点1つ目の「どのようなアプリケーションであればCDNの利点をきちんと活用できるか」についてです。 私が調べた中で一番メリットが大きいと感じたのは動画配信です。[6]によれば、動画ストリーミングにCDNを利用するメリットは、「視聴者との距離を最短にすることで、遅延を軽減」「オリジンサーバに負荷がかからない」「ストリーミングコンテンツがネットワークの帯域幅を超えない」などがあげられます。だいたい一般のコンテンツをCDNで配信する時のメリットと似通っていますが、動画というパケット量が多くなるコンテンツであるからこそCDNを使うメリットを引き出せるのではと感じました。

次に2つ目の「DNSまわりがどのような仕組みになっているのか」についてです。 [8]を読んだところ、エニーキャストという仕組みを使っていることがわかりました。[9]によれば、エニーキャストとは、着信リクエストをさまざまな場所(「ノード」)に転送できるネットワークアドレッシング/ルーティング方式のことです。要は1つのIPアドレスを複数のサーバに適用できる仕組みになります。Cloudflareがどのようにしてエニーキャストを実装しているかは[11]で紹介されていました。例えばCloudflareのDNSサービスのIPアドレスは173.245.58.205で、ホップが最も少ない経路で世界各国にあるCloudflareデータセンターのうちのどれかにパケットが送られます。例えば福島県会津若松市にいる自分がこのIPアドレスに対してtracerouteすると以下のような結果が返ってきます。

traceroute to 173.245.58.205 (173.245.58.205), 30 hops max, 46 byte packets
1  _gateway (192.168.1.1)  1.364 ms  1.034 ms  1.165 ms
2  fksnij41.asahi-net.or.jp (118.243.96.16)  3.987 ms  4.358 ms  3.805 ms
3  cs1bi2-v2228.asahi-net.or.jp (118.243.96.174)  8.570 ms  8.432 ms  8.538 ms
4  cs1cr4-v1151.asahi-net.or.jp (202.224.52.172)  14.744 ms  9.418 ms  24.212 ms
5  cs1ni3-v1173.asahi-net.or.jp (202.224.52.217)  9.330 ms  9.783 ms  9.648 ms
6  101.203.88.62 (101.203.88.62)  10.827 ms  25.958 ms  *
7  103.22.201.38 (103.22.201.38)  11.398 ms  103.22.201.31 (103.22.201.31)  12.576 ms  103.22.201.38 (103.22.201.38)  11.068 ms
8  molly.ns.cloudflare.com (173.245.58.205)  12.830 ms  9.932 ms  9.858 ms

ipinfoで7番の103.22.201.38を検索すると、Cloudflare所有のIPアドレスで東京にあるデータセンターであることがわかります。 [9]の記事には、ロンドンやサンフランシスコから同じことをすると、それぞれの近くにあるデータセンターを通っていることが確認できると記述されています。 これらの技術を使うことで、ある1つのIPアドレスへのリクエストを地理的に近いデータセンターへルーティングできる(エッジ)ことがわかりました。

次に3つ目の「高速にレスポンスを返すためにどのような処理が内部的に行われているのか」です。 CDNでロード時間が短縮される仕組みは主に以下のものが挙げられます[11] 1. IXPにサーバを配置する[12] IXPはISPCDNなどが相互に接続しているポイントを指し、異なるネットワークのエッジと言えます。IXPにサーバを配置することにより、他のネットワーク間とのトランジットの経路を短縮でき、レイテンシー削減、RTTの改善などにつながります。 2. 距離の短縮 世界中にサーバがあるので(エッジ)、クライアントと要求されたデータの物理的な距離が短縮でき、結果RTTが短くなります 3. ハードウェア/ソフトウェアの最適化 SSDや効率的な負荷分散を用いてサーバ側のインフラストラクチャのパフォーマンスを高めることができます。 4. データ転送の削減 コードのミニファイやgzipなどでのファイル圧縮により、データ転送量の低減をしています。

最後に4つ目の「DoS攻撃などに対する対策はどのように行われているのか」についてです。 前述のエニーキャストがDDoS対策の1つとして挙げられます。[9] エニーキャストはリクエストが複数のサーバに分散されるため、1つのサーバにトラフィックが集中することを防げます。 また、当初考えていた機械学習を使ったDDoS対策は、一般的にはCDNではなくWAFの責務であることがわかりました。

一通りCDNについて調べてみた所感としては、やはり静的なファイルを配信する際はCDNを使うことがとても有効であることがわかりました。ただし、動的なアプリケーションにCDNを挟んでしまうと、キャッシュされてはいけないものがキャッシュされてしまうため、使い所を慎重に選ばないと危ない面もあると感じました。そういった場面では自分が学んでいる分散システムが活きてくることもあるんだろうと考えています。

参考文献 [6] (No date a) 動画CDNとは? | CDN動画ストリーミング | Cloudflare. Available at: https://www.cloudflare.com/ja-jp/learning/video/what-is-video-cdn/ (Accessed: 20 May 2024).

[7] (No date) CDNのメリット:CDNを使う理由は?. Available at: https://www.cloudflare.com/ja-jp/learning/cdn/cdn-benefits (Accessed: 20 May 2024).

[8] Cloud CDN の概要と仕組み | google cloud 公式ブログ (no date) Google. Available at: https://cloud.google.com/blog/ja/topics/developers-practitioners/what-cloud-cdn-and-how-does-it-work (Accessed: 20 May 2024).

[9] (No date a) How does anycast work? | cloudflare. Available at: https://www.cloudflare.com/ja-jp/learning/cdn/glossary/anycast-network (Accessed: 20 May 2024).

[10] Prince, M. et al. (2023a) Load balancing without load balancers, The Cloudflare Blog. Available at: https://blog.cloudflare.com/cloudflares-architecture-eliminating-single-p/ (Accessed: 20 May 2024).

[11] (No date a) Cdn performance | cloudflare. Available at: https://www.cloudflare.com/ja-jp/learning/cdn/performance/ (Accessed: 20 May 2024).

[12] (No date a) インターネットエクスチェンジとは? - Cloudflare. Available at: https://www.cloudflare.com/ja-jp/learning/cdn/glossary/internet-exchange-point-ixp (Accessed: 20 May 2024).

■ その他に関する問い その他,アピールしたい点などあれば自由記述で回答してください.

私は自分が今まで触れたことのない技術に触るのが大好きです。自分の中に新しい知識が入ってくるとものすごくワクワクします。とにかく面白そうな技術だと思ったらなんでも飛びついてしまうタイプです。課題に取り組む過程でも色々調査しながら新しい知識が増えるのが楽しすぎて、本来掘るつもりではなかった部分まで掘り進めてしまいました。 今回のネクストキャンプも、私が深く触ったことのない技術が多く、講義一覧を見ているだけでワクワクが止まりません。今まで行ったインターンシップなども、全て自分が深く触ったことのない分野に挑戦できるものばかり参加してきました。今回もそのような挑戦をさせていただける場を提供いただけるのならとても嬉しいです。もし参加できることになった暁には、吸収できるものを貪欲に全て吸収し切って帰りたいと思っています。

強迫観念駆動人生へ愛を込めて

はじめに

自分は最近までかなり強迫観念に囚われて生きてきたのですが、最近それが薄れてきて今までの生き方を俯瞰的に見れるようになったので、いったん文章をしたためてアウトプットしておきます。かなり雑多な文なので読みにくいかもしれません。

共感を呼ぶような生き方ではないので、こんな人もいるんだなくらいで読んでください。共感してくれる人がいたら頑張って生きていこうなという気持ちです。

強迫観念駆動人生

自分は以下のような強迫観念を最近まで抱いていました。

  • 何者かにならないといけない
  • 何か大きいことを成し遂げないといけない
  • 常に手を動かし続けないといけない
  • 無駄なことをやっている暇はない
  • 技術をやらないと死ぬ
  • 技術的に価値のない自分に生きている価値がない

強迫観念はどこからきたのか

そもそも強迫観念には、環境や人などの外的要因と、自ら植え付ける内的要因があると思っています。

外的要因

まず自分の外的要因として一番大きかったのは筑波大学のAC入試に落ちてしまったことです。今は会津大学にいるのですが、会津に来てしまったからには入試の失敗を取り返さないといけない、何か成果を出さなくてはいけない、何者かにならなくてはいけないと思っていました。

また、増幅させる原因として自分の観測範囲に強い人がいすぎたという問題があります。特に一番悪影響だったのはTwitterで、TLを見ればすごい人ばかり流れてきます。全人類未踏採択されてる、全人類セキュリティキャンプ受かってる、全人類ラボユース採択されてる、全人類起業して資金調達してるし、全人類暖色コーダーのような錯覚をしてしまうのです。

基本的に大学1年からはずっとこのような劣等感に苛まれて生きてきました。

ただ、一般的な人間はこのような劣等感だけでは前述のような強い強迫観念は生まれないと思います。ここまで増幅させた一番の原因は以下の内的要因です。

内的要因

とりあえず「強くならないといけない」程度の強迫観念を外的要因により植え付けられた自分は、強くなるためにもっと強迫観念を増幅すれば良いのではと考えました。そこで、入学した会津大学で実力に見合わないポジションを取り「しんぶんぶん」という虚像を作れば、実体とのギャップを埋めるために死ぬ気で努力するから強くなれるという手法を試します。

自分の手札には「ハッカソン受賞歴」「高校生ながらインターンに行っていた経験」「共著で商業誌を執筆した経験」などがあったため、これらをうまく使いながら本来の自分より数倍も実力があるようなふりをし、「イキリ力」で「技術的にめちゃめちゃ強い人」というポジションを取りました。

もちろん自分より技術のできる人なんて大学にたくさんいるので、下手なムーブをするとすぐボロが出ます。ボロが出て周りに失望される前に自分の実力を上げてそのギャップを埋める必要があるため、死ぬ気で頑張らなければいけないのです。失望される恐怖はとても強い燃料になります。

自分はこのような状況を作り出すことにより、とても強い強迫観念を自分に植え付けることができました。

自分のアイデンティティ

強迫観念を増幅させるもう1つの要因としてあったのが、自分のアイデンティティがコンピュータにあったことです。

中高生の頃からコンピュータをずっとやり続けていると、だんだん自分のアイデンティティがコンピュータに寄ってきます。特に自分は高校生の頃からコミュニティに出て色々な大人に褒められて承認欲求を満たすという経験をしていたので、自分に関する価値はコンピュータに依拠する部分がかなり大きいと思っていました。

前述の通り、Twitterには(外から見ると)天才(に見える人)がたくさんいます。そういう人たちをみると自分はこいつらに勝たなければいけないという強迫観念が生まれてきます。なぜなら、そいつらに負けると自分のアイデンティティが揺らいでしまうから。

強迫観念が増大すると何が起こるか

自分は1日15~20時間くらいずっとコンピュータを触り続けている生活になりました。大学のオープンスペースの一角を占有して、朝起きてから寝るまでコンピュータをやり続け、限界に達したら寮に帰る or 大学のソファーで寝るといった具合です。

最初の方はアドレナリンが出続けどうにかなったのですが、半年くらいたってだんだんキツくなってきて、ちょっとセーブしつつそれでも1年半くらい続けていたら精神がぶっ壊れました。

周りへ与える影響

強迫観念に囚われているとまわりにもそれを振り撒いてしまうことが起こります。技術をエンジョイしている人をみると、「俺は命をかけてやっているのにこいつらはなんなんだ、カスなのか?」という気持ちになってくるのです。命をかけて技術をやっていない人間がだんだんゴミに見えてくるし、自分の信じている評価軸が技術一辺倒になるため、技術でしか人を判断できなくなります。そのような調子でまわりにも命を削ることを強要すると、友達がいなくなります。

実力に見合わないポジションを取ることの危うさ

前述の通り失望に対する恐怖は強迫観念の燃料になるのですが、やはり気付く人は本当の私の実力がわかってしまいます。このやり方をすると本当の実力者から嫌われる危険性があります。

また、当たり前ですがまわりの評価に対して自分の実力が見合っていない状態はとても精神的負荷がかかります。やってる間はずっと精神的に辛いし、やり続けると結果的に精神が壊れます。

強迫観念駆動人生で得たもの

マイナスのことばかり綴ってきましたが、リスクを取る分やはり得るものはかなり大きいです。当たり前ですが毎日十数時間コンピュータを触り続ければかなりできるようになります。最初はただのイキリ野郎でしたが(まぁ今もそうなんですが)、とったポジションに見合うとまではいかなくとも、大学生にしてはそこそこできる方なんじゃないかというレベルの実力はつきました。

ただ、逆に言えばこれだけやってもこの程度の実力しかつかなかっため、とったリスクに大して十分なリターンがあったとは言えないなと思っています。

強迫観念を薄れさせるには

自分と同種の強迫観念を持っている場合は、ある程度現状の自分に満足することが一番の近道です。自分の場合は、作り上げた虚像と現実のギャップがある程度埋まり、他者の評価軸でもある程度戦っていける実力や実績がついた時に強迫観念がだんだん薄れてきました。結局、一度強迫観念を持ってやり始めてしまったら、どれだけ苦しくても満足いくまでやり切るしかないと思っています。精神がぶっ壊れるのか自分が満足するのか、どっちが早いかのチキンレースです。

ただ、薄れさせることはできても完全に無くすことは難しいです。自分も薄れた時期はありましたが、周りの環境がちょっと変化するとすぐに再燃しました。今の自分は安定していますが、自分の精神が未熟な限りずっと付き纏われるんだろうなと思っています。ただ、結局厨二病を拗らせているだけなので精神が成熟したらなくなっていくものなんじゃないかという希望的観測もあります。

それでもコンピュータは嫌いになれなかった

どれだけ苦しくてもコンピュータのことだけは絶対嫌いになれませんでした。結局どこまでいっても自分はコンピュータが本当に好きなんだろうなという確信は持てました。好きだからこそ苦しくてもここまで続いた部分はかなりあると思います。

死人に口なし

ここまで色々かいたものの、結局これは全部生存バイアスです。死人に口なしなのです。自分はたまたまある程度ものになりましたが、間違っても真似はしない方が良いと思います。ただ、人生いろいろあるので、自分の命をかけてでも成長しないといけない場面があるかもしれません。そのような場面にぶち当たった時にこのブログを思い出して「そういや1人同志がいたな」と思ってもらえると僕も嬉しいです。

おわりに

適度な強迫観念を持つことは効果的ですが、いきすぎるとこうなるという一つの事例でした。やっぱりコンピュータは適度に楽しむのが一番良いと思うのです。みなさんは適切な摂取量で素敵なコンピュータライフを送ってください。

学生エンジニアコミュニティに対するお気持ち

学生エンジニアコミュニティに対するお気持ち

はじめに

Twitterで「就活エージェントがバックについてる学生コミュニティってどうなんだ?(意訳)」みたいな話題が上がっており、学生エンジニアコミュニティについていくつか思うところがあったのでつらつらと書いていきます。かなり雑多な文章なので「はぇ〜そんな考えの人もいるのか」くらいのノリで読んでください。

全体を通して言いたいことは「一括りに学生エンジニアといえどみんな向いてる方向は違うから、自分に合ったコミュニティが見つかると良いよね」という話です。

みんな向いている方向が違う

これは学生云々関係ない話ですが、そもそもお金稼ぎのために技術をやっている人もいれば好きでやっている人もいます。同じように学生にも、就活のために実績を作っている人もいれば、就活とは全く関係ない技術ばっかりを好きでやってる人もいれば、自分が好きでやったことが就活につながれば嬉しいなぁというスタンスの人もいますよね。

向いている方向が違う人たちが相容れないのは当たり前の話なので、棲み分けかなと思っています。

学生エンジニアコミュニティを分類してみよう

じゃあ指向性はどのように分類できるのでしょうか?僕が今まで所属していたコミュニティを例に挙げていくつかに分類してみます。

100%好きでやっている人たち

SGG(すごくなりたいがくせいぐるーぷ)

僕が高校生の時に友達と一緒に立ち上げた、高校生エンジニア中心のコミュニティです。

このコミュニティは高校生が主体で運営しているため、お金稼ぎとか就活とかが介在する余地がありません(まだそのフェーズではないので)。そのため、ほぼほぼ100%好きでやっている人たちが集まっている印象でした。

TOGATTA SERVER

僕が最近立ち上げたコミュニティです。社会人も入れるので厳密には学生コミュニティではないのですが、一応例として挙げておきます。

このコミュニティは加入条件が「アクティブな技術オタク」なので、技術オタクじゃない人はそもそも入れないようになっています。また、ほぼ内輪だけでやっているので好きなことをいくらでも話せます(とはいえある程度外に開いていいないと新しい人が入ってこないので、参加登録すれば毎回のLTは誰でも聞ける形にしていますが)。

少し就活色のあるコミュニティ

Zli

僕が代表をやっていた会津大学の技術系サークルです。

Zliは基本的には技術が好きな人とか興味ある人が集まる形になっているのですが、「就職のために大学に入ってきた人」もたくさんいるので、「就職のために技術を学びたい」人もたくさんいます。そういう意味では、Zliは2つのタイプが入り混じっているコミュニティになります。

また、企業を呼んで合同LT会を開いたりもしています。これは、協賛金をもらって活動資金を得るため、学生の企業に対するアピールの場にするため、企業のことを知るためなどの目的があります。総じて、参加学生の主目的はやはり「就活につなげるため」というところが大きいでしょう。

就活色が色濃いコミュニティ

就活エージェントなどがバックについているタイプのコミュニティですね。 運営側としては採用につなげるのが目的で、入ってくる人も就活に繋げるのが目的なので、必然的に就活職は色濃くなります。

学生エンジニアコミュニティの持続性について

最初は好きでやっている人が集まっていたのにだんだん就活色が出てきてしまったというパターンは割とあるんじゃないかと思います。個人的には、コミュニティの持続性を考えると就活色を出すのが一番手っ取り早いのではと考えているので、まぁ仕方がない側面が大きいのかなと。色々理由はありますが、大きいところで言うと「運営費の問題が解決する」「利害関係者が増えるからちゃんと運営せざるを得なくなり、結果的に持続する」「さらに運営元自体が企業になれば投入できるリソースの量が違うのでさらに持続性が増す」などかなと。

とはいえ企業が絡んでくると色々デメリットもあります。「しがらみが増えて好きなことがやりにくくなる」「就活目的の人ばかり集まってきて元のコミュニティの色がなくなっていく」などですね。

これは完全にトレードオフなので、特に大学のサークルなどのコミュニティは良い距離感で企業と付き合っていくのが重要かなと思っています。

総括して個人的なお気持ち

結局僕は早口技術オタクニチャニチャコミュニティが好きなのであった(終)という話になってしまうのですが、とはいえ僕はZliの代表をやって企業さんと色々イベントをやったりしていたわけです。

Zliがあったから企業とのつながりもたくさん作れたし、インターンに繋がったりしたのでそれはそれでよかったと思っています。これは、「僕は技術が好きだしオタク同士でずっとニチャニチャしていたいけど、現実問題としていつか就活する必要もあるのであった」という話であり、Zliで活動していたことでそこはうまくいったので、次のフェーズとしてオタクニチャニチャコミュニティを作って、就職してからも仕事とは別にオタクだけでずっとニチャニチャしていたいということです。

所属するコミュニティは1つに絞る必要はないですし、フェーズによって必要なコミュニティも変わってくると思います。

みんな自分の指向性に合ったコミュニティを見つけていければとても良いと思いますし、なかったら作れば良いだけなので。

もし指向性のあわない人たちと相容れないのだとしても、それは仕方がないことです。そこは棲み分けだと思いましょう。

僕が言いたいことは大体書けました、それでは。

セキュリティ・キャンプ全国大会2023 参加記

セキュリティ・キャンプ全国大会2023 参加記

はじめに

しんぶんぶんです!

セキュリティ・キャンプ全国大会2023 Y3 分散合意ゼミに参加したので、参加記を書いていきます!

応募課題

応募課題はこちらです。

僕の回答は恥ずかしいので公開しませんが、色々検討はずれなことを書いていた気がします。

調べて回答する系が多いので、ランポート先生の論文などをありがたく拝読しながら回答しました。

事前課題

事前課題はこちらです。

僕が実装したリポジトリこちらです。

課題1はTCP通信でのEcho Serverの実装、課題2は課題1をRPCで再実装、課題3は課題2をベースにState Machineを実装といった形になっています。

課題4はレプリケーションの実装なのですが、普通にやり忘れてました、反省。

共通講義

こちらに掲載されています。

個人的にはハッカーの倫理が一番面白かったです。電車の話でした(違う)

キャンプ当日

1日目

遅刻せずに無事クロスウェーブ府中に辿り着けました。

到着したらまずお昼ご飯です。

そば

最初は開講式から始まりました。

近いゼミごとに席が分かれていたので、周りの人と早速名刺交換して交流しました。

開講式が終わった後は共通講義とLTを聞き、グループワークをしました。

グループワークのテーマは「セキュリティに関するコンテンツを作ろう」的なもので、5人ずつのグループに分かれてアイデア出しをしていく形になります。

僕達のグループは、アイデアはたくさんでたのですが全くまとまらずに初日のグループワークが終了しましたw

グループワーク後は夕食です。

夕食

めちゃめちゃ豪華ですね〜。美味しかったです。

夕食後はデザートタイム兼交流会で、色々な人と名刺交換しました。

その後は各ゼミに分かれて顔合わせ兼開発タイムです。

ClientからLogをLeaderに追加して、Leaderが他のノードにレプリケーションするという仕組みを作りました。

2日目

朝ご飯

朝ご飯です。普段朝食べないので少なめ。

2日目は1日開発デーです。

リーダー選挙を実装しました。

昼ごはんです。

かれー

夕飯です。

ゆうはん

2日目の最後には協賛企業イベントがありました。1人あたり4社の話を聞けるような形になっています。

僕は以下の企業さんのお話を聞かせていただきました。

どの会社もセキュリティ部署の担当者の方がいらっしゃっていて、どのようなセキュリティ業務を行っているかなどを中心にお話ししていただきました。

3日目

朝ご飯です。

あさ

そろそろ朝起きるのが辛くなってきます。

3日目は朝から楽しい社会見学で、バスに乗ってIPAに行きました。 詳しい内容は話しちゃいけないらしいので省きますが、施設を見学したり登大遊さんからお話を聞いたりできました。

帰ってきたら昼食です。

らーめん

食べ終わったらまた開発です。

3日目はログレプリケーションを実装しました。 

夕飯の写真は撮り忘れました...。

4日目

4日目は1日中開発です。

僕は3日目までにコア機能の開発が終わっていたので、発表資料の作成をしていました。

昼ごはんです。

pasutaaaaaaaaa

午後にはYトラック内で発表会があり、1人5分で成果発表を行いました。

5日目にも全体の成果発表があるのですが、Yトラックではそこで発表する人を1つのゼミあたり1人投票で選ぶ形になっていて、僕は投票で選ばれたので5日目にも発表することになりました。

発表資料を作っていて、デモ動画や実演がめちゃめちゃやりづらい(CUIの画面見せても何やってるかよくわからない)のに気づき、急遽Vue.jsでビジュアライザを作ることにしました。

ちょっと遅くまでカタカタしてたおかげで無事5日目の発表には間に合いました。

あ、夕飯はこちらです。

おにく

夕飯後はLT会があり、僕も1本しゃべりました。 資料はこちらです。

LT会の後にはグループワークの続きがありました。

僕たちのグループはなんと「自作CPU+自作OS+自作Webサーバ」を作るという壮大なコンテンツをぶち上げました。

これ実はキャンプ後も継続するらしいのでとても楽しみです。

夜に突発的に有志による名刺交換会が実施されて、いろいろな人と名刺交換しました。暑かった(物理的に)。

5日目

朝ご飯です(昼ごはんは撮り忘れました)

あさ

5日目は発表会と閉講式がありました。

発表会、いろいろなゼミでやってることを聞けてとても楽しかったです。

自分の発表資料も貼っておきます。

ビジュアライザのデモ動画です。

おわりに

いかがでしたか!?

セキュキャンに参加すればこんなに美味しいご飯が無料で食べられます! みんな参加しよう!!

おわりに(まじめ)

僕の身の回りにはアプリケーションレイヤーをやっている人間が多いので、低レイヤー(システムソフトウェアなど)のことをやっている方々と仲良くできてとても良い刺激になりました(特にYトラックの方々)。

開発ももちろん楽しかったのですが、それ以上に受講生同士や講師・チューターの方々との交流がとても楽しかったなと思っています。

オフライン開催をしてくださった運営の方々には頭が上がりません、本当に。

キャンプでお世話になったみなさま、本当にありがとうございました!

来年も何らかの形で参加したいなと思っています!!

MIXIのインターン参加してきた

はじめに

会津大学学部三年のしんぶんぶんです!2023/3/15~4/5までの約3週間MIXIインターンに参加したので、やったことや感想など書いていきます!

端的にまとめると

全部読むのめんどくさいよ!という方のために簡潔にまとめると、

  • RustとかGoとかgRPCとかAgonesとか色々触ったよ
  • 過去一楽しいインターンだったよ
  • オフィスめっちゃ綺麗で最高の環境だったよ

というような話です。

インターンに参加した経緯

最初にMIXIインターンを知ったのは学部1年のころで、みんな大好き魔法のスプレッドシートを見て面白そうだなーと思っていました。

そんなこんなで学部2年になり、12月ごろに春インターンを探していて、本当はサイバーエージェントインターンに行こうと思っていました。なのですが、年末年始だからなのか応募フォームがなぜか閉じていて応募できなかったので、そういえばMIXIインターン面白そうだったなということを思い出して応募してみることにしました。

僕は認証に興味があったしMIXIには認証界隈で有名な某氏もいらっしゃるので楽しそうだなーと思い、最初はMIXI Mの部署を希望していました。

ところが時期的にタスクがなくて受け入れが難しいということで、改めてどこの部署が良いかなーと探していたところ、部署横断でRustやElixirが書けて高い専門性を持ったエンジニアが多く在籍しているという「開発本部CTO室たんぽぽグループ」という部署を見つけ、これは面白そうだぞ!!ということでこの部署に希望を出しました。

選考フローは書類→人事さんと面接→エンジニア面接→人事さんと希望の部署について面談→受け入れ希望先部署との面接で決定という流れでした。

人事さんとの面接はわりとちゃんと"面接"という感じがする面接でした。 エンジニア面接は結構雑談感が強くて話しやすかったです。 受け入れ希望先部署との面接は、タスクと僕のやりたいことがマッチしているかの最終確認だけという感じで、枠は1時間あったのに15分くらいで終わったような覚えがありますw

その後、電話で合格の連絡が来て無事インターンに行けることになりました。

オフィスについて

インターンはリモートでも出社してもどちらでも大丈夫だったのですが、僕はせっかくだから出社したかったのでインターン期間中は毎日出社しました。

場所は渋谷スクランブルスクエアで、地下鉄の渋谷駅から直結してるので一切外に出ずにオフィスまで行けます。

オフィスの机は電動昇降式デスクで、椅子はアーロンチェア。 コーヒーマシンやウォーターサーバー、お湯が用意されていて味噌汁やスープなども無料で飲めます。

35階にある社食はビュッフェ形式になっていて、1g1円でお昼が食べられます。めちゃめちゃ美味しいです。 ローソンやバイロンベイコーヒーも入っていて、めちゃめちゃ設備が整っている印象でした。

社食

インターンでやったこと

いよいよ本題のインターンでやったことについてです。

今回僕が触ったのは、「Agones上に作るQUICを使った音声通信機能」です。 詳細はMIXI TECH CONFERENCEで発表されているこちらの資料を読んでいただければ理解できるかなと思います。

要するに、「WebTransportを使って実装した音声通信機能をAgones上に載せたもの」という感じです。

登場人物と構成

  • aria-server
    • RustとElixirで書かれた音声用サーバ
    • 1ルーム1podが割り当てられる
    • Agonesに乗っている
  • aria-allocator-proxy
    • aria-serverはマルチクラスター構成になっているため、サービスから来たリクエストを元にどれを使うかをここで決める
    • Cloud Runに乗っている
    • GoでgRPC
  • aria-allocator
    • 実際にaria-serverをAllocateし、接続用のtokenを生成する
    • GKEに乗っている
    • GoでgRPC
  • aria-server-lite
    • aria-serverをRustだけで書き直したもの
  • aria-cui-client
    • aria-serverにリクエストを送れるクライアント
    • Rust製

アーキテクチャ

※画像はAgones上に作るQUICを使った音声通信機能より引用

aria-serverとaria-server-liteの違い

今回重要になってくるのはaria-serverとaria-server-liteの違いです。

まずaria-serverは、Thread/MicroProcessをたくさん用意し、Queue(Channel)を通してイベントを投げていくメッセージパッシングになっています。複数のコアを有効活用して使い切る思想です。 クライアントは20msに1回音声パケットを送信するのですが、例えば4人部屋の場合、サーバは1回のrecvあたり、自分へのAck、他の3人へのブロードキャストで系4回のsendが発生します。 4人のメンバーが送信している場合はその4倍で、20msに4回のrecv、16回のsendが発生することになります。 それぞれのタイミングはずれるので、この方法だとコンテキストスイッチシステムコールが頻繁に発生します。

対してaria-server-liteは、コンテキストスイッチ、ロック、システムコールを極力減らすことが目的で作られています。 サーバは複数のバッファの配列を用意してrecvmmsgをします。そして、4つのバッファが全部埋められるか指定秒数経過するかどちらかの条件を満たすまで待ちます。 カーネルは受信したパケットを全部一発でアプリケーションに戻します。 アプリケーションは受け取った4つのパケットをループ処理していき、それぞれ送信すべきデータを宛先ごとにバッファします。 そうすると各ユーザーに送信すべきデータはそれぞれ4つのQUIC Frameになるため、それぞれ1つのQUICパケットにまとめて合計4つのパケットをsendmmsgに渡して一括送信します。 こうすることで、socket関連のシステムコールはresvmmsg, sendmmsg一回ずつに削減することができます。 また、一連の処理は一括で行われるため、コンテキストスイッチのポイントもありません。 Agones上で動かすことを考えた場合、同じマシンで稼働している別Podのプロセスがresvmmsgのバッファを満たした時 or タイムアウトした時プロセススケジューラにとって処理が移ります。 個々のプロセスは、最低限のシステムコール、thread間を移動しない一括処理によってさくっと処理を終えて、他のプロセスがすぐにCPUを使えるようにします。

今回僕がやったこと

aria-server-liteが実戦投入可能かを確かめるために、期待されていた性能改善ができているのかの検証と、Agonesへのデプロイをするのが今回のタスクでした。

細かいタスクは以下の通りです。

  1. aria-server, aria-server-lite, aria-cui-clientをスタンドアローンで動かす
  2. 性能検証の時にパケットロスが起きていると正しい測定ができないため、パケットロス率を確かめるプログラムをaria-cui-clientに実装する
  3. 1で立てたスタンドアローンの環境を使い、サーバのメトリクスをとって性能検証をする
  4. Agonesにaria-server-liteをデプロイする

ここからはそれぞれのタスクの詳細について書いていきます。

aria-server, aria-server-lite, aria-cui-clientをスタンドアローンで動かす

まずはaria-server, aria-server-lite, aria-cui-clientをスタンドアローンで動かすために、GCEのインスタンスを用意しました。

aria-server, aria-server-liteは本来Agones上で動かすものなのですが、今回は性能検証のためにスタンドアローンモードで動かしました。

パケットロスの検出

aria-cui-clientにパケットロス率を表示する機能を実装しました。

送信時のシーケンス番号をグローバル変数に保存しておき、受信時に抜けがないかを確認することでパケットロスを検出しています。

具体的な手法としては、

  1. once_cellを使って、グローバルに送信元クライアント番号とシーケンス番号を保管するHashMapを定義
  2. 500リクエストに一回HashMapの中身を確認してパケットロスがないかをチェック

といった形になります。

性能検証

性能検証は主に以下の方法で行いました。

vmstatの検証結果

まず、CPU使用率はaria-server-liteの方が圧倒的に低いです。9スピーカーで40%ほど違いが出ました。

コンテキストスイッチaria-server-liteの方が少ないという結果になりました。

コンテキストスイッチシステムコール、ロックを減らすのがaria-server-liteの目的なので、CPU使用率、コンテキストスイッチが減ったのは期待通りの結果です。

レイテンシー

クライアントを2つ使用し、片方のクライアントで送信してからもう片方のクライアントで受信するまでにどれくらいの時間がかかるかを計測しました。

aria-server, aria-server-liteそれぞれのインスタンスからaria-cui-clientのインスタンスへのpingに有意な差がなかったためこの方法で計測しています。

結果はaria-server-liteの方が遅かったのですが、これも想定通りの結果です(aria-server-liteはコンテキストスイッチシステムコールを抑えるためにsendmmsg、recvmmsgを呼ぶ回数を4人分まとめて1回ずつに抑えているため、そのぶん待ち時間が発生します)。

perf, pprof-rs

フレームグラフを作ってボトルネック解析をしました。 aria-server-liteに関してはカーネル以外の部分でボトルネックになっているところが特になかったため、設計思想通りの動作になっていることがわかりました。

dhat

とりあえず計測してみたものの、あまり使えそうなデータは取れなかったです。

Agonesにaria-server-liteをデプロイ

すでにaria-serverがたっているクラスタaria-server-liteのpodを追加する形でデプロイしました。

やったことは以下の通りです。

  • DockerfileとCloud Buildの設定を書く
  • Terraformのアップデート
  • TerraformでCloud Buildのトリガーを書く
  • aria-server-liteのマニフェストを追加
  • aria-allocator(-proxy)を改造
  • aria-cui-clientを改造

まずはCloudBuildでビルドできるようにDockerfileとCloudBuildの設定ファイルを書きます。 その次にTerraformでCloudBuildのトリガーを書こうと思ったのですが、TerraformとHelmプロバイダバージョンが古くてarm64-darwinで実行できなかったので、アップデートの作業を行いました。 無事アップデートができたので、GitHubリポジトリにタグがpushされたらビルドが走るようなトリガーをTerraformで書きました。 さらにaria-server-lite用のHelmマニフェストを追加し、一旦デプロイ完了です。

ただ、この状態ではaria-allocator(-proxy)からからaria-server-liteをAllocateできません。そのため、aria-allocater(-proxy)のgRPCリクエストにUseLiteというフィールドを追加し、trueの場合はaria-server-liteをAllocateするような実装にしました。

これでいよいよ動くぞ!となったのですが、aria-cui-clientで接続の際に指定するアドレスがIPアドレスじゃないと動かないようになっていたため、こちらを名前解決できるように修正しました。

以上で無事今回のタスクは完遂となり、aria-cui-clientをAgones上で動かすことができるようになりました!

おまけタスク

前述の作業で動くようにはなったのですが、Goのプログラムを使ってaria-allocator(-proxy)を叩いて接続先情報を取ってくる&Allocateする→aria-cui-clientに接続先情報をわたして接続すると、2段階の手順を踏まないと接続できません。 そのため、aria-cui-clientからaria-allocator(-proxy)を叩けるようにして、一発で接続できるようにaria-cui-clientを改造しました。

aira-allocator-proxyはgRPCエンドポイントになっているため、tonicというgRPCライブラリを使用しました。 ただ、aria-allocator-proxyのエンドポイントにはGCPのサービスアカウントでの認証がかかっているため、https://www.googleapis.com/oauth2/v4/tokenを叩いてJWTを取得する処理を書き、それをgRPCリクエストのAuthorizationヘッダーに含める形で実装しています。 (JWT生成のリクエストを送る際のassersionのJWTにtarget_audienceというClaimを含める必要があり、そこに気づかなくてだいぶハマりました)

全体の感想

ちゃんとしたRustのプロダクションコードを読んだことがなかったのでとても勉強になりました。 また、比較的低レイヤーな部分もさわれて楽しかったです。

かなり色々な技術をさわれたのも楽しさポイントが高くて、Rust, Go, gRPC, WebTransport, perf, Agones, GKE, Terraform, CloudBuild, CloudRun etc… 色々な技術を触りました。 半分くらいは(ほとんど)触ったことがない技術でした。

新しい技術、自分の知らない技術を触ることが好きなので、自分のやりたいことにとてもマッチしているインターンでした。 メンターさんの技術力もめちゃめちゃ高くて、色々なお話が聞けて楽しかったです。 過去色々なインターンに行きましたが、過去一楽しかった気がします。

ただ、自分の技術力のなさを痛感する場面がかなり多かったので、これからも精進しようと思いました。 全体の仕組みを理解するのにもかなり時間がかかった気がします。

さいごに

メンターさんやチームの方には大変お世話になりました! また行く機会があればよろしくお願いします!!