人間とウェブの未来

「ウェブの歴史は人類の歴史の繰り返し」という観点から色々勉強しています。

マルチプロセッサのタスクスケジューリングに基づいたWebシステムにおけるコンテナのハードウェアスケジューリングのシミュレーション構想

データフローグラフ(タスクの依存関係をグラフ化したもの。タスクは処理の特性等の違いもある)をいかに効率良くマルチコアCPUにタスクスケジューリングするかという研究がある。マルチプロセッサシステムのタスクの割り当てとスケジューリングはTASとも呼ばれる。

効率的なTASを実現するための研究開発において、例えば任意のデータフローグラフがあった場合に、自分たちが考えたTASアルゴリズムに対してデータフローグラフを流し込んだ結果、CPUコアに適切にタスクスケジューリングできて従来のアルゴリズムよりも速く処理ができた、電力の面で効率よく処理ができた、といったシミュレーションと定量評価を手元で行うことが多い。

また、CPUコアの特性の違いも含めて適切にスケジューリングするヘテロジーニアスコアに最適なスケジューリングアルゴリズムの研究もある。

この考え方をWebシステムに当てはめると、例えばコンテナの再配置がリクエスト単位で動的に行われる場合、コンテナの収容ホストは、TASにおけるCPUコアと言える。また、ホストの収容率によってホストの処理性能に違いが出た場合、それはヘテロジーニアスコアと同様、動的に変化するとはいえ、ホストの処理性能が違う特性をもつコア、あるいはプロセッサである、とみなすことができる。

このように考えると、コンテナに対するHTTPリクエストとコンテナの再配置が、TASのタスクスケジューリングにおけるタスクとみなすこともできる。つまり、コンテナに基づいたWebシステムのハードウェアスケジューリングの問題、つまり、どの特性を持つホストにどのようにタスクであるリクエストを振り分け、コンテナに仕事をさせるか、という問題は、CPUコアのタスクスケジューリングの問題とほぼ同じように解釈可能になる。

では、タスクの性質と依存関係を示すデータフローグラフとは、Webシステムに置き換えた場合どういうものになりうるか?ここはまだ言語化するほどには答えは出ていないが、定義できそうな気がしている。

もしこれが定義できれば、これまで歴史的にも取り組まれていたマルチプロセッサのタスクスケジューリング問題と同様に、その資産を利用して、Webシステムのハードウェアスケジューリングを手元で定量的にシミュレーション可能となり、コンテナによる複雑なWebシステムにおける「いれてみないとわからない」というステージから、シミュレーションによってハードウェアスケジューリングアルゴリズムの定量評価か可能な時代となり、そのような状況から脱却できる可能性もある。

さらに、手元でシミュレーションできるということは研究開発効率も上がり、複雑なWebシステムに対して、様々なスケジューリングアルゴリズムを容易に確かめることもできる。

FastContainerのようにリクエストとコンテナの状態遷移が紐付くシステムのハードウェアスケジューリングを考える中で、まずこの複雑なWebシステムのハードウェアスケジューリングのシミュレーションを、TASの研究を参考に確立したいと思った。そうすれば、ハードウェアスケジューリングという難解ではあるが収容設計に準ずる重要な研究に対して、我々の目的にあったハードウェアスケジューリングを研究開発することが容易になり、また一歩システムにおけるなめらかさに近づくことができそうだ。

DevOpsの文脈でのDevelopment ResearchすなわちDevResについて

DevOpsについては多くが語られてきました。一方で、開発者と研究者の関係をDevOpsの文脈、いわゆる、Development ResearchすなわちDevResとしたときの関係性についてはあまり語られていません。これからの企業、ひいては、社会における開発者と研究者のあり方についてはDevOpsという名の元に解決しようとされてきたことの多くがまた繰り返されるように思えます。むしろ、DevOpsとして取り組んできた歴史よりも、技術者と研究者との関係性やその分断は、古くから続く課題といえるかもしれません。

続きを読む

ngx_mruby v2のHTTPクライアントをv1よりも最大90倍高速にした

写真のような感じでRubyKaigi2018で登壇し、RubyKaigiを経て、ようやくngx_mrubyのv2をリリースしました。基本的にv1と互換性がありますので、今後はv2を開発していくことになります。

github.com

ngx_mruby v2の目玉機能としては、Rubyスクリプトからノンブロッキングのsleepとhttp[s]クライアントを使えるようになったことです。実装的には、nginxのsub requestという機能をうまく使って、ノンブロッキングのhttp[s]クライアントを汎用的なsub_requestメソッドとして実現しています。

では、本エントリではそのノンブロッキングhttpクライアントがどの程度高速処理可能になったかを実験してみましょう。また最後には、RubyKaigi2018の感想も述べます。

  • 実験
    • proxyサーバのblockingとnon-blockingのhttpクライアントの設定
    • apiサーバの設定
  • 実験結果
    • レスポンスタイムを変化させたベンチマーク
    • 同時接続数を変化させたベンチマーク
  • まとめとRubyKaigi2018の感想
続きを読む

第二回 #wsa研 でHTTPリクエスト単位でコンテナを再配置する仮想化基盤の高速なスケジューリング手法について発表しました

第二回Web System Architecture研究会で、タイトルの内容について発表してきましたので、そのスライドと予稿を以下に公開します。

speakerdeck.com

英文タイトルは以下の通り。

Fast Scheduler for a Cloud Platform to Relocate Containers at Each HTTP Request

クラウドサービスの普及に伴い,個人のWebサイトでもクラウドサービスに類する機能を利用して,突発的なアクセス集中に耐性があり,かつ,利用したリソース使用量に応じて課金するサービスの提供が求められている. 我々はその要求に応じるために,Webサイトをコンテナ上に構築し,コンテナの起動や停止,複製やリソース割り当てといった状態の変更を素早く実行できるコンテナ管理アーキテクチャFastContainerを提案した. 一方で,単一のコンテナが特定のサーバに収容されている状態で,サーバが過負荷に陥ったり停止したりするような状況においては,障害時にコンテナの収容サーバ情報の変更を手動で構成管理データベースに反映させる必要があった. 本研究では,HTTPリクエスト処理時において,収容サーバ,および,その経路までの状態に応じて,自動的にコンテナを収容するサーバを決定し,サービスを継続させる,HTTPリクエスト単位でのコンテナスケジューリング手法を提案する. 提案手法では,FastContainerの状態変化の高速性に基づいて,コンテナが頻繁に収容サーバを変更されてもサービスに影響がないことを利用する. それによって,プロキシサーバから収容サーバに1個のICMPパケットで応答速度を計測し,少ないパケット数と応答速度に基づいた短いタイムアウトで収容サーバの反応時間を計測できる. そのことで,単一のコンテナであっても,HTTPリクエスト単位でのコンテナスケジューリングを実現し,可用性を担保する.

  • 1. はじめに
  • 2. Webサービス基盤の負荷分散と可用性
    • Webホスティングサービス
    • クラウドサービス
    • FastContainerアーキテクチャ
  • 3. 提案手法
  • 4. 実験
    • 予備実験
      • ICMPタイムアウトに関する予備実験
      • Apacheコンテナの起動時間に関する予備実験
    • 再配置時のレスポンスタイムの本実験
  • 5. まとめ
    • 接続待ちソケット生成前のプロセスイメージを利用したWebサーバの汎用的な起動時間短縮手法
    • 参考文献
続きを読む

OSレイヤでWebサーバが起動時に実行するシステムコールを監視し起動完了直前のプロセスをイメージ化する

今回は、Webサーバの実装に依存することなく、OSレイヤでWebサーバソフトウェアが起動時に実行するであろうシステムコールを監視して、そのタイミングでプロセスをイメージ化する方法(PoC)について紹介します。

続きを読む

もうできないと思えた時こそ大きな差をつけるチャンス

ある日、今年は研究開発活動を国際化していくぞ、と意気込んで出した国際会議のreject通知が届いた。そして、その内容も4人の査読者からフルボッコであり、特に英語がなっていないということをかなり強い言葉で指摘されていた。そんな通知をもらった僕は、かつてないほどの悔しさと後悔を感じたのであった。過去に何度か国際会議通していたこともあり、これぐらいでいいだろうとタカをくくって舐めていた、手を抜いていた面もあったからだ。

その1週間後の4/10に、国際会議のワークショップ締め切りがあり、指摘を直してそれに出してみてはどうかとreject通知に書かれていたのだが、その4/10は自分の別の論文1本と共著の2本の合計3本の論文締め切りと同じ日であり、これは流石に無理だと諦めたのであった。きつい。

精神的にも落ち込んでいたし、今年は国際化やっていくぞ!と思っていた矢先の出来事で、なかなか立ち直れなかった。残る3本の論文執筆は達成しなければならないという思いも強かった。でも、改めて自分を見つめ直した時、ただそれだけの気持ちではなかったのだ。

「また英語で出してフルボッコにされるのは嫌だ」「そうならないように納得のいく修正をするのは難しいだろう」「間に合うかもしれないけどもうなんか出したくないな…」「また落ちたら恥ずかしい…」「出せないということにしたい…」「逃げたい」そんなシンプルな感情に溢れかえっていた。

そんなとき、ふと博士課程時代の先生の言葉を思い出しつつ、自分が本当に得意としていることはなんであったのかを考えていた。

「ここまでせっかく書いたのだから直せるだけ直してとりあえず出してみましょう」

「そのちょっとした努力をこの状況だからこそやってみるのですよ」

「普通の人はここで諦めるでしょう。だからこそ我々はここでやってみないと」

「それがいずれ大きな差となる」

「もうできないと思えた時こそ大きな差をつけるチャンス」

「その時にやったことは全てがもれなく成長となる」

それぞれの言葉は細かいところでは違っているとはいえ、そのような内容の言葉を沢山やりとりしていたことが思い出された。

僕自身、社内の立場や外から見られる立ち位置も少しずつ上がってきていて、いつのまにかその立場が大きな鎧となり、身動きが取れず、がむしゃらに動くことを諦めはじめていた。でも、自分が多くの技術を学び、ただひたすら前を見て研究していたあの頃はそんな気持ちではなかった。少しでもチャンスがあれば手を伸ばし、指が引っかかることを信じて、とにかく掴む努力を誰よりも、特に普通なら諦めかける状況であればあるほど、手を伸ばし続けていたはずだった。何度でも失敗したっていい。その時の全力を尽くすだけだ。僕のような別段頭が良いわけではない人間が一歩先へ進むにはそれしかなかったはずだ。そんなことを思い出しはじめた。

そして、僕は4/10に国際会議の論文をできる限り修正し提出した。同時に、ギリギリまで共著論文を2本レビューし、自分の論文も含めて合計4本の新しい論文も提出できた。ちゃんと提出できたのだ。なんてことはない、ほんの少しやろうとするだけ、重い鎧を脱ぐだけで、できないと思えてもやってみると案外できるものだ。もうできないと思えた時にこそ、自分を矮小化することなく、ほんの少しだけ勇気を出して、格好をつけるのをやめて、踏ん張ってみる。すると、もう一歩だけ進むことができるのだ。その一歩の積み重ねが大きな力となっていく。

僕が唯一人と差をつけられることはこれだったはずだ。今日はもう眠い。でもそこでもう少しだけ踏ん張ってこのエントリを書く。本質的にはそれと変わらない。たったそれだけのことをを再び忘れないように、ここに行動し、記しておく。

プログラミングにおける不安と学びのプロセス

僕の場合、実現したいことをコードで書けない時には、ひたすら似たコードを読んで理解して写して…を繰り返す。そのうちに手元に大量の自分のサンプルが溜まっていく。その繰り返しがパターンの細分化を促し、書けるコードの幅を広げていく。書けるコードを気持ちよく書き続けてるだけでは新しいコードは書けないからだ....と、向き合えるようになるには時間がかかった。

書き慣れたコードの延長で書いていると、自分でコードを書けている実感があって、リファレンスなど何も見ずに自分の力でプログラミングできている感があるのだが、ある時これはただ「慣れ」の感覚を高めているように思えた。素早く書けること自体は、それはそれで一種のスキルで素晴らしいのだけど、実現したいことをコードで書けるようになる、という観点で振り返ったときに、どうしても成長を感じなかったのだ。それ以来、まずいと思い、実現したいことを思い描き、それを実現するために自分が書けないコードを探しては読み、写しては学ぶようにした。しかしそこには常に不安がつきまとう。

書けないコードを読んで真似をするという行為を繰り返している状態は、自分でコードを書けている実感がとても弱くなる。だからこそ、その漠然とした不安を払拭するためにそのプロセスを続けるのだけど、ある時振り返ると、出来ないことをできるようになっていた、という結果とその成長を実感できる。とはいえ不安はまだまだあるし、満たされることもないので、継続的に取り組み続ける。実はこれは満足感と払拭されない不安がうまく両立されている状態なのだ。

自信や実感の無さにいかに向き合ってそれをエネルギーに変えるか、その際に周りとの相対比較による無駄な雑念をどれだけ取り除けるか、というのはとても大事で、そのような状態でプログラミングに向き合えたら、自分のために、実現したいことのためにただ書けないコードを書けるようにと学び続けられる。遅くたって構わない。ただひたすらに継続してやっていくだけだ。

業務でもプログラミングでもそうだけど、専門性という意味合いのない、ある特定の狭い領域にのめり込むと割と簡単に全能感を得られてしまう。その全能感は気持ちよくて癖になってなかなかやめられないのだけど、その全能感故にその狭い領域や今出来ることから抜けられない。いかに簡単にその全能感を捨てられるかがポイントに思う。

周りよりも速く全能感を得られたのなら、次は自分のできないことに取り組みながら、俺が俺がとやってきたことを適切に周りに頼り任せていく。そうすると、自分ができないことができるようになる間に、周りのできることが自分も少しずつできなくなっていくし、それどころか、忘れてすらいく。でも実は、そのように生じる役割分担とその連鎖は、実現したいことの限界を突破していくという意味では、集合知として専門性を高める作業にほかならないのだ。

このテーマで何が言いたかったというと、そうやってコードを読んで理解して真似してる時はコードを書けてない実感が強く不安だから、それを避けて出来る方や慣れる方を優先しがちだけど、実はその不安は正しい学びのプロセスであって成長の角度が比較的大きくなるので、その不安と向き合ってしまうと良いと思うのであった。

そしてこれは、プログラミングに限らずあらゆることに適用できそうな学びのプロセスであるかもな、とも思う。