Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

大規模分散システムの現在 -- Twitter

26,133 views

Published on

マルレク2015 第二回「大規模分散システムの現在 -- Twitter」講演資料

Published in: Internet
  • Be the first to comment

大規模分散システムの現在 -- Twitter

  1. 1. 大規模分散システムの現在 @maruyama097 丸山不二夫
  2. 2. Most of our systems are big “Future transformers” - Marius Eriksen
  3. 3. predictable performance is difficult to achieve. In a predictable system, worst-case performance is crucial; average performance not so much. ... predictable performance is difficult to achieve. In a predictable system, worst-case performance is crucial; average performance not so much. - Peter Schuller
  4. 4. predictable performance is difficult to achieve. In a predictable system, worst-case performance is crucial; average performance not so much. It’s with the intent of modeling a world where the Twitters, Googles, and Facebooks are no longer superpowers… just power - Aurora
  5. 5. はじめに  Twitterの大規模分散システムが、世界有数のものであ ることは論を待たない。2億人以上のユーザーが、このプ ラットフォームを利用し、彼らのシステムは、毎秒100万以 上のtweetに耐えられることを目指している。  Twitterのアプローチの大きな特徴の一つは、こうした大 規模分散システムの記述には、関数型のプログラム言語 が、適合的だという積極的な主張にある。  小論では、まず、彼らのシステム記述の中核ライブラリー である Finagle を取り上げる。ここでは、非同期性を表 現する Futureが本質的な役割を果たす。Twitterの大 規模分散システムは、「Futureの巨大な変換装置」とされ る。こうした認識は、Twitterのシステム理解の要になる。
  6. 6. はじめに  Twitterのアプローチのもう一つの特徴は、彼らが彼らの 大規模分散システムの心臓部分の実装を、オープンソー スで公開していることである。GoogleもAmazonも Microsoftも、そういうことはしていない。  Mesosは、「分散アプリケーション、すなわち、フレームワ ークをまたいで、効果的なリソースの分離と共有を提供す るクラスター・マネージャー」である。それは、データセンタ ーあるいはクラウドのOSと呼ぶべきものである。  Mesosだけでなく、その周辺のAurora, Mesosphereと いった「Mesos文化圏」ともいうべきものは、大規模分散 の世界で、もっともダイナミックでアクティブな領域に成長 しようとしている。
  7. 7. Agenda  Twitterのシステムの変化  Finagle 関数型言語による分散処理の記述  Manhattan 多機能分散データベース  Mesos データセンターOSとその影響の拡大
  8. 8. Overview Twitterのシステムの変化 ここでは、Twitterのシステムの変化を概観し よう。
  9. 9. 2009年  MySQLを使った純粋なRuby-on-Railsアプリ。  たくさんのmemcacheを使い、投稿されたタイムラインを memcacheに積む。  ソーシャル・グラフはサービスで扱う。  遅延は、queueで吸収。
  10. 10.  monolithicなアプリ ケーション  サービス・インフラの 欠如  新しいサービス・新し い特徴追加が困難  スピード、効率性、信 頼性で勝る大規模イン フラへ  関心の分離  チームの独立性 “Real-time systems at Twitter” http://goo.gl/EaYyZA 2009 2010
  11. 11. 2010年 - 2011年 - 2012年  2010年:タイムラインを、独自のサービス・システムに移 行開始する。 ruby on railsから離れるためのプロジェク トgodwit開始。サービス・インフラの共有化に取り組む。  2011年:インフラの整備進む。無数のアプリのポーティ ング。TFE(HTTP Proxy)オンライン稼働。  2012年:TFE が通年で全てのトラフィックを扱うようにな る。ますます多くのAPIのトラフィックが新しいシステムで 動くようになる。
  12. 12. 2011 2012 “Real-time systems at Twitter” http://goo.gl/EaYyZA
  13. 13. 2012年末のアーキテクチャー 多くのオープンソース・コンポーネントの導入  Memcache, redis, MySQL, etc.  必然的にヘテロなシステムに サービス中心に組織化  異なった責任を持つ  相互に分離されている  分散化された処理とデータ  システム間のRPC 前面にHTTPのマルチプレキシング  モデュラー性とロードバランシングにとって、本質的に 重要
  14. 14. 2013年 Twitter stack  Finagle  Ostrich  Zipkin  Mesos  Iago  ZooKeeper  Scalding  jvmgcprof http://goo.gl/Ax9LVw
  15. 15. 2013年 Finagle  Twitterのサービスの中心部分には、Finagle ライブラリ ーがある。RPCシステムの基本的な土台の部分を抽象化 することによって、Finagleは、サービス開発者が扱わな ければいけなかった複雑さを大幅に軽減した。  それは、分散システムの低レベルの詳細にこだわらねば いけなかったかわりに、アプリケーションに固有のビジネ ス・ロジックを書くことに集中することを可能にした。  最終的には、Webサイト自身も、運用を効率化でも、 HTMLを書き出すのに必要なデータの取り出しにも、この サービスを使っている。Twitterでは内部のサービスは Thriftを使っているのだが、Finagleでは、Protocol bufferやHTTPのような他のプロトコルもサポートしている 。 http://goo.gl/Ax9LVw
  16. 16. 2013年 Mesos  Mesos は、自分を次のように規定している。 「分散アプリケーション、すなわち、フレームワークをまた いで、効果的なリソースの分離と共有を提供するクラスタ ー・マネージャー」  Mesosの中心プロジェクトは、オープンソースのApache インキュベーター・プロジェクトである。Mesosの上に、例 えば、StormやHadoopといった特別の技術を扱うスケ ジューラーを走らせることができる。そのアイデアは、同じ ハードウェアは、複数の目的のために利用でき、リソース の浪費を低減できるというものである。 http://goo.gl/Ax9LVw
  17. 17. 2014年 Manhattan  Twitterが、パブリックな自己表現と会話のグローバルな プラットフォームに成長するにつれ、我々のストレージに 対する要請も増大した。この数年間にわたって、我々は、 リアルタイムの環境の中で、非常に低い遅延で、毎秒数 百万のクエリーに応えられるストレージ・システムが必要 であることに気づいていた。可用性とシステムのスピード が、最も重要な要素になっていた。単に、早いことが必要 なだけでなく、世界中のいくつかの地域をまたいで、スケ ーラブルである必要があった。 https://goo.gl/GN960E
  18. 18. 2014年 Manhattan  何年にもわたって、我々は、多くのオープンソースのデー タベースを利用してきたし、それらに重要な貢献もしてき た。しかし、Twitterのリアルタイムの本性は、既存のオー プンソース製品が提供しているものより、低い遅延を要求 していることに、我々は気づいていた。我々の様々な製品 のパフォーマンスの期待にそうために、火を噴きそうな製 品システムと、我々は、非常に長い時間を過ごしてきた。 そして、あまりに多くの手作業やプロセスを含んだユース ケースに代わる、新しいストレージの能力を立ち上げよう としている。 https://goo.gl/GN960E
  19. 19. Finagle
  20. 20. Finagle 関数型言語による分散処理の記述  シーケンシャルな処理を考える  改めて、シーケンシャルな処理を考え  Futureの利用  パラレルな処理を考える  サービスのモジュールへの分割  Finagle: RPCシステム
  21. 21. シーケンシャルな処理を考える
  22. 22. 計算処理を関数と考える 処理 関数 f 入力 出力 関数の引数 x 関数の返り値 y y = f(x) 引数の型がAで、その返り値の型がBなら、この処理は 次のような型を持つ関数 f で定義される。 def f(x:A):B
  23. 23. シーケンシャルな処理 処理1 入力 出力 二つの処理 fとgが、シーケンシャルに連続して行われる時、 その処理 h は、関数 f と関数 gの合成になる。これを、 h = g ・ f と表す。 処理2 入力 出力 関数 f 引数 x 返り値 f(x) 関数 g 引数 返り値 y y = h(x) = g(f(x)) 関数 h
  24. 24. シーケンシャルな処理 処理1 入力 出力 シーケンシャルな処理が、f1, f2, ... , fn と連続して行われる時、 その処理 h は、h = fn ・ ... ・ f2 ・ f1 と表わすことができる。。 処理2 入力 出力 y = h(x) = fn(・・・ (f2(f1(x))・・・) 関数 h 処理n 出力 ・・・ f1 f2 fn・・・ 引数 x 返り値 y
  25. 25. シーケンシャルな処理の特徴 h = fn ・ ... ・ f2 ・ f1  関数の合成で、シーケンシャルな処理が記述できたのだ が、それだけではシーケンシャルな処理の特徴を捉えたこ とにはならない。そこには、次のような問題がある。  f1の処理が終わるまで、f2の処理は待たされる。 f2の処理が終わるまで、f3の処理は待たされる。 ・・・ fnの処理は、それ以前のすべての処理が終わるまで待た される。  h = fn ・ ... ・ fi ・ ... ・ f2 ・ f1 待たされるだけではない。途中の処理 fi の一つでも失敗 すれば、その時点で、全体の処理 h は、失敗する。  待つことや、エラーの処理に、うまい方法はないのだろう か?
  26. 26. 出力に時間がかかる場合 f f 入力 出力 入力 出力がない! 待機! 出力がすぐ返ればいいのだが、処理に時間がかかる 場合には、出力がない状態が生まれる。
  27. 27. 非同期処理 f g 入力 出力がない状態 入力 出力 こうした場合には、出力がない状態で待機せずに、別の 処理に制御を写すのが好ましい。f は、呼び出されると、 出力の有無にかかわらず、すぐに制御を返すのがいい。 非同期処理である。ただ、それには、仕掛けが必要である。 別の処理 g 待機せずに、別の処理に 制御を移す。
  28. 28. Future  Futureは、関数が返すものを入れる「箱」である。  この「箱」は、空の場合もあれば、中身を一つ持っている 場合もある。Futureは、ゼロ個か1個の中身を持つ。  中身は、関数が返した値が入っているか、あるいは、関数 の実行に失敗したという情報が入っているかの、いずれ かである。 T 値 エラー 空のFuture 中身を持つFuture 結果待ち状態 実行成功 実行失敗
  29. 29. Futuresが必要とされる場合 出力を得るのに、待機する必要がある場合  長い時間を要する計算  ネットワークの呼び出し  ディスクからの読み出し 計算は失敗することがある。  接続の失敗  時間切れ  ゼロでの除算
  30. 30. Futureと関数の非同期化 f g 入力 入力 別の処理 g Futureが返ったら、別の 処理にただちに、制御を移す。 Futureが返る Futureが返る h 入力 別の処理 h Futureが返る Futureが返ったら、別の 処理にただちに、制御を移す。 もし、関数が Futureを返 すなら、関数 は、非同期に できる。 非同期型 def f(x:A):Future[B] 同期型 def f(x:A):B
  31. 31. Futuresの値の取得 get Futureは、ある種のコンテナーである。 trait Future[A] それは、empty, full, failedの三つの状態を取る。我々 は、それを待つことができる。その値は getで取得できる。 val f: Future[A] val result = f() f.get() match { case Return(res) => ... case Throw(exc) => ... } ただ、いつ get するのか? せっかく非同期にしたのに、 get の利用は、あまり意味がない
  32. 32. scala> import com.twitter.util.{Future,Promise} import com.twitter.util.{Future, Promise} // すでに解決済みのFutureを作る。 scala> val f6 = Future.value(6) f6: com.twitter.util.Future[Int] = com.twitter.util.ConstFuture@c63a8af scala> f6.get() res0: Int = 6 // 失敗となるFutureを作る scala> val fex = Future.exception(new Exception) fex: com.twitter.util.Future[Nothing] = com.twitter.util.ConstFuture@38dd ab20 scala> fex.get() java.lang.Exception ... stack trace ... Futureのgetを実験する
  33. 33. // 解決されていないPromiseを作る scala> val pr7 = new Promise[Int] pr7: com.twitter.util.Promise[Int] = Promise@1994943491(...) scala> pr7.get() ...console hangs, waiting for future to resolve... Ctrl-C Execution interrupted by signal. scala> pr7.setValue(7) scala> pr7.get() res1: Int = 7 scala> Futureのgetを実験する
  34. 34. Futureのコールバック 「私に電話するな。私がかける。」 とMr. Futureはいう。 ( Hollywood principle ) val f: Future[String] f onSuccess { s => log.info(s) } onFailure { exc => log.error(exc) }
  35. 35. Promises Futures はread-onlyだが (初期化の時に、一回だけ、書 かれる)、Promiseは、何回でも書き込み可能である val p: Promise[Int] val f: Future[Int] = p Success: p.setValue(1) Failure: p.setException(new MyExc)
  36. 36. 改めて、シーケンシャルな処理を考える Futureの利用 Futureの準備はできた。ここでは、Futureを返すこと で非同期化された関数の、シーケンシャルな合成を考 えてみよう。
  37. 37. サンプルのシナリオ getThumbnail  ここでは、与えられたURLから Webページを取得し、つ づいて、そのWebページの最初の画像リンクから画像を 取得する処理 getThumbnail を考えてみよう。  基本的なデータ型として、Webpageを次のように定義し よう。要は、Webページは、画像リンク(imagelinks)とリ ンク(links)からなり、それぞれは、文字列(URL)の Sequence(リストと思っていい)だということ。 trait Webpage { def imageLinks: Seq[String] def links: Seq[String] ... }
  38. 38. 同期型のシナリオ getThumbnailSync  Futureを使わない同期型では、こんな感じになる。 def fetchSync(url: String): Webpage = { ... } def firstImageURLSync(page:Webpage):String = { page.imageLinks(0) } def getThumbnailSync(url:String):Webpage = { fetchSync( firstImageURLSync( fetchSync( url ))) } fetchSync firstImageURLSync fetchSync url page image-url pageI getThumbnailSync
  39. 39. 非同期型のシナリオ getThumbnail  Futureを使った同期型では、こんな感じになる。中間の 部分の処理は、大して時間かからなそうなので、内部に組 み込んだ。 def fetch(url: String):Future[Webpage] def getThumbnailSync(url:String):Future[Webpage] page. imageLi nks(0) fetch fetch url getThumbnail page onSuccess onSuccess onFailure onFailure
  40. 40. 非同期型のシナリオ getThumbnail のコード def getThumbnail(url: String): Future[Webpage] = { val promise = new Promise[Webpage] fetch(url) onSuccess { page => fetch(page.imageLinks(0)) onSuccess { p => promise.setValue(p) } onFailure { exc => promise.setException(exc) } } onFailure { exc => promise.setException(exc) } promise } これは、よくあるCallback Hellのパターンだ。
  41. 41. getThumbnailをflatMapで実装 def getThumbnail(url: String): Future[Webpage] = fetch(url) flatMap { page => fetch(page.imageLinks(0)) }
  42. 42. 回り道 Collectionのmap こうしたコンビネーターを、おそらく、毎日使っているかもしれ ない。例えば、collectionに働く “map” は、コンビネーター である。 val l = Seq(1,2,3,4) val mult2 = { x => x*2 } val l2 = l map mult2 // 次の様にも書ける: l map { x => x*2 } l2 == Seq(2,4,6,8)
  43. 43. 回り道 CollectionのflatMap flatMapコンビネーターは、非常に汎用的なツールである。 trait Seq[A] { def flatMap[B](f: A => Seq[B]): Seq[B] ... その名前が示唆する様に、それは、mapとflattenの組み合 わせである。 def flatMap[B](f: A => Seq[B]) = map(f).flatten
  44. 44. flatMapで、何ができるか? 拡張: Seq(1,2,3,4) flatMap { x => Seq(x, -x)} == Seq(Seq(1,-1)),Seq(2,-2),Seq(3,-3),Seq(4,-4).flatten == Seq(1,-1,2,-2,3,-3,4,-4) 条件: Seq(1,2,3,4) flatMap { x => if (x%2 == 0) Seq(x) else Seq() } == Seq(Seq(2),Seq(4)).flatten == Seq(2,4) Seq[Seq[int]]を、Seq[int]に変える
  45. 45. FutureのflatMap trait Future[A] { def flatMap[B](f: A => Future[B]): Future[B] ... Future[Future[T]]を、Future[T]に変える
  46. 46. flatMapが助けになる? 我々は、次のような関数を定義しようとしている。 def getThumbnail(url: String): Future[Webpage] 最初にページを取り込んで、最初のイメージのリンクを見つけ、 そのリンクからイメージを取り込む。 この操作のいずれかが失敗すれば、このgetThumbnailも失 敗する。 trait Future[A] { ... def flatMap[B](f: A => Future[B]): Future[B]
  47. 47. page. imageLi nks(0) fetch fetch url getThumbnail page onSuccess onSuccess onFailure onFailure url fetch page. imageLin ks(0) fetch Future 非同期関数
  48. 48. flatMapurl fetch page. imageLin ks(0) fetch flatMap ... エラー flatMappage page. imageLin ks(0) fetch エラー page
  49. 49. flatMappage page. imageLin ks(0) fetch page map . flattenpage page. imageLin ks(0) fetch page page. imageLin ks(0) fetch . flatten
  50. 50. page. imageLin ks(0) fetch . flatten . flatten . flatten エラー エラー Image page
  51. 51. . flatten Image page Image page Future flatmap 非同期関数 で、新しいFutureが返る flatMapで、Future[Future[T]] が、Future[T]に変わる
  52. 52. getThumbnailをflatMapで実装 def getThumbnail(url: String): Future[Webpage] = fetch(url) flatMap { page => fetch(page.imageLinks(0)) }
  53. 53. 失敗はどうなるのか? これらは、合成も上手く行く。また、それは、回復可能でなければな らない。flatMap には、その双対が必要である。flatMapは、成功 した値の上に働き、rescueは、例外を処理する。 trait Future[A] { ... def rescue[B](f: Exception => Future[B]): Future[B] エラーの回復は、次のようになる val f = fetch(url) rescue { case ConnectionFailed => .... }
  54. 54. flatMapの利用  flatMap シーケンスは二つのFutureを持つ。それは、 Futureと非同期関数を引数にとって別のFutureを返す。  このメソッドのシグニチャーは、次のようなストーリーを語 っている。  与えられた成功したFutureの値に対して、関数fは、次の Futureを提供する。flatMapは、入力のFutureが成功 裏に終了した時に、自動的に f を呼び出す。この操作の 結果は、別のFutureで、二つのFutureの双方が終了し た場合にのみ終了する。もし、どちらかのFutureが失敗 すれば、このFutureは失敗する。
  55. 55. flatMapの利用  この暗黙のエラーの織り込みは、エラーが意味的に重要 な場所で起きた場合にのみそれらを処理することを可能 にする。flatMapは、こうしたセマンティックを持つ combinatorの標準的な名前である。  もし、Futureがあって、非同期APIをその値に適用しよう と思ったら、flatMapを使うこと。
  56. 56. flatMapの利用 もう一つの例  例えば、Future[User]があったとしよう。そして、特定の ユーザーが失格になっていることを示す Future[Boolean]が必要だとしよう。あるユーザーが失 格になっているかどうかを決めるisBanned APIがある。 ただ、これは非同期APIなので、flatMapを利用すること ができる。
  57. 57. scala> import com.twitter.util.{Future,Promise} import com.twitter.util.{Future, Promise} scala> class User(n: String) { val name = n } defined class User scala> def isBanned(u: User) = { Future.value(false) } isBanned: (u: User)com.twitter.util.Future[Boolean] scala> val pru = new Promise[User] pru: com.twitter.util.Promise[User] = Promise@897588993(...) // apply isBanned to future scala> val futBan = pru flatMap isBanned futBan: com.twitter.util.Future[Boolean] = Promise@1733189548(...) scala> futBan.get() ...REPL hangs, futBan not resolved yet... Ctrl-C Execution interrupted by signal. scala> pru.setValue(new User("prudence")) scala> futBan.get() res45: Boolean = false scala>
  58. 58. シーケンシャルな処理の非同期化 h = fn ・ ... ・ f2 ・ f1  シーケンシャルな処理は、時間やエラーの問題を無視す れば、h = fn ・ ... ・ f2 ・ f1 のように、「関数の合成」で モデル化できた。  Futureで非同期化された関数の合成は、flatMapを使う と次のように簡単に表現でき、かつ、より現実的なシーケ ンシャルな処理のモデルを与える。 f1 flatMap f2 flatMap ... flatMap fn
  59. 59. パラレルな処理を考える
  60. 60. パラレルな処理を考える  パラレルな処理が、計算上で意味を持つのは、独立に計 算されたそれらの結果が、別の一つの処理で利用される 場合だけである。 処理 出力 処理1 処理2 処理n 入力 パラレルな処理
  61. 61. パラレルな処理の合成を関数で考える  この複数の処理を一つに束ねる処理の、もっとも簡単な 関数での解釈の一つは、複数の引数を持つ関数を考える ことである。 f(x1, x2, ... , xn) f 返り値 p1 p2 pn 引数 パラレルな処理
  62. 62. 「複数の引数」の問題  パラレルに走っている、引数を与える方の関数がエラーを 起こして、引数が、一つでも揃わないことが確定すると、そ の時点で、複数の引数を受け取る関数は、失敗する。  複数の引数が、同時に与えられる保証はない。複数の引 数を受け取る関数は、引数が全部揃うまで「待機」する必 要がある。  例えば、コンテンツと広告を表示するWebサービスを書い ているとしよう。この時、あるサービスからコンテンツを取 り出し、他のサービスから広告を取り出すことになるだろう 。しかし、両方の返答を待てということをどうしたらコードに 伝えれることができるだろう。  ここでも、Futureが使える。
  63. 63. パラレルな処理の合成を 非同期関数とFutureで考える  複数の引数を持つ関数を考える代わりに、複数のFuture のListを、複数のListの一つのFutureに変換する combinatorを考えよう。 collect p1 p2 pn パラレルな処理の結果 としてのFutureのList p1 p2 pn List パラレルな処理の結果 のListのFuture List Future
  64. 64. パラレルな処理の合成を 非同期関数とFutureで考える  このcombinatorが成功するのは、左のListの要素のす べてのFutureが成功する場会のみである。逆に、この時 、すべての要素は揃っている。 collect p1 p2 pn パラレルな処理の結果 としてのFutureのList p1 p2 pn List パラレルな処理の結果 のListのFuture List Future
  65. 65.  Futureは、ある種の並列処理のcombinatorを提供して いる。一般的には、これらは、Futureのリストを、少し違っ たやり方で、リストのFutureに変換する。これは、本質的 には、複数のFutureを一つのFutureにパッケージする ので、都合がいい。 object Future { … def collect[A](fs: Seq[Future[A]]): Future[Seq[A]] def join(fs: Seq[Future[_]]): Future[Unit] def select(fs: Seq[Future[A]]) : Future[(Try[A], Seq[Future[A]])] } パラレルな処理の合成
  66. 66. 先の、ページから最初の画像ページを取り出すプログラムを、少 し修正して、あるページの全ての画像ページを取り出すプログラ ムを作ることができる。 def getThumbnails(url: String): Future[Seq[Webpage]] = fetch(url) flatMap { page => Future.collect( page.imageLinks map { u => fetch(u) } ) } ページから、すべての画像 ページを取り出すプログラム a1 a2 ・ ・ an a1 a2 ・ ・ an collect fan-out
  67. 67. 単純な Web Crawler def crawl(url: String): Future[Seq[Webpage]] = fetch(url) flatMap { page => Future.collect( page.links map { u => crawl(u) } ) map { pps => pps.flatten } } (* Apocryphal ほんとかな?)
  68. 68. サービスのモジュールへの分割
  69. 69. Services futureが、いかに並行プラグラミングに利用できるかを見てき た。ここでは、ネットワーク・プログラミングが、いかに、この図式 に当てはまるかを見ることにしよう。 RPCは、どうだろうか?  リクエストを送る  しばらく待つ  成功か、失敗か これは、関数である。 type Service[Req, Rep] = Req => Future[Rep]
  70. 70. 単純なサービス A server: val multiplier = { i => Future.value(i*2) } A client: multiplier(123) onSuccess { res => println(“result”, r) }
  71. 71. Server  同様に Finagle serverはServiceをネットワークに “exports”する。serverは、二つの部分を持つ。 1. Serviceを実装した関数:Reqを受け取り、Future[Rep] を返す。 2. 入ってくるReqをどう“listen”するかの設定。例えば、 HTTPのリクエストを、80番ポートで待つ等。 こうして、Serviceのロジックと、ネットワーク上どのようにデー タが流れるかの設定は、分離される。
  72. 72. Client Finaglのclientは、ネットワークからServiceを “imports” する。概念的には、Finagle clientは、二つの部分からなる。 1. Serviceを利用する関数: リクエスト Req を送り、帰って 来たFuture[Rep]を処理する。 2. リクエストをどう送るかの設定。例えば、次のような設定 api.twitter.comのポート80に、HTTPで送る。
  73. 73. Filters サービスに共通の振る舞いの多くは、サービスに固有の特徴 とは無関係である。つぎのようなものがある。  繰り返し  時間切れ  例外処理  統計情報 Filterは、サービスの上で合成される。概念的に言えば、我 々は、サービスが「何」なのかとは無関係に、サービスの「振 る舞い」 を変えたいのである。
  74. 74. Filter  Finagle filterは、次のようなものである。filterは、サー ビスの間に入って、その中を通るデータを変換する。filter は、サービスとうまく合成できる。 例えば、rate-limiterフ ィルターとtweet-servingサービスがあったとすれば、こ れらを一緒にして、 rate-limited tweet-servingサー ビスを作ることができる。
  75. 75. Filterは、serviceを変形する。 それらは、service generic な機能 を提供できる。例えば、rate-limitingをサポートすべき複数のサー ビスがあったとする。一つのrate-limitingフィルターを書けば、それ をすべてのサービスに適用できる。Filterは、また、サービスを異なっ たフェーズに分解するのにいい働きをする。 単純なproxyは、次のような形をしているだろう。ここで、 rewriteReq と rewriteRes は、プロトコルの変換を提供する。 class MyService(client: Service[..]) extends Service[HttpRequest, HttpResponse] { def apply(request: HttpRequest) = { client(rewriteReq(request)) map { res => rewriteRes(res) } } }
  76. 76. filterの例 与えられたrequestとserviceに対して、それを実行するが、 1秒後にタイムアウトする。 val timeout = { (req, service) => service(req).within(1.second) } requestを認証し、それが成功した時にのみ、サービスを実 行する。 val auth = { (req, service) => if (isAuth(req)) service(req) else Future.exception(AuthErr) }
  77. 77. Filterは、積み重ねられる。 val timeout: Filter[…] val auth: Filter[…] val service: Service[…] timeout andThen auth andThen service def andThen[A](g: (R) ⇒ A): (T1) ⇒ A Composes two instances of Function1 in a new Function1, with this function applied first. def compose[A](g: (A) ⇒ T1): (A) ⇒ R Composes two instances of Function1 in a new Function1, with this function applied last.
  78. 78. Finagle: RPCシステム
  79. 79. Finagle Finagle は、次のことを可能にする  クライアントがサービスを提供して、サーバーがそれを消費 する  コンフィグ可能な振る舞いを追加する: ロードバランシング、コネクション・プーリング、再実行、タイ ムアウト、割合の制限、モニタリング、統計情報の収集  プロトコル独立性:codecで、ワイア・プロトコルを実装  リソースの管理
  80. 80. Clients val client = ClientBuilder() .name("loadtest") .codec(Http) .hosts("google.com:80,..") .build() client は、 Service[HttpReq, HttpRep] である。 client(HttpRequest(GET, "/"))
  81. 81. Servers val service = { req => Future.value(HttpRes(Code.OK, "blah")) } ServerBuilder() .name("httpd") .codec(Http) .bindTo(":8080") .build(service)
  82. 82. それらをまとめると 新しい処理を追加したくなったとしよう。それは簡単である。 val backupReq: Filter[…] = { (req, service) => val reqs = Seq( service(req), timer.doLater(delay) { service(req)).flatten } ) Future.select(reqs) flatMap { case (Return(res), Seq(other)) => other.cancel() Future.value(res) case (Throw(_), Seq(other)) => other } }
  83. 83. [昔話] SOAとRPCを振り返る SOA「サービス指向アーキテクチャー」やRPCやモジ ュラーなコンポーネントの歴史は古い。ここでは、 2002年に筆者が行った講演の一部を紹介する。「サ ービス」概念の抽象化と実装の変化を振り返るのは、 興味深い。
  84. 84. 2002年6月マルレク 「WebコンポーネンとWebサービス」から https://goo.gl/wLGyYe
  85. 85. https://goo.gl/4f4Hos Manhattan, our real-time, multi-tenant distributed database for Twitter scale https://goo.gl/MROsMq
  86. 86. Manhattan  開発の背景と要請  大規模システムでの信頼性  Storage System  Storage Service  Storage as a Service
  87. 87. Data Platform Landscape Map  次の電車の路線図みたいのは、必見。拡大して、よく見て 欲しい。世の中のデータストアの地図だ!!  真ん中右の白いエリアがリレーショナル・データベース、 右下のグリーンのエリアが、Grid/Cacheのエリア。残り のグレーの部分が、NonSQLのエリア。「エリア」内の「各 駅」が、General Purposeとか、Key Valueとか、 Graphといった「路線」でつながっている。571もある。 https://goo.gl/rQ6XHc
  88. 88. Manhattan, our real-time, multi-tenant distributed database for Twitter scale April 2, 2014 By Peter Schuller, Core Storage Team https://blog.twitter.com/2014/manhattan- our-real-time-multi-tenant-distributed- database-for-twitter-scale 抄訳
  89. 89. Manhattan 開発の背景  Twitterが、パブリックな自己表現と会話のグローバルな プラットフォームに成長するにつれ、我々のストレージに 対する要請も増大した。この数年間にわたって、我々は、 リアルタイムの環境の中で、非常に低い遅延で、毎秒数 百万のクエリーに応えられるストレージ・システムが必要 であることに気づいていた。  可用性とシステムのスピードが、最も重要な要素になって いた。単に、早いことが必要なだけでなく、世界中のいくつ かの地域をまたいで、スケーラブルである必要があった。  Twitterのリアルタイムの本性は、既存のオープンソース 製品が提供しているものより、低い遅延を要求しているこ とに、我々は気づいていた。
  90. 90. データベースに対する要請  Reliability: Twitterのサービスは、予測可能なパフォ ーマンスを持った耐久性のあるデータストアを必要として いる。それは、失敗やスピード低下や急拡大や負荷集中 その他、想定できるあらゆる事態を通じて、信頼できるも のである。  Availability: 我々のユースケースの大部分は、整合 性以上に可用性を強く望んでいる。それゆえ、常に稼働し ている、 eventually consistent なデータベースは、必 須であった。
  91. 91.  Extensibility: 我々の構築するテクノロジーは、我々 の要請の変化に応じて、発展することが可能でなければ ならない。それゆえ、新しいストレージ・エンジンから強い 整合性にいたる、あらゆるものがその上に構築される、強 固でモジューラー型の基礎を持たなければならない。さら に追加すれば、スキーマのないkey-valueデータ・モデ ルが、大部分の顧客のニーズにフィットし、構造をあとで 追加する余地を持つことを可能にする。  Operability: クラスターが、数百から数千のノードに成 長するにつれ、もっとも単純なオペレーションは苦痛にな り、オペレーターの時間を奪う。マンパワーを効率的にス ケールさせるために、最初の日から運用を容易なものに する必要がある。すべての新しい特徴について、運用の 複雑さと診断の容易さについて、我々は考えた。
  92. 92.  Low latency: リアルタイムのサービスとして、Titter の製品は、整合性をもった低遅延を要求する。低遅延の パフォーマンスを保証するために、Twitter固有のトレー ドオフを行わなければならない。  Real-world scalability: スケールの変化は、分散 システムでは、普遍的なものである。Twitterは、ある点 でだけスケールできるデータベースではなく、コストの効率 性や運用の容易さを犠牲にすることなく、すべてのメトリッ ク -- クラスターのサイズ、一秒あたりのリクエスト、データ のサイズ、地理的な拡大、顧客数 --等において、新しい 高みに成長を続けられるデータベースを必要とする。  Developer productivity: 会社の開発者は、サー ビスを構築するために必要とされるものすべてを、セルフ・ サービス型のプラットフォームとして、ストレージの技術者 の干渉を必要としないで、蓄積できる必要がある。システ ムは、彼らから見れば、「いつも動いている」ものである。
  93. 93. 大規模システムでの信頼性 Manhattanの構築を始めた時、Twitterには、すで に沢山の大規模なストレージ・クラスターがあった。 それで、我々は、大規模なシステムを走らせることか らくる挑戦を理解していた。それは、新しいシステムで は、どのような性質を望み、どれを避けなければいけ ないかを教えていた。
  94. 94. 最悪ケースのパフォーマンス  信頼できるストレージシステムというのは、運用のあらゆ る場面でうまく稼働することを信用できるシステムである。 そして、予測可能なパフォーマンスは、達成するのは難し いのだ。予測可能なシステムでは、最悪ケースのパフォー マンスが、本質的に重要になる。平均的なパフォーマンス は、大きな問題にならない。よく実装され、正しく配備され たシステムでは、平均的なパフォーマンスが、関心を引く ことはほとんどない。  我々は、最悪ケースのスループットのために設計・配備を 行う必要がある。
  95. 95.  予測可能であることの、この優先順によって、いかなる潜 在的な問題、失敗のモードのあいだでも、いいパフォーマ ンスのためにプランが必要となる。顧客は、我々の実装の 詳細にも、言い訳にも興味がない。我々のサービスが、彼 らとTwitterにとって、動いているか動いていないかが問 題なのである。たとえ、全くありそうもない問題に直面して 、好ましくないトレードオフを行わなければいけないことに なったとしても、我々が記憶せねばならないのは、稀な出 来事というのは、大規模システムでは、もはや稀ではない のだということである。  スケールとともに、マシンやリクエストやデータの量が巨大 になるばかりではなく、そのシステムを利用しサポートす る両方の人間の数が増大するという人間のスケールの要 因が生まれてくる。幾つかの関心にフォーカスして、我々 は、この問題を管理している。
  96. 96. ストレージ・システムの構築 次世代のストレージシステムを構築する際、我々は、 システムを幾つかの階層に分割することを決めた。そ うすることで、システムは、十分なモジュラー性を持ち 我々がその上で構築できるものに、強固な基礎を提 供する。また、大きな変更を行うことなしに、少しずつ 特徴をロールアウトすることが可能になる。
  97. 97. Manhattanの階層  我々は、Manhattanを、以下の四つの階層に分離した。 interfaces, storage services, storage engines、coreである。
  98. 98. Core  coreは、ストレージシステムの最もクリティカルな側面で ある。それは、高度に安定していて頑健である。coreは、 失敗、結果整合性、ルーティング、トポロジーの管理、デ ータセンター内・データセンター間の複製の作成、衝突の 解決を処理する。システムのcoreの内部では、アークテク チャー上重要な部分は、完全に差し替え可能になってい て、速いスピードでデザインや改良を繰り返すことができ る。同様に、ユニット・テストも効果的に行われる。
  99. 99. 整合性のモデル  Twitterのアプリケーションの多くは、 eventually consistent モデルに、非常によくフィットする。我々は、 ほとんどすべてのユースケースで、整合性より高可用性 を好む。それで、Manhattanを、 coreの部分では、 eventually consistent なシステムとして構築したのは 、自然なことであった。  しかし、データについて、強い整合性を要求するアプリケ ーションは、常にあり得る。そうしたシステムを構築するこ とは、多くの顧客を得るために、高いプライオリティがあっ た。  強い整合性は、opt-inモデルである。開発者は、そのトレ ードオフをよく知っていなければならない。
  100. 100. 整合性の追求  eventually consistent なシステムで整合性を達成す るためには、我々がレプリカの調停と呼んでいる、要求さ れたメカニズムが必要になる。このメカニズムは、 incrementalでなければならず、また、常にレプリカ間の データを調整するプロセスが走っている必要がある。それ は、ビット落ちやソフトウェアのバグや書き込みの失敗(ノ ードが長い期間ダウンした)、データセンター間の分離な どに直面した時に役に立つ。  read-repair  hinted-handoff
  101. 101. Storage engines  我々は、現在、三つのストレージ・エンジンを持っている。  seadb: Hadoopからのバッチ処理のデータのための読 み取り専用のファイル・フォーマット。  sstable: 重い書き込み処理のための、ログ構造の merge treeベースのフォーマット。  btree: 重い読み出し、軽い書き出しのためのbtreeベ ースのフォーマット。  すべてのストレージエンジンは、ブロック単位の圧縮をサ ポートしている。
  102. 102. 二つの整合性モデル 三つのStorage Engine 二つの整合性モデル、三つのStorage Engine
  103. 103. ストレージ・サービス 我々は、Manhattanのcoreの上に、開発者が伝統 的なデータベースから期待するようになるかもしれな い特徴を、もっと頑健なものにすることを可能にする、 追加のサービスを作り出した。
  104. 104. Batch Hadoop importing  もともとの、Manhattanのユースケースの一つは、 Hadoopで生み出されるデータ上で、効率的にサービス を提供する層というものだった。  我々は、顧客がHDFS上に単純なフォーマットのデータセ ットを作り出すことを可能にする、インポート用のパイプラ インを構築し、その場所をセルフサービスのインターフェ ースに指定した。我々のWatcherが、自動的に新しいデ ータセットをピックアップし、それをHDFSの中のseadbに 変換する、だから、それらは、SSDからでもメモリーからで も、高速にクラスターにインポートされる。
  105. 105. binary diffs  このインポート用のパイプラインは、ストリーム・ライン化さ れて扱いが容易なので、我々は、成長を続けるデータセッ ト上で、開発者が、直ちに開発を繰り返し行えるようにす ることにフォーカスした。顧客から我々が学んだ一つの教 訓は、彼らは、巨大な数テラバイトもあるデータセットを作 る傾向があるということだった。その後のデータセットの更 新では、典型的には、10-20%以下のデータしか変更さ れないにもかかわらずだ。我々は、このデータをレプリカ にダウンロードするときに適用することができるbinary diffs を作ることで、ネットワークの帯域を低減するため の最適化を組み込んだ。これによってデータセンター間の すべてのデータのインポート時間を、実質的に低減した。
  106. 106. 強い整合性のサービス  強い整合性のサービスは、顧客がある一群の操作を行う ときに、強い整合性を持つことを可能にする。我々は、コ ンセンサス・アルゴリズムと複製されたログをペアで利用 して、すべてのレプリカにイベントが順番どうりに到達する ことを保証した。これで、 Check-And-Set (CAS)や、強 い読み込み、強い書き出しのような操作を行うことを可能 にした。今日では、 LOCAL_CASとGLOBAL_CASと呼 ばれている二つのモードをサポートしている。 GLOBAL_CASは、複数のデータセンターのquorumを またいで、強い整合性の操作を開発者に可能にする。一 方、 LOCAL_CASは、それが発行されたデータセンター の内部でだけ、調整される。両方の操作とも、遅延とアプ リケーションのモデリングで、異なったトレードオフを持つ。
  107. 107. Timeseries Counters service  我々は、Manhattanで、大きな容量を持つ時系列のカウ ンターを扱う、極めて特殊なサービスを開発した。このサ ービスを要請した顧客は、一秒あたり数百万のカウンター ・インクリメントを扱うことを必要としていた、我々の Observability インフラであった。  このスケールのレベルでは、耐久性の課題、インクリメント の前にそれが警報システムに見えるために必要とされる 遅延の問題、また顧客からのどのような種類の秒以下の トタフィックのパターンなら耐えられるのかといった問題等 々、様々な事柄でのトレードオフのデザインについて合意 する必要があるのだが、合意に至るまで、我々の技術者 は、演習に駆り出された。
  108. 108. ツール  我々は、host groupとweightの入ったファイルを編集 するだけで、システム全体のトポロジーを変更させ、再起 動のような共通の操作を、ノード全体で一つのコマンドで 実行できることを可能にするようなツールから始めた。こう した初期のツールでさえも、あまりにも煩わしいものになり 始めたころ、クラスターの状態を目標とする単純なコマンド を受け入れる自動化されたエージェントを構築した。それ は、オペレーターからの注意を引くこともなく、安全に効率 的に、命令をスタックし結合し実行することができる。
  109. 109. Storage as a service  既存のデータベースで我々が見てきた共通の問題は、そ れが、ユースケースのある特別な集まりに対して、設定さ れ管理されるようにデザインされていることだった。 Twitterの新しい内部サービスが成長するにつれ、我々 が認識したのは、そうしたことは、我々のビジネスには効 率的ではないということだった。  我々のソリューシンは、storage as a serviceという ものだ。我々は、エンジニアと運用者のチームに、エンジ ニアをコントロールする、完全なセルフサービスのストレー ジ・システムを構築することによって、大きな生産性の改 善を提供してきた。
  110. 110. Storage as a service  エンジニアは、彼らのアプリケーションが必要とするもの( ストレージのサイズ、一秒あたりのクエリー等)を与え、ハ ードウェアがインストールされスキーマが設定されるのを 待つことなしに、瞬時にストレージの利用を開始すること ができる。  会社内の顧客は、我々の運用チームが管理するマルチ・ テナントな環境で実行する。セルフサービスとマルチ・テナ ントのクラスターを管理することは、ある種のチャレンジだ った。それで、我々は、このサービス層を、第一級の特徴 として扱った。
  111. 111. Storage as a service  我々は顧客に、データと処理を、見える形で提供した。 quotaの機能強化とrate制限を組み込んで、エンジニア が、彼らの定義された制限を超えた時には警告を受け取る ようにした。我々のすべての情報は、分析と報告のため Capacity and Fleet Managementチームに、直接送ら れる。  エンジニアが新しい特徴をローンチすることを容易にするこ とで、我々が見たのは、実験が活発に立ち上がり、新しい ユースケースが急速に増えたということだった。これらをう まくハンドルするために、これらのデータを、コスト分析に 結びつける内部のAPIを開発した。これによって、どのユー スケースが最もビジネスにコストをかけ、また、どのユース ケースがおきそうもないかを決定することができた。
  112. 112. マルチ・テナンシーとQoS  マルチ・テナンシーをサポートすることは、多くの異なった アプリケーションが、同じリソースを共有することを意味す るのだが、それは、当初からキーとなる重要な要請だった 。それ以前のシステムを我々はTwitterで管理していたの だが、我々は、すべての特徴ごとにクラスターを構築して いた。それは、オペレーターの負荷を高め、リソースを浪 費し、顧客が新しい特徴を生み出すのを遅れさせていた。  先にも述べたように、複数の顧客が同じクラスターを使う ことを認めることは、我々のシステム実行のチャレンジを 増大させる。我々は、今では、隔離、リソースの管理、複 数の顧客の容量のモデリング、rateの制限、QoS、 quota、その他たくさんのことを考えなければならない。
  113. 113. マルチ・テナンシーとQoS  顧客に可視性を与えることに加えて、顧客は良き市民で あることが求められる。我々は、我々自身のrate制限サ ービスを、顧客のリソースやquotaの利用を強制するた めにデザインした。我々は、モニターし、必要であれば、リ ソース利用を絞る。それは、多くのメトリックを通じて、シス テム上では、誰のアプリケーションも他人のアプリに影響 を与えないことを保証するためである。rate制限は、荒い 粒度ではなく、秒以下のレベルで起きる。実世界の利用で 起きるある種のスパイクの間、耐えるために。
  114. 114. マルチ・テナンシーとQoS  我々は、すべての顧客からデータを抽出して、それを Capacityチームに送るという必要からAPIを構築した。 Capacityチームは、 (Twitterの標準によれば)小規模 ないしは中規模の要求をもった顧客に対して、我々はい つも準備ができた利用可能なリソースがあることを保証す るために働いている。だから、これらのエンジニアには、 我々からの追加のヘルプは必要でない。こうしたこと全て を直接セルフ・サービスに統合することで、顧客は我々の 大規模マルチテナントクラスター上に、新しい特徴をより 早くローンチすることが可能になり、我々は、もっと簡単に トラフィックのスパイクを吸収することが可能になる。という のも、大部分の顧客は、リソースの全てを、全ての時間で 使うことはないからだ。
  115. 115. 将来展望  我々は、将来に、まだ多くの仕事を残している。挑戦は、 増え続いており、Manhattan上で内部的にローンチされ る特徴の数も、速いペースで増え続けている。我々自身を 、より良いよりスマートなものへと強く押しているのは、 Core Storageチームで我々を駆り立てているものだ。我 々は我々の価値に誇りを持っている。twitterを良くする ために何ができるか、我々の顧客を成功させるにはいか にすればいいか? 我々は、Manhattanについてもっと 技術的な詳細と、我々が、製品として2年以上の稼働の間 に学んだものは何かを概括したホワイト・ペーパーのリリ ースを計画している。期待してほしい。
  116. 116. Mesos データセンターOSとその影響の拡大  Mesos  Aurora  Docker Containerizer  Mesosphere  Mesosの影響の拡大
  117. 117. Mesos Datacenter Operation System “Program against your datacenter like it’s a single pool of resources” http://mesos.apache.org/
  118. 118. Mesosとは何か?  Mesos は、自分を次のように規定している。 「分散アプリケーション、すなわち、フレームワークをまた いで、効果的なリソースの分離と共有を提供するクラスタ ー・マネージャー」  Mesosの中心プロジェクトは、オープンソースのApache インキュベーター・プロジェクトである。Mesosの上に、例 えば、StormやHadoopといった特別の技術を扱うスケ ジューラーを走らせることができる。そのアイデアは、同じ ハードウェアは、複数の目的のために利用でき、リソース の浪費を低減できるというものである。 http://goo.gl/Ax9LVw
  119. 119. Mesosとは何か?  数万のノードへのScalability  ZooKeeper を使った、Fault-tolerantなマスターとスレ ーブのレプリカ管理  Dockerコンテナーのサポート  Linuxコンテナーでの、タスク間のネーティブな隔離  マルチ・リソース (memory, CPU, disk, ports)のスケ ジューリング  新しいパラレル・アプリケーションを開発するための Java, Python, C++ APIs  クラスターの状態を見るWeb UI
  120. 120. Mesos のアーキテクチャー http://mesos.apache.org/documentat ion/latest/mesos-architecture/
  121. 121. Mesosの主要なコンポーネント  次の図は、Mesosの主要なコンポーネントを表している。  Mesosは、それぞれのクラスター上のノードで走るスレー ブ・デーモンと、それを管理するマスター・デーモン、これ らのスレーブ上でタスクを走らせるアプリケーション(これ は、フレームワークとも呼ばれる)から構成される。
  122. 122. Framework
  123. 123. マスターとリソース・オファー  マスターは、アプリケーションがリソースのオファーを行う ことで、アプリケーション間の細かな粒度でのリソース( CPU, RAM等)の共有を可能にする。  それぞれのリソース・オファーは、それらのリストを含んで いる。マスターは、与えられた(fair sharing, strict priorityといった)組織的なポリシーに応じて、どれだけ のリソースをそれぞれのフレームワークに提供するかを決 定する。  多様なポリシーの集合をサポートするために、マスターは 、プラグインのメカニズムを通じて、容易に新しいモジュー ルを割り当てられるように、モジュラー・アーキテクチャー を用いている。
  124. 124. schedulerとexecutor  Mesosの上で走っているフレームワークは、二つのコンポ ーネントからなる。一つは、フレームワークのscheduler (スケジューラー)で、マスターに提供されるべきリソースを 登録する。もう一つは、 executor プロセスで、スレーブ ノード上で起動されてフレームワークのタスクを実行する。  マスターは、どれだけの量のリソースが、それぞれのフレ ームワークに提供されるかを決定し、その一方で、フレー ムワークのスケジューラーは、どの提供されたリソースを 使うかを決定する。フレームワークが、提供されたリソー スを受け取る時には、Mesosに、実行しようと思っている タスクの記述をMesosに渡す。その代わりに、Mesosは、 対応するスレーブ上で、タスクを起動する。
  125. 125. リソース・オファーの例 フレームワーク Mesos マスター Mesos スレーブ
  126. 126. リソース・オファーのプロセス ① Slave 1は Masterに、自分には 4 CPUあって4 GBの メモリーが空いていると報告する。報告を受けるとMaster は、Allocation Policy Moduleを呼び出す。 Allocation Moduleは、Framework 1が、利用できる リソースを求めていると伝える。 ② Masterは、Slave 1にこれだけの利用可能なリソースが あるとFramework 1にリソース提供を申し出る。 ③ Framework 1のスケジューラは、Masterに二つのタス クをSlave 1 で走らせて欲しいと応答する。一つ目のタス クは <2 CPUs, 1 GB RAM> で、二つ目のタスクは<1 CPUs, 2 GB RAM>でという情報と一緒に。
  127. 127. リソース・オファーのプロセス ④ 最後に、Master は、Slave 1 にタスクを送る。それは、 Slave1 の Framework1 の実行エンジンに適切なリソ ースを割り当てる。こうして、二つのタスクが起動される( 図での、Slave 1の点線で囲まれた部分)。Slave 1の、 1 CPUと 1 GBのメモリーは、アロケートされていないの で、Framework 2のタスクに使われるかもしれない。 このリソース提供のプロセスは、タスクが終了して、新しいリソ ースがフリーになった時には、繰り返される。
  128. 128. フレームワークの制約条件と delay scheduling  Mesosによって提供される薄いインターフェースは、フレ ームワークが独立に、スケールし発展することを許すのだ が、一つの疑問が残る。すなわち、フレームワークの制約 条件は、Mesosがこれらの制約条件を知らなくとも、満た されることはできるのかということである。  例えば、Mesosがフレームワークが必要とするデータが、 どのノードにあるのかを知らないままで、フレームワーク は、どのようにしたら、データの局所性を実現することはで きるのだろうかという問題である。  Mesosの、こうした問題に対する答えは、フレームワーク にオファーを断る能力を与えるという単純なものである。 あるフレームワークは、自身の制約条件を満たさないオフ ァーは断り、満たすもののみを受け入れるのだ。
  129. 129. フレームワークの制約条件と delay scheduling  特に、入力データを格納するノードを見つけるまで、制限 時間のあいだは、フレームワークは待機するという、 delay schedulingと呼ばれている単純なポリシーが、 ほとんど最適なデータの局所性を与えることを、我々は、 見つけ出した。
  130. 130. http://aurora.apache.org/ Apache Aurora 長時間走るサービスと cronジョブのためのフレームワーク
  131. 131. Apache Aurora Apache Auroraは、Mesos上で走るサービス・ス ケジューラーである。それは、Mesosのスケーラ ビリティ、耐障害性、リソース隔離の利点を生か して、長時間走るサービスを走らせることを可能 にする。Apache Auroraは、現在は、Apache Incubatorの一部である。 https://github.com/apache/aurora/blob/ma ster/docs/tutorial.md
  132. 132. Aurora: Job  Aurora は、Mesos上でjobをスケジュールするために 利用されるMesosのフレームワークである。Mesosは、 個々のtaskを面倒見るのだが、典型的なjobは、数百に も昇るtaskのレプリカを持つ。Auroraは、Mesosの上 に、jobという抽象の層を提供する。  Auroraのjobは、taskのテンプレートと、そのtaskとほと んど等しいtaskのレプリカ(”instance id”が違うとか、マ シンごとにポート番号が違うとか。それ以外は、ほぼ同じ。 )を生成する命令からなる。  いくつのtaskがjobを構成するかは、複雑である。基本的 には、一つのjobは、一つのtaskテンプレートとそのtask とほとんど等しいtaskのレプリカ(”インスタンス”とか “shard”と呼ばれることもある)を生成する命令からなる。
  133. 133. Aurora: taskとprocess  taskは、一つのコマンドラインの命令(例えば、 my_script.py のような)に対応した、一つのprocess にすぎないこともある。ただし、taskは、その全てが一つ のsandbox上で走る沢山の別々のprocessから構成さ れることもある。例えば、logrotate, installer, master, slave というような複数のエージェントが協調し て走ることがある。  こうした時、Thermosが登場する。AuroraがMesosの Task上でJobの抽象を与えるように、Thermosは、 MesosのTaskの下で、Auroraフレームワークの executorの一部としてサービスし、Processの抽象を 与える。
  134. 134. Auroraの階層  Auroraは、taskからなるjobを管理する。  Mesosは、processからなるtaskを管理する。  Thermosは、processを管理する。  全ては、 .aurora 設定ファイルで定義される。
  135. 135. Sandbox  それぞれのTaskは、Taskが起動した時に生成され、そ れが終了した時に、ガーベージコレクトされるSandbox を持つ。  全てのTaskのProcessは、このsandboxの中で走る。 だから、processは、共有されたcurrent working directoryを使って、状態の共有が可能である。  Sandboxのガーベージ・コレクションのポリシーは、多く のファクターを考慮して決める必要がある。もっとも重要な のは、経過時間とサイズである。
  136. 136. AuroraでHello World! Auroraで、Hallo World! を実行してみよう Auroraで
  137. 137. import sys import time def main(argv): SLEEP_DELAY = 10 # Python ninjas - ignore this blatant bug. for i in xrange(100): print("Hello world! The time is now: %s. Sleeping for %d secs" % ( time.asctime(), SLEEP_DELAY)) sys.stdout.flush() time.sleep(SLEEP_DELAY) if __name__ == "__main__": main(sys.argv) hello_world.py
  138. 138. pkg_path = '/vagrant/hello_world.py' # ファイルの中身に応じて設定を変える。ここでは、バージョン番号に、 # ファイルのchekusumを使う。 import hashlib with open(pkg_path, 'rb') as f: pkg_checksum = hashlib.md5(f.read()).hexdigest() # hello_world.py をローカルのsandboxにコピー install = Process( name = 'fetch_package', cmdline = ‘cp %s . && echo %s && chmod +x hello_world.py’ % (pkg_path, pkg_checksum)) # スクリプトの実行 hello_world = Process( name = 'hello_world', cmdline = 'python hello_world.py') Auroraの設定ファイル hello_world.aurora
  139. 139. # taskの記述 # installとhello_worldをシーケンシャルに実行する。 hello_world_task = SequentialTask( processes = [install, hello_world], resources = Resources (cpu = 1, ram = 1*MB, disk=8*MB)) # jobの記述 jobs = [ Service ( cluster = 'devcluster', environment = 'devel', role = 'www-data', name = 'hello_world', task = hello_world_task ) ] Auroraの設定ファイル hello_world.aurora (続き)
  140. 140. Auroraの設定ファイルがしていること  まず、二つのprocess、installとhello_worldを定義。 install = Process( ... ) hello_world = Process( ... )  ついで、この二つのprocessをシーケンシャルに実行する Taskを定義する。 hello_world_task = SequentialTask( ... )  このTask定義の際に、Mesosが利用できるように、この taskが利用可能な計算リソースも定義しておく。 resources = Resources( cpu = 1, ram = 1*MB, disk=8*MB) )
  141. 141. Auroraの設定ファイルがしていること  最後に、Jobの定義。Jobは、利用可能なマシン上に Taskをスケジュールする。この例では、JobはJobリスト の唯一のメンバーだが、configファイルでは、一つ以上の Jobを指定できる。 jobs = [ Service( cluster = ‘devcluster’, environment = ‘devel’, role = ‘www-data’, name = ‘hello_world’, task = hello_world_task ) ]
  142. 142. Auroraの設定ファイルがしていること  Process レベルでは、この設定ファイルは、コードが走る ローカルのsandboxに、どのようにコードをインストール するのかを指定している。 install = Process( ... )  ついで、第二のプロセスが起動した時、実際に、どのよう にコードが実行されるかを指定している。 hello_world = Process( ... )
  143. 143. Jobの生成と実行 aurora job create ...  実際に、我々のjobを走らせる Auroraクライアント・コマン ドは、 aurora job create である。それは、job keyと、 configファイルを引数に取り、それらで指定されたjobを生 成しそれを実行する。 aurora job create devcluster/www-data/devel/hello_world /vagrant/hello_world.aurora job key Aurora Configuration File
  144. 144. job key の構成  job key は、“/” で区切られた四つの部分からなる。四つの部分 は、次のような部分から構成される。 <cluster>/<role>/<environment>/<jobname>  先のコマンドの例で言うと、次のようになる。 devcluster/www-data/devel/hello_world cluster role environment jobname
  145. 145. job keyとjobの一意な指定  Cluster:clusterの名前。  Role:そのslaveマシン上に存在する、ユーザーのアカ ウント名。  Environment:名前空間。”prod” (製品版)、 “devel”(開発版)、”test” (テスト用) の三つが用意され ている。  Jobname:job名  二つのjob keyを比較して、四つの構成要素が対応する 要素と、一つでも違っていれば、二つのjob keyは、二つ の別々のjobを指定していることになる。四つの値が全て 同じであれば、このjob keyは、同一のjobを指定する
  146. 146. clusterの定義  このjob keyの指定は、よく見ると、この例では、 *.aurora のAurora設定ファイルが、 jobs = [ Service( ... ) ... ] の中で、Serviceのパラメータに設定されたものと重複し ている。(jobをTaskに結びつける、task = ... というパ ラメータを除いては)  それぞれのパラメーターの説明は、これから、おいおいす ることにして、まず、先頭のclusterは、どのように定義さ れているのだろうか?
  147. 147. clusterの設定 /etc/aurora/clusters.json  clusterの設定は、/etc/aurora/clusters.json というファ イルの中で行われている。こんな中身だ。 [{ “name”: “devcluster”, “zk”: “192.168.33.7”, “scheduler_zk_path”: “/aurora/scheduler”, “auth_mechanism”: “UNAUTHENTICATED” }]
  148. 148. MarathonとChronos
  149. 149. MarathonとChronos  Marathon: 長時間走るアプリのためのApache Mesosのフレームワ ーク。Mesosがデータセンターのkernelだとすれば、 Marathonは、init デーモンにあたる。 https://github.com/mesosphere/marathon http://mesosphere.github.io/marathon/  Chronos: 同じく、 Apache Mesosのフレームワークで、cron に 相当する。 https://github.com/mesos/chronos http://mesos.github.io/chronos/
  150. 150. Marathonによって 起動されたTaskと、 Chronosによって 起動されたTask。 Chronosは、 Marathonによって 起動されている。 Chronosによって 定期的に、dump- dbや、rake email sendが呼び出され ている。 http://mesosphere.github.io/marathon/
  151. 151. Scale out Server Error 再配置 Marathonの仕事
  152. 152. Apache Mesos 0.20/Apache Aurora 0.7で、Dockerサポート
  153. 153. Docker Containerizer http://mesos.apache.org/documentat ion/latest/docker-containerizer/
  154. 154. Docker Containerizer  Mesos 0.20.0 は、Dockerイメージを含んだtaskの実 行のサポートを追加した。また、Dockerでサポートされて いるオプションのいくつかを、将来的には追加していく。  ユーザーは、Dockerのイメージを、Task あるいは Excutor として実行できる。  slaveが、Docker Containerizer を実行可能にするた めには、containerizerのオプションの一つとして、 ”docker”を指定する必要がある。次のように。 mesos-slave –containerizers=docker,mesos  Docker containerizer を持つ、それぞれのslaveには 、Docker CLI client (version >= 1.0.0)がインスト ールされる必要がある。
  155. 155. Docker Containerizerを どのように利用するか?  0.20.0以前のTaskInfoは、bashコマンドを走らせる CommandInfo を設定するか、taskを起動する特別の Executorを起動するExecutorInfoを設定するか、どち らかのサポートのためにのみ利用されていた。  0.20.0 では、TaskInfoと ExecutorInfoに、 我々は、 ContainerInfoフィールドを追加して、Dockerのよう なContainerizerが、taskあるいはexecutorの実行を 設定されることを可能にした。
  156. 156.  Dockerイメージをtaskとして実行するためには、 TaskInfoの中で、コマンドとともに、Docker Containerizerが Dockerイメージを起動するために、そ れに伴って利用するコマンドのコンテナー・フィールドの、 両方を設定しなければならない。 このContainerInfoは 、Dockerというtypeと、 希望するdockerイメージを持つ DockerInfoを持たなければならない。  Dockerイメージを、executorとして実行するためには、 TaskInfoの中で、type dockerを持つContainerInfo と、executorを起動するために利用される CommandInfoを含む、 ExecutorInfoを設定しなけれ ばならない。  Dockerイメージは、Mesos executor として立ち上がる ことが期待されていることに留意すること。それは、一回 起動された際に、slaveとともに、登録するだろう。
  157. 157. Docker Containerizerは、 何をしているのか?  Docker Containerizer は、 Task/ExecutorのLaunch とDestroy呼び出しを、 Docker CLI コマンドへ変換して いる。  現時点で、 Docker Containerizer はtaskとして起動さ れた時、次のことをしている。 1. CommandInfo で指定されたファイルをすべて、 sandboxに取り込む。 2. リモート・リポジトリーからdockerイメージを取得。
  158. 158. Docker Containerizerは、 何をしているのか? 3. Docker executorは、  dockerイメージを実行し、  sandboxのディレクトリーをDocker コンテナーにマッ プし、  ディレクトリー・マッピングをMESOS_SANDBOX環境 変数にセット  executorは、コンテナのログをsandboxの stdout/stderrファイルに流し込む。 4. container exit あるいは、 containerizer destroyで dockerコンテナーを stop、removeする。
  159. 159.  Docker Containerizerは、先頭に”mesos-”がつき、 その後ろにslaveのidが続く(例えば、 mesos-slave1- abcdefghji のような)名前を持つ、すべてのコンテナー を起動する。そして、”mesos-”の名前を持つすべてのコ ンテナーは、slaveによって管理され、自由にコンテナーを stopあるいはkillできると想定する。  Executorとしてdockerイメージを起動する時には、ただ 一つの違いは、executorコマンドをスキップして、 docker コンテナーのexecutorのpidを取得することだ けである。
  160. 160.  dockerイメージを実行する時、現時点では、デフォールト では、ホストのネットワークに繋がっていることに留意する こと。それは、 Executorとしてdockerイメージの実行を サポートするのを容易にするためである。  containerizerは、イメージを強制的に取得する機能も、 オプションとしてサポートしている。 これがオフにされてい ると、dockerイメージは、ホストで利用できない場合にし か再更新されない。
  161. 161. プライベート Docker レポジトリー  イメージをプライベート・レポジトリーから実行するために、 ログイン情報を含んでいる .dockercfgをポイントしてい る uriを含めることができる。 この .dockercfgファイル は sandboxに引き出されて、 Docker Containerizer は、HOME環境変数を、このsandboxをポイントするよう に設定する。それで、dockerのcliは、自動的にconfigフ ァイルをピックアップできる。
  162. 162. Dockerイメージを実行する CommandInfo  dockerイメージは、現時点では、entrypointとデフォー ルト・コマンドをサポートしている。  docker run imageのように、デフォールト・コマンドで dockerイメージを実行するためには、 CommandInfo の値が設定されていなければならない。もし、値が設定さ れていれば、それはデフォールト・コマンドを上書きする。  定義されたentrypointでdockerイメージを走らせるため には、 CommandInfoのshellオプションは、falseに設 定されていなくてはならない。それがtrueの時、 Docker Containerizerは、 /bin/sh -c でラップされたユーザー コマンドを実行する。それはまた、イメージのentrypoint へのパラメーターにもなる。
  163. 163. slaveのrecoveryで、Dockerコンテ ナーを回復する  Docker containerizerは、slaveが再起動した時、 Dockerコンテナーのrecoveryをサポートしている。それ は、slaveがdockerコンテナーの中で走っていても、そう でなくとも、両方でサポートされる。  With the docker_mesos_imageフラグが立っていれ ば、 Docker containerizer は、このconternerizerが コンテナー自身の内部で走っていると想定する。そして、 dockerコンテナーが、それに従ってrecoverやlaunchを 行うメカニズムを修正する。
  164. 164. Mesosphere
  165. 165. Mesosphere DCOS と Apache Mesos の違い  Mesosphere DCOSは、オープンソースのMesos上に 構築された、商用サポートのあるソフトウェア製品。 コマンドライン、Webインターフェース、パッケージングや インストールが強化されている。また、技術的なパートナ ーとのエコシステムも拡大している。  Mesosphere DCOSは、オープンソースではない。ただ それは、オープンソースのApache Mesos, Marathon, Chronosに基づいている。
  166. 166. The Mesosphere Datacenter Operating System 「自分のデータセンターやクラウドを、Mesosphere データセンター・オペレーティング・システムで、自動 運転させる。時間とお金を節約して、ソフトウェアはよ り早く配布する。」 https://mesosphere.com/
  167. 167. A New Kind of Operating System  Mesosphere データセンター・オペレーティング・システ ム (DCOS)は、新しい種類のオペレーティング・システム である。それは、物理サーバー、クラウド・ベースのデータ センターのサーバーをまたいで、その上で、あらゆるバー ジョンのLinuxが走る。 Killer Apps User Interface Programmable Datacenter
  168. 168. 特徴  キラー・アプリ: どんなLinuxのアプリケーションも、簡単 にデプロイする。一つのコマンドで、データセンターのサー ビスをインストールできる。その中には、Hadoopや SparkやCassandraやKubernatesが含まれる。  ユーザー・インターフェース: オペレーターや開発者は、 データセンターを一つの大きなマシンのようにコントロール できる、我々のCommand Line Interface (CLI)を、 気に入っている。  プログラム可能なデータセンター: 我々のSoftware Developers Kit (SDK)とAPIで、新しい分散アプリを開 発しよう。データセンターに対して、それが一つの大きなコ ンピュータであるかのようにプログラムしよう。
  169. 169. Mesosphere DCOS  Mesosphere DCOS は、すべてのマシン、VM、クラウド 上のインスタンスを、インテリジェントで動的な共有リソー スの単一のプールに組織する、新しいタイプのオペレーテ ィング・システムである。それは、あらゆるバージョンのモ ダンなLinuxの上で走り、それを強化する。  Mesosphere DCOSは、高可用性と耐障害性を持ち、プ ライベートなデータセンターでも、パブリックなクラウドの上 でも動く。それは、劇的に、利用率を高め、オペレーション の複雑さを減少させ、開発者をもっと生産的にする。  Mesosphere DCOSは、Apache Mesosを中心に構成 されている。その分散システム・カーネルは、 UC BerkeleyのAMP Labで発明され、TwitterやNetflixや Airbnbのような会社で、大規模に利用されている。
  170. 170. データセンターでしたいと思うことは、 なんでも、我々がカバーする.  新しいアプリケーションを、書いてデプロイすることが、個 々のマシンと静的なパーティションを管理することを意味し ていた時代は、過ぎ去った。データセンターとクラウドのリ ソースをプールして、すべてのアプリが同じマシン上で動く こと。これは、複雑さと浪費を削減する。  Scale Infinitely 数万のノードに、ほとんど手間をかけなくても拡大でき、そ うして、動的にリソースを割り当てることが簡単にできる。  Run Anywhere Mesosphere は、オープンソース・テクノロジーの上に構 築されているので、 どんなクラウドやデータセンターでも、 柔軟さを保ったまま、走ることができる。
  171. 171.  Never Fail Mesosphereは、リソースを再バランスしながら、 走り続 け、失敗したタスクは自動的に再スタートされる。  Optimize Resources Mesosphere は、それぞれのサーバーに、複数のアプリ をパックして、リソースの利用を高める。  Operate Automatically Mesosphereは、クラスターを管理する高度な自動化を もたらし、オペレーションの時間とお金を節約する。  Develop Quickly Mesosphereで、開発者は、サーバーのことを考えずに、 コードだけを考えればいいので、ビルドとデプロイを高速 に行うことができる。
  172. 172. Mesosphere データセンターOSは、 全ての主要なプラットフォームで走る
  173. 173. Mesos データセンターOSとその影響の拡大 Apache Mesosだけでなく、そのデータセンター OSへの機能強化版のApache Aurora, Aurora 相当の商業製品Mesosphereといった「Mesos文 化圏」ともいうべきものは、Docker, Kubernetes と いったContainer技術と結びつき、大規模分散の世 界で、もっともダイナミックでアクティブな領域に成長し ようとしている。
  174. 174. PaaS and Long Running Big data processing Batch scheduling Data storage “Framework on Mesos” https://goo.gl/1oDvTc
  175. 175. Mesos利用の拡大 -- Mesosphere Blog タイトルから --  The Mesosphere Datacenter Operating System is now generally available  Get Mesos-DNS up and running in under 5 minutes using Docker  Building real-time data flows with Kafka on Mesos  Cassandra on Mesos: Performance + Reliability  Deploying Kubernetes on Mesos  It’s easier than ever to scale like Google without being Google https://mesosphere.com/blog/
  176. 176. Mesos利用の拡大 -- Mesoshere Blog タイトルから --  Launching thousands of Docker containers with DCOS on Azure  Join the DCOS public beta on Microsoft Azure and AWS  Apple details how it rebuilt Siri on Mesos  Making Kubernetes a first-class citizen on the DCOS  MySQL on Mesos: today’s database meets tomorrow’s datacenter https://mesosphere.com/blog/
  177. 177. “Mesosphereは、Googleスケールの計算能力を万 人にもたらす。” Abdur Chowdhury, Former Chief Scientist, Twitter “Mesosphereは、クラウド・コンピューティングの避 けられない運命だ。” Brad Silverberg, Fuel Capital “Mesosphereは、開発者にとってのブレークスルー だ。数千のDropletでさえ、一つのコンピュータのよう に管理するその能力は、とてもエキサイティングなも のだ。” Ben Uretsky, CEO and Co-founder of DigitalOcean
  178. 178. [余談] 大規模分散システムのパワーを、 誰が、どのように利用するのか? 21世紀初頭のGoogleの登場は、大規模分散システ ムが、そのパワーを現した画期だった。あれから、もう 15年がたつ。ただ、その当時には、Googleだけしか それができなかった。大規模分散システムのパワーを 、誰が、どのように利用するのかについて、次の変化 が起きつつあるように見える。
  179. 179. MesosとBorg  Mesosは、GoogleのBorgにインスパイアされて生まれ た、オープンソース・プロジェクトである。  Borgは、以前から、その存在は知られていたが、GFS, MapReduce, BigTable とは異なって、その技術的詳細 をGoogleが明かすことはなかった。Borgは、Googleの 大規模分散の中核技術であり、ある人は、それを「 Googleの秘密兵器」「Googleの急速な進化の、もっとも よく保たれた秘密」と呼んでいた。  “Return of the Borg: How Twitter Rebuilt Google‘s Secret Weapon”http://goo.gl/QyhGjx  "Twitter’s Aurora and How it Relates to Google’s Borg (Part 1)"http://goo.gl/BRhL7x
  180. 180. Google, Borgの情報公開  今年の4月、Googleは、Borgの情報を初めて公開した。 “Large-scale cluster management at Google with Borg” https://goo.gl/aN03bI  この発表に対して、Auroraのアーキテクトのコメントを含 む記事が、出ている。“Google Lifts the Veil on Borg, Revealing Apache Aurora’s Heritage”http://goo.gl/Nv8ZIQ  僕には謎だったBorgの名前の由来だが、それは、Star Trekに 登場する「宇宙種族のひとつ。蜂や蟻をモチーフにした社会的集 合意識を持っているとされ、中央制御装置としてのQueenがいる 」とのこと。Facebookで友人から教えてもらった。納得。
  181. 181. Google Borg Google’s Borg system is a cluster manager that runs hundreds of thousands of jobs, from many thousands of different applications, across a number of clusters each with up to tens of thousands of machines 数十万のジョブ 数千のアプリケーション 数万のマシン
  182. 182. 大規模分散システムとクラウド -- いくつかの視点  概念的には、大規模分散システムの方が、クラウドより広 い。ただ、2006年のAWSのサービス開始に始まるクラウ ドの成立は、大規模分散の第二の画期である。  「作る人」と「使う人」: 大規模分散システムを作るのは難 しく、使うのは易しい。FacebookやTwitterを使うのに、 そのサービスを支える技術を理解する必要はない。  クラウドを作るのは簡単ではない。クラウドを「作る人」は、 まだ、少数である。  クラウドを「使う人」は、二つのタイプに分かれる。一つは、 クラウド上にサービスを構築する人達である。彼らは、「作 る人」でもある。もう一つは、こうしてクラウドを「使う人」に よって構築されたサービスを、消費する人たちだ。
  183. 183. 大規模分散システムとクラウド -- いくつかの視点  クラウドを「使う人」であると同時に、クラウド上のサービス を「作る人」が、現在のクラウドの活況の中心にいる。それ はそれで結構なことである。  それでは、彼らのエネルギーは、これからどこに向かうの だろうか? ここで、あらためて最初に述べた、大規模分 散とクラウドの違いを考えるのは、意味があると思う。  これから重要なことは、基本的には、大規模分散のパワ ーを、新しいサービスに結びつけること、そうした新しいビ ジネスを作り出すことだと思う。  かつては、非常に困難だった、大規模分散システムを「作 る人」に、誰もが簡単になれる時代が始まろうとしている。
  184. 184. 資料編  Aurora 実行例 https://github.com/apache/aurora/blob/master /docs/tutorial.md  Aurora + Thermos Configuration Reference https://github.com/apache/aurora/blob/master /docs/configuration-reference.md  データセンターOS API http://goo.gl/Iwkn9u  Hosting Environment (これまでのContainer技術) マルレク2003から https://goo.gl/MnjtqO
  185. 185. Aurora 実行例
  186. 186. $ vagrant ssh Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64) Documentation: https://help.ubuntu.com/ Welcome to your Vagrant- built virtual machine. Last login: Fri Jan 3 02:18:55 2014 from 10.0.2.2 vagrant@precise64:~$ aurora job create devcluster/www- data/devel/hello_world /vagrant/hello_world.aurora INFO] Creating job hello_world INFO] Response from scheduler: OK (message: 1 new tasks pending for job www-data/devel/hello_world) INFO] Job url: http://precise64:8081/scheduler/www- data/devel/hello_world ... ... 実行結果
  187. 187. schedulerの状態を見る  http://$scheduler_hostname:$scheduler_port/sc heduler にアクセスするとschedulerの状態を見ることが できる。この例では、 http://192.168.33.7:8081/scheduler である。  Role www-dataのjobが一つ走っていることがわかる。
  188. 188. role(ユーザー)ごとのjobを見る  先の状態で、ユーザー名(この場合、www-data)をクリ ックする。Environment devlで、hello_world Jobが 走っていることがわかる。
  189. 189. Jobの実行を見る  hello_worldをクリックすると、jobの実行状態が見える。  あれ、Taskが失敗して、終了している。
  190. 190. Taskの状態をチェックする  hostをクリックして、Taskの状態を見る
  191. 191. バグを修正して、再実行  実行プログラムにバグがあったようだ。バグを修正して、 再実行すると、今度は、上手くいく。
  192. 192. processの出力を見る  processのstdoutをクリックすると、その出力が確認でき る。
  193. 193. jobを殺す aurora job killall ...  次のようにして、投入したjobを殺せる。 vagrant@precise64:~$ aurora job killall devcluster/www-data/devel/hello_world INFO] Killing tasks for job: devcluster/www- data/devel/hello_world INFO] Response from scheduler: OK (message: Tasks killed.) INFO] Job url: http://precise64:8081/scheduler/www- data/devel/hello_world vagrant@precise64:~$
  194. 194. jobページで、結果を確認する  Hello_world プロセスは、killされている。
  195. 195. Aurora + Thermos Configuration Reference https://github.com/apache/aurora/bl ob/master/docs/configuration- reference.md
  196. 196. Process Schema
  197. 197. Attribute Name Type Description name String プロセス名(必須) cmdline String コマンドライン(必須) max_failures Integer プロセス失敗最大数(Default: 1) daemon Boolean 真の時、daemonプロセスである (Default: False) ephemeral Boolean 真の時、ephemeralプロセスである (Default: False) min_duration Integer プロセスが再起動する間の最小継続 秒 (Default: 15) final Boolean 真の時、このプロセスは、最後に走る finalizingプロセスである (Default: False)
  198. 198. Task Schema
  199. 199. param_ type description name String プロセス名(必須) (Default: processes0.name) processes List of Process objects このtaskに結びつけられているプロセス のリスト (必須) constraints List of Constraint objects プロセスを制約しているconstrainオブ ジェクトのリスト resources Resource object リソースの詳細情報 (必須) max_failures Integer 失敗したとみなされるプロセスの失敗の 最大回数 (Default: 1) max_concurrency Integer 並列プロセスの最大数 (Default: 0, 並 列プロセス数に制限なしの意) finalization_wait Integer finalizingプロセスに割り当てられた時 間の総量。秒で。 (Default: 30)
  200. 200. Job Schema
  201. 201. name type description task Task このjobにバインドするTaskオブジェクト。必須。 name String Job名。 (Default: taskの属性名から継承) role String Job roleのアカウント。 必須。 cluster String このjobが、その中でスケジュールされている Cluster。必須。 environment String Job環境。defaultは devel。prod, devel, test, staging<number>のうちのひとつでな ければならない。 contact String jobのオーナーにリーチするのに最適のメール アドレス。製品版のjobでは、通常は、開発チー ムのメーリングリスト。 instances Integer 生成されたtask(場合によっては、レプリカある いはshard)のインスタンスの数。(Default: 1)
  202. 202. cron_schedule String cronフォーマットでのCronスケジュール。サー ビスではないjobにのみ利用されるだろう。詳細 な情報は、Cron Jobs を参照されたい。 Default: None (cron jobではないということ) cron_collision _policy String 以前の実行が生きている間に、cron jobが起 動された場合のポリシー。 KILL_EXISTING: 以前の実行を殺して、新し い実行をスケジュールする。 CANCEL_NEW: 以前の実行を継続して、新し い実行をキャンセルする。 (Default: KILL_EXISTING) update_config update_co nfig object rollingアップデートの率とポリシーをコントロー ルするパラメータ。
  203. 203. constraints dict taskのスケジューリングの制約条件。 constraint specification languageを参照。 service Boolean もし真ならば、成功・失敗に関わりなくtaskを再 起動する。 (Default: False) max_task_f ailures Integer taskが失敗したとみなされるまでの失敗の数の 最大数。 (Default: 1) 無限回の失敗を許す場合には、-1をセットする。 priority Integer taskに与えられるPreemption プライオリティ (Default 0). 高いプライオリティのtaskは、低 いプライオリティのtaskより、優先的に実行され る。
  204. 204. production Boolean これがproduction taskであろうとなかろうと、 quotaでbackされる。 (Default: False). Production jobsは、どんな non- production jobよりも優先され、同じroleの より高いプライオリティのproduction jobsに よってのみ優先される。このレベルでjobを実 行するためには、job roleは、適当なquota を持たなければならない。 productionの特 定のroleにquotaを認めるためには、オペ レーターは、aurora_admin set_quotaコ マンドを利用する。 health_che ck_config heath_check_ config object HTTP経由でのtaskのヘルス・チェックをコン トロールするパラメータ。ヘルス・ポートが、コ マンドラインのワイルドカードで指定された時 にのみ利用される。 container Container object 全てのプロセスが、その中で走るオプショナル なコンテナ。
  205. 205. データセンターOS API “Building & Deploying Applications to Apache Mesos” http://goo.gl/Iwkn9u の一部 抜粋
  206. 206. FrameworkInfo https://github.com/apache/mesos/blob/master/include/mes os/mesos.proto message FrameworkInfo { required string user = 1; required string name = 2; optional FrameworkID id = 3; optional double failover_timeout = 4 [default = 0.0]; optional bool checkpoint = 5 [default = false]; optional string role = 6 [default = "*"]; optional string hostname = 7; optional string principal = 8; optional string webui_url = 9; }
  207. 207. TaskInfo message TaskInfo { required string name = 1; required TaskID task_id = 2; required SlaveID slave_id = 3; repeated Resource resources = 4; optional ExecutorInfo executor = 5; optional CommandInfo command = 7; optional ContainerInfo container = 9; optional bytes data = 6; optional HealthCheck health_check = 8; optional Labels labels = 10; optional DiscoveryInfo discovery = 11; }
  208. 208. TaskState 可能なタスクの状態を記述する。Mesosは、終了状態に入った タスクは、もはや実行されていないとみなす。そして、この タスクに関連したすべてのものを片付ける。(最終的には、 このタスクで消費されていたリソースは、他のタスクに回さ れる) enum TaskState { TASK_STAGING = 6; // Initial state. Framework status updates should not use. TASK_STARTING = 0; TASK_RUNNING = 1; TASK_FINISHED = 2; // TERMINAL. The task finished successfully. TASK_FAILED = 3; // TERMINAL. The task failed to finish successfully. TASK_KILLED = 4; // TERMINAL. The task was killed by the executor. TASK_LOST = 5; // TERMINAL. The task failed but can be rescheduled. TASK_ERROR = 7; // TERMINAL. The task description contains an error. }
  209. 209. Scheduler registered スケジューラーがMesosマスターへの登録が成功した時に 起動される。ユニークなID(マスターによって生成され る)は、このフレームワークを他のフレームワークと区 別するために利用される。現在のマスターのIPアドレスと ポート番号をもつMasterInfoが、引数として提供される。 def registered( driver: SchedulerDriver, frameworkId: FrameworkID, masterInfo: MasterInfo): Unit = { log.info("Scheduler.registered") log.info("FrameworkID:n%s" format frameworkId) log.info("MasterInfo:n%s" format masterInfo) }
  210. 210. Scheduler reregistered 新しいMesosマスターが選出された、スケジューラーが 登録された時起動される。これは、スケジューラーが以 前に登録されていた場合にのみ呼び出される。 MasterInfoは、新しく選出されたマスターの更新された 情報を含んでいて、引数を提供する。 def reregistered( driver: SchedulerDriver, masterInfo: MasterInfo): Unit = { log.info("Scheduler.reregistered") log.info("MasterInfo:n%s" format masterInfo) }
  211. 211. Scheduler resourceOffers スクジューラは、リソースがこのフレームワークにオファーされた時 に起動される。単一のオファーは、単一のスレーブからのリソース だけを含んでいるだろう。オファーに関連したリソースは、次の条 件を満たさなければ、このフレームワークには、再オファーされる ことはないだろう。 (a) このフレームワークが、これらのリソースを断っていた。 (b) これらのリソースが撤回されていた。 リソースは、同時に(利用されているAllocatorに従って)、一つ以上 のフレームワークにオファーされることがあることに注意せよ。この 場合には、これらのリソースを使ってタスクを起動した最初のフレ ームワークが、それを使うことができる。

×