Hadoop の時代は終わってないけど、使いどころは限定されてきたかもしれない

id:shiumachi さんが書かれてる下記の記事がとても良かったです。 shiumachi.hatenablog.com

私自身もSparkを触る前は「Hadoop == MapReduce」と思ってましたが、どちらかというとYARNやHDFSHadoopファミリの核だと最近は思いますし その意味でのHadoopは全然終わってないと思います。記事の中で書かれてる通り、ある意味ではさらなる進化を遂げて花開いてる状態かな、と。

ただ、Twitterにも少し書いたんですが一方で「猫も杓子もHadoop!」の時代が終わりつつあるのも事実かな、と思います。

もうちょっというとHadoopに限らず巨大スケールの分散システムの用途が収斂してきたのかな、と。

HadoopGoogle MapReduce登場時のと違い、ストレージI/Oは133MB/sとかの単位で争ってたHDDからストレージに代わって、今や3GB/sを超えます。しかもランダムアクセスもHDDよりずっと速くなっている。

ちょうど最近発表されたZenベースのサーバだと64コア/128スレッドで、メモリも4TBです。普通に当時の10倍以上のマシンスペックがある訳です。単純に。

pc.watch.impress.co.jp

また、そういったハードウェアスペックに合わせてインメモリDBやクラスストレージメモリ、あるいはGPUを活用する形にRDBなどのミドルウェアも進化しています。

それこそ2010年からしばらくは「デカいデータ処理(あえてビックデータとは呼ばない)は分散システムでやるべし、すなわちHadoop!」って感じだったと思っています。

これは本来Hadoopがターゲットにしているビックデータ(TB級やPB級)ではなく数百GB級でも普通に組んだら性能足らなくて仕方なく使ってたケースがあるかと。

そういった用途で使われていたHadoopファミリは徐々に利用されない形になっていくんじゃないかと。

例えば、3GB/sのI/O性能が出るなら、1TBのデータ読み込みですら5分と少しです。

数TBのサイズであればインメモリDBにデータがすべて乗ります。

数十から百程度の並列処理なら分散しなくても単体マシンで処理可能です。

こうなってくると機械学習や特大のDWH以外はTB,PBクラスの処理をすることは少ないと思います。特に歴史がある会社だと昔から運用してるので業務的に圧縮してるはずだから、通常業務のデータはそんなにでかくないはずなんですね。日次とか月次でサマったり。じゃないと元々運用できないですし。

なので、そういった業務に対して単純に利用者が増えるとかの線形なデータ増加に対する対応だとHadoopのような巨大な分散システムを運用する必要性は小さくなってきます。

もちろん、冗長性やローリングアップデートのためにもシステムが多重化されてる事は大事なんですが、数百台のクラスタで動かすことを想定した分散システムではなく、 それなりに信頼できる数台のマシンで構成した小さなクラスタを運用する方向性が強まってくるんじゃないかな、と。

ただ、強まってくるんじゃないかと思いつつもRDBに分投げる方はともかく、分散処理エンジンであるSparkに代替するような並列処理エンジン/管理システムがあんまり無いのも困りもの。

自分が知る限りだとそのコンセプトを強く打ち出してるのはAsakusa-on-M3BPくらいですね。

RDBをインメモリで運用できてそっちに処理をオフロード出来るケースなら、あまり問題ないのですがそうじゃない場合は「複数スレッドをマネージするバッチの処理基盤」自体はやはり必要です。

何も考えずに各々のアプリが好きなサイズのスレッドを取得して使うと、ジョブスケジューリングが適切にできなくなってしまいます。

なので、Asakusaのような思想でのミドルがもう少し増えて、運用ノウハウが溜まっていけばな、と思ってます。

あるいはMesosやk8sでリソースを別途管理する基盤を作るかですね。JavaEEのjBatchもそういう方向で活用が出来そうだけど、ぶっちゃけ登場が遅すぎて機能とエコシステムが弱いのがネックですねぇ。

この辺は決定版が無さそうだから管理ツールとか含めて自作する必要があるかも。

まとめ

なんか途中から大分脱線した気がしなくもないけど、Hadoopの時代は終わってなものの「本当はHadoop使うには微妙だけど他に選択しないからHadoop」って用途がHWやMWの進化で、 適切なシステムに移行していくので、結果としてHaoopのような大規模分散クラスタは特定の用途に寄るだろうなってのが言いたい事でした。

それではHappy Hacking!

参考:

Javaの分散トレーシングとかAPMとか実行時ログとか

メモ的まとめ

APM

blog.takipi.com

www.itcentralstation.com

http://www.hawkular.org/hawkular-apm/www.hawkular.org

github.com

分散トレーシング

http://zipkin.io/zipkin.io

http://opentracing.io/opentracing.io

ログ系

builder.japan.zdnet.com

docs.oracle.com

http://icedtea.classpath.org/wiki/HeapStats/jpicedtea.classpath.org

www.slideshare.net

Weblogic(ECID)

www.slideshare.net

blogs.oracle.com

形式手法関連のメモ

ソフトウェア工学の道具としての形式手法

形式手法に関して歴史的かつ網羅的にまとめてあった

OpenJML

上記でも触れられてたJava向けの拡張静的チェッカ? ECS/Java2の後継? Java8対応らしいので試してみる

机上の Kubernetes - 形式手法で見るコンテナオーケストレーション

形式手法はソフトウェア設計に適用するものって凝り固まってたけど、 考えてみれば状態遷移やルール記述の塊であるインフラ構成やフローにも適用できるよね。目から鱗

ccvanishing.hateblo.jp

www.slideshare.net

EJB コンポーネントアーキテクチャの SPIN による振舞い解析

Spinを使ったEJBコンポーネントの記述事例。分散システムの記述にSPINは良いらしい

ゼロから始めるdocker生活 ~ VT-Xなんてない

さて、タイトルで誤解されそうですがこの記事はDockerの入門記事ではありません。

現代的なツールチェインが使えない異世界な気分に浸れる開発環境を与えられたとあるプログラマーの異世界訪問記みたいなものです。

現代的な開発環境を作る上で欠かせない存在。その一つはDockerです。

サーバ環境と同等の開発環境をサクッと作れるのは開発者はもちろん開発環境や運用環境を構築する担当としても有用なものです。

でも、そんなDockerが使えなかったら? 今回はそんな開発環境に迷い込んだ時のお話。

※ この物語はフィクションです。登場する人物・団体・名称、エピソード等は架空であり、実在のものとは少ししか関係ありません。

開発環境? もちろんWindowsだよ!

今日から新しい職場です。プロジェクトの初期メンバとして開発環境も作らないとなのでがんばるぞー。

え、開発環境はWindows? MacLinuxではない。。。? 動作環境はLinuxなのに? まあ、そうですよね。

でも、そんなのは慣れっこです。Vagrantを使う開発手順にしましょう(※1)。

サーバに上げないと開発できないとかツラいし、Cygwinとかで作ると細かい差で本番で死ぬからね!

という分けで基本的にはIDEで開発/テストをし、Bashを含んだような全体の動作確認はVagarantで。

共有フォルダを設定しとけばデータ連携もスムーズだし、chefやserverspecでSTG/PRD環境との互換性も保ちやすくて良いね!

※1 当時はDockerは出たばかりで仕事で使うにはちょっと。。。 な時代

ごめんね? 今日からあなたの開発環境はシンクライアントなの。

「みなさんに大事なお話があります」

偉い人は言いました。

「今日からみんなシンクライアント(VDI)! いいね?」

そして開発環境もVDIになりました。

「マウスを高速に動かすと画面がちらつく!」「キー入力にラグがある気がする!」

そんな声もありましたが、私はあまり気になりませんでした。

むしろ、元のマシンがHDDな残念な子だったので、SSDになったし画面も3日もすれば慣れたから問題は無いかな? という気分でした。

そう。Vagarantが動けばね!

夢の32bit OS

32bit OSをご存知でしょうか?

今までのシステムより圧倒的な大容量なメモリ。素晴らしいグラフィック。そしてセキュアで堅牢な作り。

時代の要請に答えて圧倒的に進化したOS、それが32bit OSです!

. . .

およそ25年ほど前の話なら、ね。

私は選択しました。Vagrant上で動かすシステムを32bitにすることを。

だって、VDIは仮想環境だからVT-Xが使えないんです。つまりVirtualBoxとか普通に使ってる仮想環境だとVT-Xの利用を前提にしてる64bitOSは動かない。

Nested Virtualization はなかなか難しいし。。。

幸いにして32bitでも必要なライブラリはそろいました。JavaがベースなのであまりOSレベルの差は気になりません。

というわけでゲストOSを64bitから32bitにダウングレードすることで妥協ラインに。

そう。。。いつ32bit版のライブラリが無くなるかという爆弾を抱えたまま、私たちは走り始めたのです。

マスター、一番いいのを頼む

困った。メモリが足りない。

JavaIDE立ち上げて、アプリケーションサーバ立ち上げて、DB立ち上げて、Excel立ち上げて、Chrome立ち上げてたら

4GBぽっちのメモリはすぐに枯渇してしまいます。

あと、CPUもたりない。

マルチスレッドでの性能向上の検証とか2コアでどうしろと。。。 サーバと開発機の性能が違いすぎるの困りもの。。。

困ったときは相談です。とりあずVDIの担当者に話に行きます。

「メモリ、増やせるよ?」

!? あなたは神か。。。 工夫とか特にしなくても問題解決☆ 富豪プログラマー万歳です。

というわけでCPUを8コアにメモリを16GBにとりあえず増やしてもらいました。

よし、普通に動く。自分だけだとあまり意味がないので、担当者と話して申請手順も整備、これでOK.

再起動しただけでメモリ増えるなんて、なんだVDI以外と出来る子じゃない。

先生…!! Dockerがでドヤ顔したいです……

やがて時は過ぎ環境構築の主流はVagarantからDockerに移っていきました。

自宅ではDockerで開発環境をいろいろ作り、便利さはある程度分かってきたつもりです。

そうなると、やはり仕事でも使いたいのが人情。でもVT-Xが使えない。。。

Dockerは基本的に64bit Linuxが、前提。無理すれば32bitでも作れそうな記事も見かけたけど、DockerHubとかのエコシステムにまったく乗れない。

ぜんぜん。。うれしく、ない。。。

virtualboxvmwareもVT-Xを前提に64bit化を実現します。32bitなら遅くてもVT-Xで動くのにこの格差は何なんだ。。。

そう思いながらもんもんとしていたある日、ふと閃きました。

Bochsqemuがあるじゃない!」

天啓でした。Android端末の上でWindowsを動かすことにしか最近使われてない気がするBochsqemuですが、KVMとか使わなければ「普通のアプリケーションとして」フルエミュレーションをするはずです。

さっそくダウンロードです。boot2dockerのISOも落としておきましょう。

$ 'C:\Program Files\qemu\qemu-img.exe' create -f qcow2 harddisk.qcow2 32G
$ "C:\Program Files\qemu\qemu-system-x86_64w.exe" -m 4G -cdrom boot2docker.iso -name boot2docker -drive file=harddisk.qcow2,media=disk,cache=writeback  -smp 2 -netdev user,id=user.0 -device e1000,netdev=user.0

動いた! 無事クジラさんが見えました! docker psやdocker runも打てるよ!

そして…

さて、無事にVT-Xが使えないシンクライアント上でもDockerが動くようになりました。圧倒的 進歩!

ただ、まだこれで終わりではありません。qemuって重いんです。知ってました?

これでどこまで現実的に開発に利用できるかは試してみるしかありません。

docker-machineとの連携も調べないといけません。genericsとかでやれば動くでしょうか? そもそもボリュームどうしましょう?

DockerRegistoryどうしようとか考えることは山盛りあります。

残念ながら、異世界開発環境で「おれつぇー」が出来るのはもう少し先のことになりそうです。

あとがき

さて、たんにdocker on qemu without VT-xが出来たので記事にしようと思ったら、何故かこんなものを書いてました。

夜勤明けにビール飲みながら見てるインターネッツは怖いですねー。

ゼロから始める魔法の書』を見ながら、ふとタイトルを思いたのが運の尽きですが、結果として出来たタイトルはどちらかというとリゼロなのが不思議です。

そのうち「docker on qemu without VT-x」関連を抜粋してQiitaに投稿しておきます。

それではHappy Hacking!

Oracle Exadataは分散システム?

はじめに

最近、Oracle Exadata/RACを触る機会がありました。

個人的にはOracle RAC自体まともに触るのが初めてだったので、お約束のキャッシュフィージョンを起こして性能が出なかったりとか、RAC初心者あるあるを起こしたりもしました。

その時に、ExadataやRACの公開情報をあらためて見てたのですが、Exadataは分散システムとして理解したほうがしっくりくるなぁ、という事に気付きチューニングもその観点を持ったほうが良い気がしたので、少しまとめてみました。

Oracle Exadataとは?

Exadataは簡単に言えばOracleが考えた「僕が考えた最強のRDB」です。

RDB製品としてトップクラスの実績を誇るOracle Databaseとそのクラスタ構成であるRAC(Real Application Clusters)をボトルネックなく最速で動かすための当代最速のマシンで組み上げたアプライアンスです。

各ノードはInfinibandという40Gbpsを誇る高速な回線で、TPC/UDPよりもオーバーヘッドが小さいRDMAを採用。ストレージもSSDマシマシでメモリもたくさん載せる。CPUは当然大量に。というRACボトルネックになりそうなところをキチンとつぶした構成になっています。

加えて、ソフトレベルで色々チューニングが施してあって、単に同じハードでOracle Database Enterprise Editionを実行するよりも数倍速いってのが特徴です。

購入はこちらから! って言ってこのURLがアフィリエイトだったら私がウハウハできる程度にはお高いのがネックでしょうか。

Exadata Database Machine | Oracle

まあ、Oracle Enterprise入れることを検討する程お金があるなら一考の余地はあるでしょうけど。あと、クラウドもあるみたい。

Oracle RAC(Real Application Clusters)とは?

Oracle RACOracle Databaseをクラスタリングし、性能と可用性を高めるための製品です。その最大の特徴はShared Everything.

MySQLPostgreSQLの良くあるクラスタと違ってストレージも共有してますし、キャッシュも共有しています。つまり計算するDBエンジンだけを分散化してるのが特徴です。

正直、2から数台程度のスケールだとこれが一番面倒は無さそうというのは納得です。ただ、後述する通り「厳密にはExadataの構成とは違う」ってのが注意点。

f:id:pascal256:20170326182338p:plain

ここでRACのポイントとなるのがASMとキャッシュ。ASMはAutomatic Storage Managementの略で、その名の通りストレージの自動管理をしてくれる仕組みみたい。大分誤解がありそうだけど自分の理解としてはDB特化型のソフトウェアストレージですね。

DBで直接ブロックデバイスを扱わずにソフト的な抽象レイヤーを作る事で、耐障害性をあげたりと色々な事をする機能。これがExadataでは大活躍します。

つづいてキャッシュだけど、これの注意点はすべてのDBサーバで共有されてるということ。

つまり良くあるmemcache的な分散型キャッシュシステムとして動いてるのではなく、Netflix Hollowみたいな散在型キャッシュシステムです。

この仕組みであれば参照時のローカリティが常に保たれるため効率的ですね。半面、書き込み時にキャッシュを共有する必要が出てきます。これがキャッシュフィージョンです。

通常は、キャッシュフィージョンのコストが参照時にキャッシュヒットせずにストレージアクセスするコストより小さいという分析から、こういう仕組みになってるのでしょう。

f:id:pascal256:20170326185057p:plain

当然、これが頻発すると性能が落ちます。特に同じキャッシュの場所を更新するとコンフリクトの解決が必要になるので目に見えて遅くなります。

私のようにRAC構成のOracleが分散システムであるという事を忘れてInsertをしまくると痛い目を見ます。ただ、解決方法もあってハッシュパーティションとかでDB上の更新箇所を散らしてやるのが効果的です。このあたりのチューニング方法は下記の記事が分かりやすかったです。

実はシンプル!RACチューニングの考え方(PDF)

ExadataとSmart Scan

Exadataの最大の特徴といえばSmart Scanでしょう。下記の記事が詳しいです。

Smart Scanを簡単に言ってしまえば「インデックスを張らずにフルスキャンをしても高速にレスポンスを返す」ための仕組みです。

どやってるかというと発想は単純で、ストレージサーバ側で簡易な検索を行いデータを小さくした後にDBサーバに返してDBサーバ側でJOINなど複雑な処理をする、というものです。

これによってInsert時のIndexにまつわるコストを大幅に下げつつ、性能を上げることが出来ます。

f:id:pascal256:20170326191604p:plain 引用: Oracle Exadataはなぜ速い?圧倒的なパフォーマンスの秘密を徹底解剖

データが大きくなればなるほどストレージからDBサーバにデータを持ってくる通信コストは無視できなくなりますし、分散してりるストレージサーバ上で処理すればビックデータに対しての性能が稼ぎやすくなります。

このあたりはHadoopGoogleのBigQueryと近しい思想だと思います。

さすがにPKとかでKey Valueで採ってこれるような処理よりは遅いみたいですが、バッチシステムとかだったら十分効果ありってのがOracle側の見解です。

さて、この辺のExadataの記事見てたら気づくと思うのですがRACの説明と大きく違うところがあります。そう、ストレージが1個じゃねーじゃん、と。

ExadataとRACと分散ストレージ

RACの特徴はShared Everythingでストレージが1つしかないことです。しかし、RACを採用してるはずのExadataの特徴は複数のストレージサーバに処理をオフロード出来ることです。この差は何でしょうか?

色々あるのですが「Exadataで動いてるシステムは厳密にはRACじゃない」と理解しておくのが一番楽そうです。RACをベースとした「クラスタシステム:Exadata」と思っとく方が無難ですね。

たしかに、RACはソフトウェアにすぎませんし、そこから見る単一のストレージシステムってのは「ASMで抽象化されたストレージ」くらいの意味しかないと思います。

その先がNASやSANであれば「個人向けのNASのようにハードディスクを直結した単一にぶら下がるストレージ」であろうが、「GlusterFSのような分散ストレージ」であろうがどちらであっても「単一のストレージ」です。OracleやEMCのNASやSANも中身が複数台で構成されてるってのは普通にあるでしょうし。

DBエンジン毎に違うストレージが刺さってないってのがポイントでしょう。Exadataはその構成上、分散ストレージになってると思いますがそれだけであればASMが頑張れば良いだけです。

ただ、SmartScanを考慮すると話が違います。どんなにASMが頑張ってSQL処理だけ特別な処理をするように透過的に要求を処理しても、selectの結果として返ってくるレコードの量が減ってるとかDBエンジン側でも考慮しないとストレージのバグとして処理される気がするんですよね。

このあたりは同じEngineered製品であるBig Data Applicanceと組み合わせた時の振る舞いが顕著です。

BDAにはOralce Big data SQLという面白い機能があって、これはExadataのSmartScanからExadataのストレージサーバのようにHadoop(Hive)を取り扱うものです。 f:id:pascal256:20170326194836p:plain

引用: Why Oracle Big Data SQL Potentially Solves a Big Issue with Hadoop Security

この際、OracleのDatabaseサーバ側からみると、ExadataのストレージサーバもBDAのHadoopノードのも等価として扱われるとのことです。

その意味でもSmartScanとそれにまつわる仕組みは単一ストレージとして考えず、分散システムとして考えた方がしっくりきます。

まとめ

Exadataはアプライアンスなので単一システムとして売られていますが、本質的には分散システムでありHDFSのような分散ストレージを使った製品であると理解したほうが良さそうです。

Netfix hollowHDFSに似てるところがあるからこんな感じの理解ですかね?

f:id:pascal256:20170326200907p:plain

こうしてみると商用RDBの最先端であるOracle DatabaseもAWS Auroraを始めとしたNewSQLと同じような方向性の進化を進めてることが良くわかります。

アプライアンスはハードウェアも込みでアーキテクチャが練られてるところが良いですね。

この辺はOracleがSunを買ったメリットの一つかなぁ。HPには災難だろうけど自社で完結するほうが良いよね。

それではHappy Hacking!

参考

いつのまにかGitのshallow cloneが”Push”も"Pull"もできるように超進化していたよ! すごーい!

流行りに乗ってフレンズ用語を活用しようと思って、タイトルで力尽きたブログはこちらです。

はじめに

不向きと言われながらもgitでGBを超える巨大リポジトリを取り扱うことはあります。 そんなときの強い味方が Shallow Clone

これは任意の世代だけを持ってくるので、どうせ滅多に参照しない1年以上前の履歴とか持ってくる必要がない便利な機能です。

なんですが、最近まで私の中では「shallow clone(笑)」な印象でした。

というのも、Gitのshallow cloneには制約が多く、fetchが出来ないのでputもpushも使えずせいぜいがCIサーバでのビルド時くらいだろうと思ってました。

実際、昔は出来なかったし今でもブログとかでも何だかんだで古いものがヒットするから、同じ印象だった人もそれなりにいるんじゃないかな? と思います。

Facebookが改造したというMercurialのshallow cloneはfetchが出来るので、うらやましく思ったものです。

www.infoq.com

でも、実は、Git 1.9から変わってた!。下記のAtlassianの記事でもさりげなく言及されてました。さりげなさすぎるよ!

japan.blogs.atlassian.com

blogs.atlassian.com

1.9が出た当時だから2014年以降のgitはshallow clone後もfetchが出来ますが、その結果どうなるかはあまり明言された記事も見つからなかったので確認してみました。

基本的なpushとpull

元になるリポジトリの作成

まずは検証用のリポジトリを作ります。

$ echo "# sandbox-git_shallow-clone" >> README.md
$ git init
$ git add README.md
$ git commit -m "first commit"
$ git remote add origin https://github.com/koduki/sandbox-git_shallow-clone.git
$ git push -u origin master

以降の作業が分かりやすいように全履歴をもつ通常のリポジトリfull-repoとしてcloneします。

$ git clone git@github.com:koduki/sandbox-git_shallow-clone.git full-repo
$ cd full-repo/

full-repoにいくつかcommitをしてみます。

$ touch history.txt
$ git add history.txt
$ echo "history1" >> history.txt
$ git commit -m "history commit 1 from full-repo" -a
$ echo "history2" >> history.txt
$ git commit -m "history commit 2 from full-repo" -a
$ echo "history3" >> history.txt
$ git commit -m "history commit 3 from full-repo" -a
$ git push

当たり前ですが下記のように履歴が出ています。

$ git log --pretty=oneline
7539bfe549690c037c172aec11c1b764424ee101 history commit 3 from full-repo
886bbd29a664c388473494af38689b362a7adf34 history commit 2 from full-repo
f8024e169867ca6c2ce3731ede8c2f87de8841da history commit 1 from full-repo
17404e2207096399f2e15a7176665dd62f5f4821 first commit

shallow cloneリポジトリの作成とPush

続いて検証のためにshallow cloneをdepth=2くらいで、shallo-repoとして作成します。

$ git clone --depth 2 git@github.com:koduki/sandbox-git_shallow-clone.git shallow-repo
$ cd shallow-repo
$ git log --pretty=oneline
7539bfe549690c037c172aec11c1b764424ee101 history commit 3 from full-repo
886bbd29a664c388473494af38689b362a7adf34 history commit 2 from full-repo

ちゃんと2世代分だけがとれたことが確認できました。ではshallow cloneした側でも同様に適当なcommitをしてみます。

$ echo "history4" >> history.txt
$ git commit -m "history commit 4 from shallow-repo" -a
$ echo "history5" >> history.txt
$ git commit -m "history commit 5 from shallow-repo" -a
$ git log --pretty=oneline
3f1dcc459ab3e105d0e10fba007e1beb693ab277 history commit 5 from shallow-repo
4a034d35a5893150308a9bd73d07370cd5dc971b history commit 4 from shallow-repo
7539bfe549690c037c172aec11c1b764424ee101 history commit 3 from full-repo
886bbd29a664c388473494af38689b362a7adf34 history commit 2 from full-repo
$ git push

とりあえず、エラーもなくPushもできました。

full-repoとshallow-repoでの相互のpull & push

では元の全履歴を持ったfull-repoでpullできるかを確認します。

$ cd ../full-repo/
$ git log --pretty=oneline -n1
7539bfe549690c037c172aec11c1b764424ee101 history commit 3 from full-repo
$ git pull
$ git log --pretty=oneline
3f1dcc459ab3e105d0e10fba007e1beb693ab277 history commit 5 from shallow-repo
4a034d35a5893150308a9bd73d07370cd5dc971b history commit 4 from shallow-repo
7539bfe549690c037c172aec11c1b764424ee101 history commit 3 from full-repo
886bbd29a664c388473494af38689b362a7adf34 history commit 2 from full-repo
f8024e169867ca6c2ce3731ede8c2f87de8841da history commit 1 from full-repo
17404e2207096399f2e15a7176665dd62f5f4821 first commit

pullする事で、ちゃんとshallow cloneした側のコミット内容が取り込まれましたね?

当たり前ですがshallow cloneした側の履歴で上書きされたりせず、元の履歴もきちんと保持しています。

念のため、全履歴を持つfull-repoからshallow-repoへの反映も確認します。

$ echo "history6" >> history.txt
$ git commit -m "history commit 6 from full-repo" -a
$ git push
$ cd ../shallow-repo
$ git pull
$ git log --pretty=oneline
e94867ec121d779cc234441cd9045fa03494d2e1 history commit 6 from full-repo
3f1dcc459ab3e105d0e10fba007e1beb693ab277 history commit 5 from shallow-repo
4a034d35a5893150308a9bd73d07370cd5dc971b history commit 4 from shallow-repo
7539bfe549690c037c172aec11c1b764424ee101 history commit 3 from full-repo
886bbd29a664c388473494af38689b362a7adf34 history commit 2 from full-repo

問題なくcommitが反映されてますね。相互にcommitしあっても何の問題も無さそうですね。これなら他のブランチの修正もmasterマージ後に取り込める

まとめ

今回はgitのshallow cloneについて検証をしました。

正直「これが出来たらなぁ」と思ってた機能が3年近く前から実装されてたのは衝撃ですが、これは中々に便利がよさそうなので活用していきたいです。

ちなみに私の手元の環境では数十分cloneにかかってたのがshallowだと数分になりました。たのしー

しかし「git 巨大リポジトリ 対処」とかで調べても昔の情報ばかり出てくるのは残念。

それではHappy Hacking!

レガシー分散システムからモダン分散システムへ

はじめに

Dockerは個人的には色々便利なんだけど、オンプレな本番環境に適用するメリットあるかな? とたまに思います。 Infrastructure as Codeは別な方法でも実現できますし。

Googleとかもコンテナは分散システムの基盤としてを重要視してるように感じるので、本番環境に適用する決め手はこっちかな、と思っています。

なので、今回は思考の整理に、近代的な分散システムってなんで要るんだっけ? というのをまとめてみました。

分散システムとは?

分散システムと聞くと何を思い浮かべますか? SparkやHadoopですか? それともUnixダウンサイジングですか?

この記事を見る人の多くは前者を思い浮かべると思うのですが、Wikipedia的には後者の意味で記載されています。

分散システム - Wikipedia

前者は分散コンピューティングとして扱われてますね。英語でも同じかどうかは調べてないですが。

エンタープライズ系の人だと後者もなじみ深いと思うのですが、ようはメインフレームの対義語です。 単一のマシンですべての業務をこなすメインフレームに対して、複数のマシンでそれぞれの業務をこなすのがレガシーな意味での分散システムですね。 つまり、現在私たちが触るほとんどのシステムは「分散システム」となります。このような業務(アプリ)毎に専用のマシンを使うアプローチを「レガシー分散システム」と呼びましょう。

対して、SparkやHadoopのような巨大なワークロードを複数のマシンで分散して実行するアプローチや、 docker-swarmやk8sやmesosのような多様なワークロードを複数のマシンで分散して実行するようなアプローチも分散システムと呼ぶこともあると思います。 このような複数のコンピューターリソースを束ね、業務(アプリ)毎に振り分けるアプローチを「モダン分散システム」と呼ぶことにします。 ちなみに、巨大なワークロードも究極的には多様なワークロードの一種でしかないので、今回は分散コンピューティングの話はあまりしません。

最近、Dockerをはじめとして「コンテナ!」「コンテナ!」と言っていますが、開発環境と本番環境をポータブルに行き来できる、ということ以外には「モダン分散システム」の作りやすさがあります。 必要なCPU数やメモリをコンテナに割り当てて、それを実行するのに必要なリソースをスケジューラで確保して、実体はプールしたマシンのどこかしますがあたかも単一のOS上で動いてるように見せかけます。 GoogleのBorgやKubernetes、Apache MesosApache Hadoop YARNはそのためのミドルウェアですし、IntelのRack-Scale-Design(旧Rack-Scale-Architecture)はそれを想定したハードウェアです。

なぜモダン分散システムが必要か?

なぜ、このような仕組みが必要になってきたかというと、CPUが十二分に速くなってきた事とCPUがこれ以上はあまり速くならない事です。

20年前、10年前にくらべてCPUはずいぶん速くなりました。1つのアプリケーションを走らせただけで通常はCPUが100%になることなどなく、ユーザからのリクエストや処理するデータがCPUに対して少なくてほとんど遊んでるマシンも珍しくありません。

また、フリーランチは終了しました。ムーアの法則は破れこれ以上CPUは単独では速くならないとも言われています。そのため、最近は1ソケットだろうとサーバ買えば少なくとも4コアは付いています。

シングルスレッドのアプリケーションだとOSが賢くスケジューリングしてくれるにしても効率的に稼働させるのは限度があります。

スマートな相乗り

こうした無駄なリソースを効率的に使うための方法があります。それは「相乗り」です。 1つのマシンで複数のアプリケーションを動かすことでサーバの利用効率を高め、マシン導入の手間も省く事ができるのでビジネス的にも大きなメリットがあります。

が、メリットがあるので使われてきましたが、相乗りは蛇蝎のごとく嫌われていました。曰く「片方のアプリケーションがリソースを使いすぎてもう片方も重くなる」「ポートが被る」「ファイルパスが被る」と運用上のリスクがたくさんあるからです。

これはすべて真実です。わたしも下記で書いてあるような作りこみをしない限りは「相乗り、ダメ、ゼッタイ」というスタンスです。

ただ、これは相乗りが悪いのじゃなくて、リソースが分離されてないからです。

例えば、ファイルパスやポートはjailでもかなりの部分綺麗に分離できます。テスト環境のような計算リソースの共有が許容されるレベルならこれで十分でしょう。

また、Dockerでも使われているcgroupsを使えばCPUやメモリも適切に隔離することができます。このような「スマートな相乗り」であれば、サーバリソースを効率的に使うための優れた方式です。

近年、vmwareとかの仮想化が流行っているのもこの「スマートな相乗り」を実現するための手法の一種だからです。

ワークロードの分散

一方で、これはまだ不十分です。アプリケーションで必要なリソースとタイミングはそれぞれ異なります。

CPUが2個ついたマシンが2台あったとして、何時にどのサーバでどのアプリケーションを動かすのが最適になるのかをJP1とかでスケジューリングできますか?

そういったことを考慮してジョブの依存を書くのは至難の業です。しかも、日によってワークロードが変わるかもしれません。

ひょっとすると今日はいつもよりサーバAで動かすジョブのデータが多くて、他のジョブはサーバBで動かしたほうが効率的かもしれません

ダイナミックな情報も必要なので、どのサーバで動かすのが適切かを人間が決めることは出来ません。なのでプーリングとスケジューラが必要です。

レガシー分散システムのように「業務Aを実行するサーバ」、あるいはそれに相乗りの要素を加えて「業務AとBを実行するサーバ」という概念を捨てます。

そうではなく「業務を実行するコンピュータリソースのプール」として管理します。例えば合計4個のvCPUプールとか。

あとは簡単ですね? vCPUの空き状況を見ながらタスクを振ればワークロードは分散されます。

こうすることで、サーバの使用率を最大化することが出来ます。これはサーバ費用と調達時間という2つのコストを削減できるのでビジネス的にもとても良いことです。

vmwareのような仮想化技術では「スマートな相乗り」までは実現できますが、仮想OSで動いてるシステムがレガシー分散システムだとワークロードの分散は出来ません。

でも、相乗りなんでしょ?

メリットは確かにありますが「相乗り」というリスクを犯してまで使うべきでしょうか?

もちろん「スマートな相乗り」であれば基本的に相乗りのデメリットは受けないのですが、そのスマートさを保証する機能自体のバグというリスクはあります。

私は使うべきだと思います。なぜなら、本質的にモダン分散システムは冗長構成だから。

1台のマシンで100個のリクエストを捌く構成より、10台のマシンで10リクエスト捌く方が機器障害やメンテナンス時のインパクトが小さいです。 まあ、これは前提として1台のハイスペックマシンだと意味がないので、ある程度ホストマシンも数をそろえておく必要はあるけど。

ダン分散システムへの移行は必須か?

ダン分散システムはサーバーの使用率を最大化することで、総体としてのサーバ費用と業務毎における調達時間を圧縮できるので、ビジネスメリットがあります。

でも、それだけなら移行する動機付けとしては弱くもあります。

まず、調達時間の圧縮は仮想で十分。サーバ費用に関しても仮想ならある程度割り当てるリソースの調整でベアメタルよりはマシになります。

なので、これが決定的な導入理由にはならないことも多そう。

ハードウェア費用ケチるより、利益を上げる作業をした方が儲かるビジネスモデルもあるしね。人のリソースは有限だから。

どちらかというと、Elasticにリソースをアプリケーションに割り当てれる運用性が価値になるかな。仮想だとOSの起動や停止から始まるのでトロいし。 この特性はバッチサーバ、特に並列処理とかに有用になりそう。SparkとDockerを同じリソーススケジューラで管理するとかが決め手かも。

あとは、昼と夜でリアルタイムとバッチ処理のワークロードが逆転するとかのケースにも使いやすいかな。これもOSの上げ下げとかしてると面倒だし。

運用面でも、OS単位じゃなくてアプリケーション単位でリソースがモニタリングしやすくなるので、慣れると楽そう。

いずれにしても、「移行」という観点では「今すぐ移行するべき!」と強い言葉を使うほどじゃないかな? はまりそうなユースケースでは使うべきだし、ゼロから設計するなら構築したいけど。

あと、当然だけどサーバーが大量にあってコストを圧迫してるなら検討するべき。

どちらかというと、こういうモダンなシステムを導入するにあたっての、運用や構成の見直しが一番のメリットになるといういつものパターンな気もする。

マイクロサービスとかCDとかもそうだけど、実現しようとするといろんな要素をクリアしなくちゃいけなくて、結果として前提条件をクリアすることで効果が出るというパターン。。。

まとめ

最近、もやもやっとすることをとりあえず文章にして形にしてみました。突込みや指摘をお待ちしております。

移行は必須か? のところが相当整理されてない感じがにじみ出てますが、実際どうだろうなー、というのが正直なところ。 まあ、結論が出せる程理解してないからこんな記事書いてるのだし。

ちなみにクラウドベンダーやGoogleのような巨大インフラを持ってる会社は 運用してるサーバの数が馬鹿にならないだろうから、こういうのに積極的なのだと思う。

参考