転職エージェントについて

さて先日いくつかの転職エージェントと接触したので、その経緯や結末をうまくボカしつつここに記しておくことにする。日曜の午後のヒマつぶしになると幸いである。

2015-11-08 19.07.55

狭い業界、知り合いの方が多いのだがなぜ転職エージェントにアクセスしてみようと思ったかというと、実は世間は広くて、私の知らない面白いことをやっている会社が沢山あるのではないかとふと不安に駆られたからだ。このままでは大海を知るためには、結局アメリカや欧州へ渡るしかなくなってしまう。このままでは拙い。酔っていたせいでもある。ある日思い立って、Gmailを "Opportunities" とかそういうので検索しまくって、適当にメールをいくつかのエージェントに送った。夜中に酔った勢いで書いたものだから、短く簡潔で素晴らしいメールになった。

Thank you for reaching out to me. I'm getting more interested now, could you give me more detailed job descriptions and the company goal?
Thanks,

以下のことは時系列に起きていたわけではなく、並列に起きていたのだけど、本当のことをいうと実はフィクションです。全部ウソなので真に受けないでね。

I社 S君

メールに返事があって、電話。電話口ですぐに名前が出てきたのはA社だが、そこは個人的なブラックリストであったので無条件でお断りした。次にF社を持ってきたがそちらも私も興味のあるところではないし、エンジニアとしての私の能力が伸びることも生きることもなさそうな職場であったのでお断りした。S君は流暢な英語で、会話している分には不快なことはまったくなかったし、何より話が速かった。が、よい案件がなかったので自然消滅。

後日そのF社に尊敬する某S氏が転職していったのを見て、もうちょっと話を聞いておけばよかったと若干の後悔はあるが、やっぱりあそこにいっても合わなそうな気がするので関係ないか。

P社 A君

こちらもメールに返事があって、いちど電話してからオフィスを訪問した。スーツ族が行き交う都心の雑居ビルであった。まずは自己紹介を受け、彼がいかに業界で能力がありすばらしいかを聞かされる。そしてセールストークだ。日本人で英語慣れしていない人間を相手にしてきたのだろうか、ゆっくりと諭すように話してくる。曰く転職活動をエージェントを介さずにやってもよいが、そのときの問題点がひとつある。入社してからの良好な関係を維持するために、サラリーの交渉のときに強く出れないことが問題で、エージェントを間に挟めば我々が強気でやるから、あなたのためになるというものだ。だから、あなたは我々の大船に是非とも乗っかってほしい。( ´_ゝ`)フーン。

さて次はインタビューである。わたしのレジュメに赤を入れながら、どんな仕事をしてきて、どんなプログラミング言語ツールを扱うことができるかを聞かれる。ここで私は分散システムが得意だというが、これを理解するエージェントはまあほぼ0なわけだが、彼もその例にもれなかった。そのときはフンフンと彼も聞き入ってるフリをしたのだが…そして希望年収、現在の年収、生年月日を尋ねてくる。おいおいそんなこと聞いてどうすんだよ、まあ機密でもないから教えるけどさ、ふつう聞かないよね? …卓上をみると、わたしが自分で作ったレジュメをその会社のMSワードフォーマットにそのままコピペしたものを彼は印刷して持っていた。そこに年収と生年月日を書き込んでいく。おいおい聞かれたから答えたが余計なことしてくれるなよ。このあたりで急速にわたしのかすかな希望は嘆息に変わっていく。

そのあといくつかの会社の名前を一枚紙と共に紹介し、どんな会社で、どういう言語を使っているかを1社あたり3分ほどで説明してくれる。仕方がないので2,3社ほど選んでよろしくというと、彼がアプライしておいてくれるようだ。

そのあと日本人の男性が交代で出てきて、彼が担当している日系の会社も同様に紹介してくれる。そちらも2社ほど選んでコンタクトを頼んでおく。

しばらくすると、そのうちの1社から「アプライしたのでここからプロセスを進めてね」という自動送信のメールが届く。そこには、エージェントわたしの年齢、当時の年収と共に、そしてA君が書いたと思われる3行ほどのクソみたいな自己紹介文が掲載されていた。曰くマネージメントもできて、以前は最新テクノロジーの開発をしていて、ミドルウェア開発に強みを持っているエッジのあるエンジニアなんだそうだ。

そのことについて、これ以上のエージェンシーのお断りと共に窘めるメールを送ったところ、「もう進行中の案件があるんだがそれはどうするんだ」的な返事のみで、特に私が怒っていることについてコメントはいただけなかった。

A社 K君

メールに返事があって、いちどオフィスを訪問したがK君は不在で、その部下と話をしたらまあまあ話がもりあがる。そしてやはり年収と生年月日を聞かれる。希望年収も伝えておく。その後K君とも電話で話す。K君も流暢な英語で話が速い。まずは1社紹介してもらい渋谷に行く。話が盛り上がって、とてもよい面接だったのでK君とその旨話す。しばらく間を置いて、わたしが転職先を決めてから、次の面接をセッティングされる。わたしはもうオファーがあって、次の会社を決めたんだよーと言うと、曰く「まあまあ、ちょっと話だけでも聞きに行ってくれないか、時間のある日を教えてくれよ」という。彼は好印象だったし、その会社は若干興味もあるところだったので話を聞きに行ってみることにした。面接自体は和やかに進んだものの、面接をした社員が手にもっていたのが、やはり彼らのフォーマットで簡略化された私のレジュメだった。しかも、そこには私の生年月日がしっかりと書かれており、非常に裏切られた気持ちになったのであった。

面接自体は、お互いを紹介し、いくつか質疑をして、もう次の会社を決めていることを伝えて和やかに終わった。そのあと渋谷で友人たちと楽しく酒を飲んだ。

4月になって、新しい職場で働いているときにここの別の人間から昼間に携帯に電話がかかってきていきなり英語でまくし立ててきたので、電話メインの考え方をした人たちだということだ。

所属不明 H君

いちど電話してみるも、A社、H社、M社など典型的なところしか出してこないのでお断り。やだなあ、いまさらそういうもんでもないでしょう。


さて日本語でアクセスしてきたエージェントもいくつかあったので、そちらも書いておこう。

S社 M氏 "未公開案件"

Linkedinにもメッセージがたまに来るが、そこに「未公開案件」と書かれては飛びつくしかない。勢いこんで訪問してみたところ、やはり日本人だった。M氏は女性であるが実際に出てきたのは別の男性であった。実際に出てきた未公開案件はまあ、未公開とはいわぬお粗末なものであった。Z社の求人でインターネットを検索したら一発で出てきた。要求されるスキルも私が持っているものに近いし給与もかなりはずむという主張であったが思っていたよりも高くなかったし、諸事情でお断りした。

T氏

さて、このようにエージェントに沢山接触しているとどうなるかというと、噂が広まるようだ。具体的にはA君にお断りのメールを送ったタイミングが怪しいのだが、急に沢山の首狩りメールが届くようになった。そんな中で目についたのが、5年ほど前にいちど会った日本人エージェントだ。「まずあなたはキャリア目標を持つべきだ。20年後にどうなっていたいかを書いて、そこから逆算して今するべきことを決めよう」といった旨のことを偉そうにドヤ顔で述べていた。当時所属していた会社の研修で同じような話を聞いていただけに退屈な説教であった。その日のうちに具体的な会社の名前が出ることはなかった。

まとめ

  • 実際にエージェントと会うと年収や生年月日を聞かれる。日本では違法ではないが、それが先方に書面で伝わる。
  • レジュメの書き方を指導されるでもなく、彼らのフォーマットに勝手に書き換えられ要約され提出される。
  • 実際に会ってみてどんなにイイ奴だとか信用できそうだとか思っても、結局はジュッパヒトカラゲの商品として大切に扱われるわけだ。そこには、テレビなどで見かけるスポーツ選手とエージェントのような信頼感はない。
  • ペットショップに並んでいる動物みたいだった自分を鑑みて最低な気分だった。

101ND610-DSC_2906

長時間作業するための快適そうなキーボードまとめ

学生時代は大学の情報センターにHHKBが常備され、研究室でも HHKB Pro2 をずっと使っていた。前職時代に手首に違和感を感じたこともあったが、今の職場で同僚が Kinesis を使っていたので 在宅勤務環境を整備した - kuenishi's blog の際に私も Kinesis を使うことにした。私自身特に肩凝りで悩んだことはなかったのだが、これで随分ラクになったものだ(騒音は大きくなったが)。さて山口君が ErgoDoxを購入して人生がバラ色になった - YAMAGUCHI::weblog のを皮切りに、某所で多くのキーボードが取り上げられた。私自身次のキーボードを買うまでに覚えておけるわけがないので、ここにそれをまとめておくことにする。

私自身は打鍵感に特に拘りはなくて、肩がある程度開くようになっていればそれなりに満足して使える。プログラムを書くことは多いけど、文字をタイプするよりも考える時間の方が長いので大して問題じゃない(頭が悪いともいう)。

ここに載ってないもので「これはすげーよ!」っていうエルゴノミクス重視な(できればUS配列の)キーボードがあったら是非おしえてください。

HHKB Pro2 Type-S

Happy Hacking Keyboard | HHKB Professional2 Type-S | PFU の初期モデルはあの和田英一先生がシンプルで最小、余計なものがついてない、プログラムを書きやすいキーボードがほしいと構想したものをPFUが商品化したものだ。Emacsenらしく、CtrlキーがAの横についてるのが非常によい。定番だけど、小さすぎて手首も肩も肩甲骨もヘンな状態になるので、実は長時間の作業には向いていない。それでもType-Sの静音化はすばらしくて、前職時代にこれがほしかったなーという一品である。

Kinesis

www.kinesis-ergo.com

わりと有名なやつ。これで手首は非常にラクになったのだが、場所とるし、けっこう打鍵音がうるさい。

Kinesis Freestyle

www.edikun.co.jp

実は前職の最後の方はこれをちょっと使っていた。ポジションも好きなところにおけて素晴らしかった。打鍵音も静かだ。ただちょっと手応えがない割に深さがあって、あまり沢山タイプするとちょっと疲れる感じはあった。

ErgoDox

Community Blog - 握力王 vs 日本男児 ヘルシーすぎるプログラマ対談(Part1) で日本男児氏がその名を知らしめたといっていい(私はまったく知らなかった)。セパレート式で、全てのキーがプログラマブルファームウェアもフリーウェアなので自分で書き換えて好きなように挙動を変更できるもののようだ。大抵のキーボードは中身が分からなくて、OSでゴニョって自分のキー配置に変えることができるが、簡単なキーマップ変更くらいしかできなかった。しかしコイツは違うようで、もともとはオープンソース?のプロジェクトだったらしくもっと複雑な挙動を組み込むことができるようだ。

もともとは部品のキット売りですらなく、キットを組み立てて売ってくれるようになったのは最近のことらしい。

www.indiegogo.com

TEX Yoda

d6ms.hatenablog.jp

ThinkPadに慣れ親しんだ人はよさそう。

Black Pawn

www.century.co.jp

む、こだわりはよいけど、JIS配列しかないのか…

Keyboradio

shop.keyboard.io

親指にキーが重点配置されててよい。

Ultimate Hacking Keyboard

www.crowdsupply.com

Kickstarter的なやつでFunding中らしい。

Stellar Consensus Protocol

筑波大の川島さんに教えてもらって読んだ論文 The Stellar Consensus Protocol:
A Federated Model for Internet-level Consensus
がけっこう面白いので、紹介しようと思う。
32ページの長文で証明つきなのでガッツリ読み込めたわけではないのだけども。。。

Security Council Votes Unanimously to Increase Humanitarian Aid in Syria

背景

Bitcoinを始めとする電子貨幣(暗号貨幣)のブームは大きな投資を呼び込んで市場を開拓しつつある。またBitcoinの署名チェーンの部分のみを応用して、チェーンの合意を独自に構築する類似技術や製品をブロックチェーンと呼んだりする。私の理解だと、いずれもProof of WorkやProof of stakeの部分が難しい。PoWだと必要以上にアナーキーで時間がかかり、やたらCPUを食ってエコではないし、PoSでは結局は既存貨幣と同様に権威による認証が必要になることが問題だ。
既存のByzantine Agreementのアルゴリズムもいくつかあるが、どれも参加ノードが基本的には固定で、「誰が参加してもよいか」というのを中央集権的に管理しなければならない。そしてそれは昨今の暗号貨幣のように、いろんなピアが自由に参加できなければならないオープンなネットワークで使うことはできない。

そこでStellarというプロジェクトでは、異なるアプローチをとって電子貨幣(暗号貨幣)のエコで安全な流通を目指す。Lumenという貨幣はすでに沢山発行されているようだ。

www.stellar.org

その中心になるのが SCP (Stellar Consensus Protocol) で、 FBAS (Federated Byzantine Agreement Algorithm) というやつに分類される。分散合意の説明のために分散台帳の基本部分は論文では省略されているが、おそらくはPeer間のブロックチェーンの合意アルゴリズムの実装に使われていると思われる。

概要

ここまで説明してもうほとんど満足してしまったが、論文自体は実装よりも理論を重視していて、証明や記述がしっかりしている。SCPの基本的なConstructionが論文の大部分を占めている。前提としては、非同期通信で故障、復帰、遅延もあり、悪意のあるノードが矛盾する提案を投げてくる世界。

ノードの集合をQuorum Sliceという重複を許した部分集合に分けてQuorumをとって、そのQuorum内で3Phaseプロトコルを動かすようにすると、ピア同士の与信がネットワーク状に連鎖して、結果的に悪いヤツが少数派になるようになっている。細かい話はうまく理解できている自信がないが…ここから先が気になる人は論文をみてほしい。ちなみにノードの実装も公開されているので、おそらくピアとして参加することもできるだろう。

個人的には、こちらの貨幣の方がかなりクリーンに作ってるようにみえるので、Bitcoinよりもこっちが普及してほしい。

分散プログラミングモデルおよびデザインパターン

同名の某記事について。僕がタイトルから想像する期待を、なんだか意外な方向に裏切ってくれた記事であった。批判するだけではよくないので、同じタイトルで僕ならどういう話になるか…という話をしよう。絵のない長文だ覚悟して読め(ΦωΦ)フフフ…。

Are You There?

分散プログラミングモデル

プログラミングモデルとはなんであろうか。

…CもJavaもMPIも登場していない1972年の論文を持ってこられてそれがオリジナルだみたいなこと言われてもえー…って感じで、Flynnの1972年の論文は並列計算やHPCの方面へ非常に大きな影響を与えていると思う。ただしそれはCPU内の話であって、時代が進むと共にたとえば牧野先生の日記「並列計算機のプログラミングモデル」で書かれているような議論につながるといえば繋がるには繋がるが、このレベルで計算を並列化する議論にしか応用できない。せいぜい、プログラミングモデルとひとくちにいっても様々な階層があって、» ヘテロジニアスとメニーコアのプログラミング・モデルで書かれているように

大規模な並列計算機資源を利用するための重大な課題は、システム・ソフトウェア・スタックによって効率的な実装を可能にしながら、ノード内のハードウェア資源の全てを利用するために、必要とされる並列性のレベルの実現を促進するような、プログラミング・モデルの提供である。ノード・レベルの並列モデルには、CPUとSMPのための、pthreads、C++11 threads、Boost thread libraryのようなスレッド・プリミティブ、NVIDIA専用のCUDAやオープン・スタンダードOpenCLのような、アクセラレーター用の低水準のもの、高水準でディレクティブに基づくOpenMPとGPUアクセラレーターのサポートから始まったOpenACC、Windows上でのC++開発環境であるMicrosoft Visual C++による並列プログラミング、他には、Cilkplus、TBB、vectorプリミティブのような選択肢がある。

といえる程度だ。スレッドやセマフォといったもう一段抽象化したプリミティブも組み合わせて様々なやりかたがあって、それらをある程度網羅していないとプログラミングモデルを論じたことにはならない。さらにいえば、こういった並列計算とかHPCといった枠組みをナイーブに分散システムの世界に持ってくることはできない。

そもそも分散システムと並列計算の世界は似たようでいて全く違う問題を解いている。分散プログラミングモデルといったときに、この「分散」はどちらの意味か確認した方がよい。一般に分散システムというとNancy LynchのMITの講義で取り上げられているような、異なる故障単位をいかに並べてコンピューターとして協調動作させるか、もっというと合意するか、故障耐性をどう保障するかという問題の定義とその解法のことを指す。計算のパフォーマンスの話にはならない *1 。なのでSIMDの話とかはほとんど関係ない。

そしてこれは、通信が非同期である、さまざまな故障が起きるといった点で並列計算の世界とは根本的に違う。並列計算の世界では基本的に「この命令は何クロックで完了する」「CPU内のどこかのモジュールで故障があったら丸ごと落ちる」「他のノードが死んたらX秒以内に検出できる」といったことを前提にできて、非同期性や故障に関してはかなり問題を単純できている(と思う、詳しいことはちょっと分からないです識者求む)。ところが分散システムの研究では、そういった非同期性と故障の双方が起こりうる世界でどうやってシステム全体の正しさを保証するかという問題に取り組む。

また、共有メモリモデルが分散システムの世界で出てくることはほとんどない。わたしが知ってる唯一のよい例はOracle RACのvotingなのだけど、それも実際はRAIDのディスクアレイ上にデータがのるので、ディスクアレイの中では基本的に同じ問題があって、それはハードウェアとかファームウェアの中で問題が解かれているわけだ(故障や非同期性の問題はある程度緩和できると思うけど)。なぜ共有メモリモデルの話がほとんどないかというと、クラウド的分散システムの世界ではShared Nothingが大前提だからだ。そもそも共有ナンたらがなくてコスパの高いPCサーバーを横に並べて構築するのが基本なわけで、非同期なメッセージパッシングを故障しうるノード間で実施するのが大前提。というわけで、共有メモリかメッセージパッシングのどちらに分類できるか、という議論には意味がない。

これがどうプログラミングモデルに影響するかって?並列計算とかふつうのプログラミング言語の世界だと、プログラムが最初から最後まで順番に進めばそれで終わりで、その中で関数型とかオブジェクト指向といった言語仕様の設計から、どうやってCache Obviousなコードを表現するかとか、並列で動くCPU間の通信をどう効率化するかといったことが問題になる。…が、そもそも通信相手が生きてるかどうかも不明なので、通信が届いているかどうか、いつになった返事がくるか、それどころか、もしかしたら先方での処理は終わってて返事が通信路で詰まっているのかもしれない。もしかしたら自分だけ仲間はずれで、他のノードはみんな仲良く協調してるかもしれない。そういうときにどういう風に動作すればよいかは自明じゃない。

よくある話だと、Master-slaveなアーキテクチャを組んでるときにMasterがStop-the-worldなGCをして固まってたらSlaveはMasterが死んだと思って自動的にMasterに昇格するんだけど、同じタイミングでMasterのGCが終わってMasterが2人いてそれぞれが矛盾する動作をして…といったときには、いわゆる並列計算の世界のアルゴリズムを持ち込んでも問題は解けない。

この辺りの文献をよくまとめている記事がReadings in distributed systemsだったり、PWLのdistributed systemsのディレクトリだったりする。

プログラミングモデルについては2通りの話がある。ここまで述べたような、分散システムをから作るためのプログラミングモデルと、分散システムので計算を表現するためのプログラミングモデルだ。

前者はUCBのグループがここ10年くらい先端を走っていて、 Overlog, Datalog, Bloom, Boom といったいろんなプログラミングモデルとその実装を出している。これらの言語は非同期性、メッセージの到達遅延、Interleaving、ブロードキャストなどを上手く記述できるようになっているらしい。で、 Dedalus *2 の最後に載っているサーベイはこのあたりのプログラミングモデルをよく網羅していると思う。この流れは実用化にうまくたどり着いていないけど、成功してほしいなあ。。。なぜなら、近年の実用的な分散システムのソフトウェアはほとんどが Java, C++, Go といったパフォーマンスの高い言語または処理系で実装されているためである。運用ノウハウも沢山あるし、多少苦労しても細部(特に非同期やIOまわり)をうまく設計、実装するためには仕方がないというのが実情かな。

後者は、Strong Consistencyが保障されるような場所だったら、みんなが知ってるように特別なプログラミングモデルはあまりなくて

  1. MapReduceやSparkのように、APIに合わせてコードを抽象化
  2. SawzallやPigのようなベタ書き独自言語
  3. Hive, Impala などNewSQLやSQL-like言語
  4. CEPとかストリーム処理のCQL

で処理を記述することがほとんどだ。問題を分割統治して、分割と統治をどういうプリミティブで見せるかが腕の見せどころになる。これらの始祖は全てMapReduceと言って差し支えないくらいで、耐故障性と性能の両立を冪等性&投機実行で力技で解決できることを示したのは本当にすごいと思う。上がわの言語とかのプログラミングモデルが、宣言的な言語仕様だったり、冪等性に気をつけるように強制するのはこのためだ。分散システムとプログラミングモデルが関係するのはここだと思う。SIMDがどうとかはほとんど関係なくて、それよりもいかに分散システムの下回り(非同期、効率性、耐故障性)を上手く抽象化したり隠蔽できるかどうかがコツだ。もうちょっというと、バッチ系のSQL-familyとリアルタイム系のCQL-familyが統合されようとしてるのが最近の流れで、 ClouderaとGoogleの協業なんかは関係者は固唾を呑んでウォッチしているはずだ。

このあたりが私の知っている分散プログラミングモデルなのだが、 はてはて…

(たぶん分散システムの)デザインパターン

うーん、こっちの話は…ひとくちに分散といっても、スケールアウトするための分散と可用性を確保するための分散でやることが多少違うんだけど…とりあえずそれ以前の話として。ちなみに↑の話は後者ね。

ハコを線で結んでポンチ絵を書くときはだいたいハコがサーバーとかノードとかプロセスで、線はそれらをつなぐ通信路だったり実際の通信の実態だったりするわけだが、その通信の実体は大きくみっつに分けられる。

  1. 相手が生きてるかどうか知るための死活監視を担うメンバーシップ系の通信
  2. 実際の分散システムがなす仕事のためのデータをやり取りする通信
  3. 実際の分散システムがなす仕事のためのコントロール系の命令をやり取りする通信

これら通信が描くトポロジーは、同じ場合もあるし全然違う場合もある。たとえばHBaseなんかは、メンバーシップ系通信は全部ZooKeeper経由で、データのやり取りはRegionサーバー同士でしかおきない。コントロール系の命令はMasterとRegionサーバー間でしか起きない *3 。マルバツ表作って分類するのは結構だけど、現実はもっと複雑で中身を個別に論じないと分からないと思うんだよね。Kafkaは、いわゆるメッセージキュー的な仕事をするけど、メンバーシップ系の話はZooKeeper抜きにはやっていけない。 SparkもScalaでデータフローを記述できるようになってるけど、ステージ毎のRDD配置の流れは自明じゃない(最適化の余地がある)はずだし、全体を管理するMasterとWorkerに分かれている。だいたいMesosだってMasterとWorkerに分かれるけど死活監視とかメタデータ置き場にはZooKeeperを使っているし…このあたりの複雑さをうまくパターン化するのは難しいので、無理にパターン化するとしても個別に実例つけないと説得力はあまりない。

で、データをやりとりする通信のところはパフォーマンスに大きく影響するので、いくつかパターンがある。

  1. Push型: データを送る方が、受け取る方のバッファに書き込む
  2. Pull型: データを受け取る方が、準備ができたら送る方のバッファから取り出す

それぞれ Pros/Consがあって、一般的にはたとえば前者だとレイテンシは向上するけどうまく制御しないと受け取る側のバッファがすぐ溢れるし、後者だとその逆になって受け取る方が詰まったらさあタイヘン…でさらにバルクでやり取りするかどうかでスループットとレイテンシのトレードオフがある。到達性保証の選択肢も At least once / At most once / Exactly once があって、耐障害性も考えると設計の複雑さとパフォーマンスと保証レベルとのトレードオフになって、上側のアプリも含めてどう設計するか、どれを採用するかというのがこれまた腕の見せどころになる。このあたり正解はなくて、それは古橋くんのブログ記事を見るとゥゲゲゲ奥が深いっすね…みたいな話になる。

あとデザインパターンとしては、Consistent Hashingを使って水平分散するパターンと、真面目に連続したキーを使ってシャーディングするパターンの二通りがあって、スケールアウトする系のシステムはだいたいどっちかに分類できる(両方できるヤツもいる)。いわゆるP2P系といわれるシステムは前者が多い。そういうの関係なく適当に配置するやつもいる。MesosとかHDFSとか、主キーみたいなのがないヤツがそれに相当する。

ちなみにRiakはどうなってるかというと…あれ、誰もきいてないかorz

まとめ

よくまとまっているとはお世辞にも言えないが、分散システムにおけるプログラミングモデルと、分散システムのデザインパターンの概要を解説した。プログラミングモデルは、分散システムを構築するためのものと、分散システム上でのデータ処理とかを記述するためのものに大きく分かれる。前者の知識は非常にニッチなもので、我々が専らよく触れるのはこれからは後者になるだろう。分散システムのデザインパターンは、まあハコと線と表だけで分かるもんじゃねーと思うなあ難しいし正解はないなあ、という話でした。

(追記)SOJのこちらの質問もウォッチしておきたいところ

*1: 計算量の話はあまり出ない

*2: http://db.cs.berkeley.edu/papers/datalog2011-dedalus.pdf

*3:基本設計はそうなはずで、最近なんか変わってたら教えて下さい

クラウド時代の分散データベースを支える技術の応用と進歩

Powered by teespring
teespring.com

分散データベースというのは、それ単体でもとても難しい、データベースと、分散システム双方の技術の粋を結集して実現されるアプリケーションだ。これをサービスといったり、ミドルウェアといったりする場合もあるが、今回は技術を応用してつくったものという意図でアプリケーションと位置づけることにする。まあ古くて新しい問題で、死屍累々の世界でありながら、それでいて金の鉱脈でもある世界だ。イカのようなトピックを概説していくことで、近年の流れをメモしておきたい。

  • Pre-cloud era: クラウド以前の時代
  • BigTable, DynamoとCAP定理
  • MegaStore
  • 研究: Calvin
  • Jepsen: できたら☎してよ〜
  • Coordination free database
  • Spanner: 何でもできるよ!!
  • Kudu+Impala
  • Next?

クラウド以前の時代

System RとかいわゆるRDBMSがあって、いろんな分散データベースがあった(らしい)。分散といってもふたつの目的があって、ひとつは耐障害性。もうひとつはスケーラビリティなんだけど、前者は必須要件でもあるわけ(メディア故障でデータが消えたら意味ない)だし枯れた実装もいくつかでてきた(CAP定理の範囲内で)。後者はまあぶっちゃけそんなに必要なかったり、テーブル分割なりスケールアップなりでみんなしのいできた。

今でもそうかもしれないけど、データベースといえばACIDでトランザクションがないと意味がないという考えがあって、分散トランザクションの難しさもあって、そこまで研究は進んでいなかった。まあ皆さん知ってる歴史だと思う。

BigTableとDynamo

BigTable *1 の登場は、 MapReduceとGFSの登場ほどのインパクトはすぐにはなかったが、Dynamo *2 の登場とあわせてジワジワとみんなを驚かせることになる。この2つは、まあよく知られている通り、いわゆるデータの整合性保証が不要で、ダウンタイムやスケールアウトの方が重要なユースケースが存在することが分かって、世間にインパクトを与えた。それまで「トラザクションがなきゃDBMSとしては認められない」と鼻高々だったDBの研究コミュニティが驚きひれ伏したわけだ。

注意しておきたいのは、BigTableとDynamoが切り捨てた整合性はそれぞれ別のものであるということだ。前者の整合性は、いわゆる伝統的なACIDの定義の中での整合性で、複数レコードや複数テーブル間の制約に関する整合性だ。もちろんインデックスも含む。
後者の整合性はそれ以前の話で、CAP定理の定義 *3 の中での整合性である。こちらはAtomic Objectと定理中で定義されているもの(NoSQLだとひとつのキーと値のペアだったり、いわゆるタプルのことだったりする)についてで、要は複製どうしの整合性についての話だ。

データモデルについても両者は新しい。どちらもリレーショナルモデルではなく独自のデータモデルだ。前者はいわゆるカラム指向ストアに分類されるが、それは「カラムを無限に追加できる」という意味であって、垂直分割したから高速だとかそういう話は本質ではない。正規化なんてまあ夢のまた夢であるし、結合とかその手のリレーショナル演算はあまり現実的じゃない。Dynamoはまあ…その…シンプルですわね、よいねえという。

このあと市井に出てくる分散データベースのほぼ全ての要素技術は、このBigTableとDynamoが持っている機能、データモデル、性質の組み合わせで説明できる。

MegaStore (とDynamoDB)

HadoopとかHBaseなんかが出てきて数年経って「やっぱりトランザクションもSQLも使えないのつらいわー」というのが世間のおおまかな合意になってきたころに登場したのがMegaStore *4 と DynamoDB *5 だ。
MegaStoreは、複数Row間のアトミックな更新ができるようになっていた。DynamoDBは中で使われている技術の詳細が明らかになっていない。しかしながら、まったく根拠がない謎の伝聞によると、BigTableは1DC内くらいの規模でしかスケールアウトしないしMegaStoreは遅いと言われていたし、DynamoDBは「EBSを使っていないから速いんだ」と言われていたようだ。つまりものすごい新技術が使われているわけではなく実装と運用を頑張っていたのだろうと想像される。

その頃アカデミックでは…

もちろんアカデミックは一歩先行く世界なので泥臭いところには拘泥しないが、いわゆる新しいワークロードが出てきたことで、まあ分散したデータベースは当たり前になってきて、研究としてのインパクトは少なくなった。いろんな技術が提案されたけど、実世界のワークロードで試されたものは少なくて実用化されて残ったものはほとんどなかった。Calvin *6はその中のひとつで、トランザクションはやはり難しいことが分かる *7

というか、20世紀の時点で研究だけがかなり先行していて、できることはやり尽くされていたと思う。たとえば2PCとPaxosが本質的には同じで、前者は後者の特殊ケースであることが示されていて *8 、アカデミックとしては耐える時代だったなと今になって思う。

分散システムの難しさ

分散データベースのトランザクションの難しさは(分散トランザクションではない)、分散システムの本質的な非同期性と故障の存在にあるけど、その正しさを検証する方法がない難しさも大きい。フォーマルな検証であればいくつか技術があるらしい。SPINとか、TLA+ *9とか。のだけど、これの問題は、フォーマルな記述と、実装の泥臭いところまで含めてギャップが出ることを防げないところにある。形式的な定義から実装を吐くようなコンパイラ的なものがあればよいとは思うけど、それはまだちゃんと実用化されていない。TLA+は発展版として IronFleet *10 が登場したらしいので要チェックやで。

21世紀になってからようやく現実的なツールがいくつか登場してきた。最初はJepsen *11 だ。これは主にデータベースのレプリケーションの正しさをテストするためのツールだ。 iptables を使ってネットワーク分断を人為的に起こしながらデータの正しさを検証していくことができる。実際に多くのデータベースがこれでテストされ、いくつかクリティカルなバグが見つかった。初期のJepsenが強かったのは主にCausalityのチェックで、Causal Consistencyや、CAS的な「書いたはずのデータが暗黙に上書きされて消えてないか」のチェックだった。いまのJepsenはさらに改良されていて、CAS的なAPIがないデータベースでもデータの変遷可能性を観測されたデータから組み合わせ計算して推測し、ありえない変遷を辿った場合にはレプリケーションが壊れていると断定することがでdきる。

Coordination Avoidance

この「一回読んだデータを邪魔されることなく正しく更新する」がSerealizabilityの根本でもあるわけだが、邪魔とはまあつまり、他にデータを読んだり書いたりしたヤツがいたかどうかである。他にデータを書いたヤツがいたら、最初に読んだデータは間違っていたことになるわけで、もうトランザクションの正統性を保証できないからアボートするしかない。これをサボると、パフォーマンスが得られるかわりに、いわゆるRDBMSにおけるAnomalyが発生する。他の誰にもデータを変更させないようにするには、ロックを使う。で、この「邪魔が入るかどうか」を保証するためには、ロックなり、誰かが読んだ証拠なりの情報を正しく全ノードで共有する必要がある。これが協調動作(Coordination)というわけだ。

これは、これまでのふつうのRDBMSだと簡単だった。ロックがある。コンピュータの中にはクロックがあるし、ユニークで単調増加なIDを発行するためのアトミックなインクリメント命令はCPUがサポートしている。RDBMSはロックをどうやって作ったり設計するか、どうやってIDを使ってトランザクションを並べるかが歴史だったわけだが、分散システムの世界ではそもそもロックを作れないし、ユニークで単調増加なIDやタイムスタンプを作ることもできない(できなくはないが、非常に難しいしめんどくさい、レッドオーシャン)。その難しさは、分散システムの本質的な性質に由来する。非同期性と故障だ。もちろん前提とするモデル次第なんだけど、いわゆる典型的なデータセンターではこれは現実に起こってる *12ので、単純化するのは難しい。時計も信用できない *13 のでIDを生成することもできない。で、これが難しくて研究者たちはずっと成果が出せずにいた。

で、この難しいをやらなくてもいいんじゃね?といったのがPeter Bailisだ *14。実世界のワークロードを分析してみて、概念を整備して、なんとかなるんじゃねという主張である。この論文は実装の詳細があまり載っていないのでどこまで実用的かはちょっと微妙ではある。

Spanner

で、それを力技でやったのがSpannerである *15。SpannerはDC間のレプリケーションと、ある区切られた論理的な範囲(Dictionary)でのCoordinator選出にPaxosを使った。このDictionary間の整合性はTrueTimeと2PCで保証する。このTrueTimeがSpannerのすごいところで、なんとGPSと原子時計を使ってDC間で整合性のあるタイムスタンプを作ってしまった。これによって、複数DC間でもそこそこのレイテンシでトランザクションできて、なおかつとてもスケールアウトするデータベースも作ってしまったのである。ちなみに、その上で動作するF1 *16 というSQL処理系も作ってしまった。

インデックスすら作れなかった分散DBがついにここまで来たのである。

Kudu

とはいえTrueTimeとか、DC間高速ネットワークなんかを作ってしまえるのはGoogleだけだ。実装が公開されるわけもない。そこで…というわけではないが関係あるのがKuduだ *17。もともとHDFSとHBaseのユースケースの間を埋めるのが目的だが、なかではHybridTime *18 という技術が使われている... といっても、 0.7.0 時点ではこれを使ったトランザクションができるようになったわけではない。まだこれからやるっぽい。これがあれば、どうもトランザクション間の依存グラフをある時間幅の外で作れるらしいのだがその方法が私にはちょっと自明ではない。果たしてどうなることやら。ともかく、これが最初に登場した可能性ありそうな実装なわけで、他に挙げるものが今のところないわけだ。

ちなみにKuduもSQLの処理系は含まれていなくて、ImpalaというMPPエンジンを上に乗せて使うのが主なユースケースのようだ。

Next?

しらない分からない、未来は予言できない。もう2,3年経ったら、分散インデックスとか限定的なトランザクションとかはCP型のデータベースではできて当たり前になると思うのだけどどれが生き残るかはちょっと分からない。

本当に代表的なものだけにして、詳細や有名な製品には触れなかったが、興味のある人がいたらまた追って解説したい。

エンジニアCROSS 2016で登壇してきました

一昨年も似たような感じで参加したのだけど、今年はちょっと違うセッションで。当日の様子はTogetterに残っているのでそちらをご覧いただくとして、私はビール3缶を開けて非常に上機嫌になっていたので、後半、私が何を言っていたのか分からなかった方も多いのではないだろうか。というわけで、私が言いたかったことを上手に解説してくださっている方がいたので引用しておくことにする。

以前の分散システムのはなしと違ってこちらは私の胃袋がビールで満たされたのと同様に開場は聴衆で満たされていたのだが、わりと全員が興味を持って聞いてくれたのではないかと思う。言葉に窮して麻雀の例えを出したのはよくなかった。開場がPokernとしてたの分かったよね。

それぞれみんな仕事やら家庭やらが忙しくて、海外に行こう!なんて一念発起するなんてそうそうできるもんじゃないし、一念発起したところで行きたい会社が簡単にみつかるわけでもないし、そことタイミングが合うことも少ないだろうと思う。今の仕事を確実にこなしつつ、面白いことや好きなこと、金になりそうなことをコツコツと準備していって、大物が現れたらガツッ掴みとることをオススメする。

エンジニアのいるべき場所は米国でも日本でもどっちでもいいんだけど、どうせならドメスティックな仕事じゃなくて、世界になんか売ってるところがいいと思うのね。そうすれば食っていけるだけの稼ぎは出るだろうし、好きなところに住めば心の余裕も生まれる。そういう余裕がある状態にまで持っていくのはまあ、ある日突然の移民!とかじゃなくて、日々の努力と獲物を逃さない眼力だろう。そんな私は3Kスコープカスタムにしてがっくりウデマエが落ちたけど。

2016年になりました

101ND610-DSC_0841

写真は、四谷の坂本 (tabelog) で買ったお節料理。とてもうまい。ついに2016年になった。

2015年を振り返る

2015年を振り返ろうとしたら、先日書いた記事に実際ほとんどまとまってしまっていて、特にまとめることもなさそうだった。昨年は対外発表とか勉強会とかそういうのをほとんどやっていない... と思ってSpeakerDeckを見返すといくつかやってた。

外向きに話すのをかなり減らしたのは子供が2月に生まれたこともあったんだけど、アウトプットしてるヒマがなくてひたすらインプットしていた一年だったからだ。

もう2年近く?続いているふたつの読書会に参加していて、ひとつは分散合意本読書会。こちらは、いわゆる同期本が1月に終了していて、非同期本に突入していた。それで、ようやくブロードキャストの基礎理論をやっと一年かけて前準備できたところ。次からやっと非同期世界の合意問題に入る。前準備だけで本一冊半、しかもずっと記号と証明の世界なので内容を理解していると自信持っていえるわけじゃないけど、驚かないくらいにはなれた。おかげでちょっとした分散プロトコルの証明くらいなら読めるようになったと自負している。

もうひとつの読書会は、いわゆる分散DB本というやつ。これがなんとか昨年内に全部読み終えることができて、なんというか、頑張ったなあという感じであります。はあ…。

どちらの本も、それぞれ別の理由で正直おすすめできるものではないのだが、やっぱり英語の本を何冊も読破できるようになって、しかもProofreadする方法を改めて確認できているので、これはなんというか大きな達成だなあというところである。まあ2年かけてやっと2.5冊読んだが、その間に洋書や論文の積読はもっと沢山たまっているわけで非常に悩むべきことである。

で、その次は分散処理本が読書会のキューにたまっている状況。こちらは基礎理論を広く押さえた(合意本は狭く深く…深すぎる)よい本だと思う。

個人的には、まあ詳しくは書かないがいろいろあった。一昨年に息子が幼稚園を一度やめた(僕が園長と喧嘩をした)のだが、近所の幼稚園にまた通いだして元気になった。よかった。たとえモンスターペアレントと呼ばれようとも、素人の教育論であったとしても、まあ許せないことは許せない。まさか子供の顔を見ない教育をする連中がいるなんて思いもよらなかったのだがまあいたんだ。

近所のジムに入会して筋肉トレーニングを再開した。学生時代にちょっとやって以来10年ぶりというレベルだが、なんとか体重と体脂肪率の目標 70kg / 20% を、たとえ一瞬にしろ風邪で食が細ったことが原因にしろ達成できたことはすばらしい。よく頑張った俺。おかげでベースになる代謝が増えて体温がちょっと上がって健康度が高まった。まだ30代なので、散歩とかヌルいこと言わずになるべく自分の肉体を追い込んでいきたい。スクワットも次男が生まれてから少しだけやっている。

Wii Uを買ってスプラトゥーンを始めた。非常にまずい。よくないことだ。あと年末は家族で沖縄に行ってきた。ハイシーズンだし別に泳げるわけではないのだけど、日差しも柔らかで気候も暖かい(晴れているわけではない)ので過ごしやすくてよかった。また行きたい。

101ND610-DSC_0460

D610を買ったのは先日のPyspa活動まとめでも書いたが、D610のカウンターは 101ND610/DSC_840 だった。つまり買ってから 10840回 シャッターを切ったことになる。実際残ってる写真や動画はもっと少ないと思うが大した量だ。容量はRAWも合わせて170GBに達した。今全力でS3にバックアップを流しているが、それでも一日で終わりそうなのだからインターネットはすごい。 2MB/s くらいだが、同時にスプラトゥーンもちゃんとできているので、スループット重視の通信とレイテンシ重視の通信を同時にできてるのだからやっぱりインターネットはすごい。

2016年の目標

参考

こういうの西暦で偶数年に書くことにした…わけじゃなくて、億劫でたまたま奇数年はやってなかったっぽい。

msgpack-erlang 0.4.0 to 0.3.5 をリリースしました

2015-11-11 15.27.37

これはErlang Advent Calendar 2015 - Qiitaの11日目の記事だ。本日、 OTPの17と18のみに対応して古いOTPで動かなくしてコードがシンプルになった 0.4.0と、R16以前でも動く0.3.5をリリースした。 0.4.0 は別に新しい機能があるとかそういうわけじゃないのだけど、ついに maps がデフォルトになったとかあのよく分からない nil がなくなったとか、 Erlang の QuickCheck でバッチリテストされようとしているくらいだろうか(ちょっと頑張ったけど、結局うまく動いてない…)。

わたしの近況

Bashoという会社で働いていて、 Riak CS という製品の開発リーダー的なことをやりつつ、新製品Machiの開発もやっている。ほぼ毎日ひたすらコードを書いたり設計したり議論したり、ちょっとだけテストしたり、という感じ。でもわりとアーランのアプリを書いてばかりなので、OTPとかBEAMに深入りしなくてもやることは沢山あって仕事には困ってない…ので、OTPの知識が増えない…

MsgPackとmsgpack-erlang の近況

msgpack/msgpackのレポジトリでは「生きてる?」みたいなコメントされたりしてネット上では存在感が薄くなってきたが、 Basho に入って3年あまりついにBasho製品に MessagePack と msgpack-erlang の実装が入ってしまった。具体的には、 Riak TS という、先日若干界隈を賑わせた製品の下回りでデータのシリアライザとして利用されている。具体的には、 Riak にスキーマ的なのをつけられるようになって、それがMsgPackでシリアライズされてLevelDBに入るようになった。カラムナなデータ構造になったわけではないが、クエリの一部をLevelDBの直前のC++のところまでプッシュダウンすることで効率化されている。まあもともとLevelDBにはsnappy圧縮が入ってるんでMsgPackの小ささ自体がそこまで貢献してるわけじゃないけど、まあJSONよりはマシかあ、PBもスキーマいるし大変だよねえといったところだ。入社前に書いたコードがついに仕事で役立っている模様(なにせ私は直接関わっていないどころか知らないところでほとんど話が進んでいた)。

ちなみにNIF版の開発は全然やってない。メモリアロケータまわりまで含めてちゃんとやるのめんどくさそうなんやもん…

msgpack-erlangErlang QuickCheck テストを追加

QuickCheckはすばらしい。 msgpack-erlang を rebar3 化するにあたってあまりノウハウがなかったのだが、そこは想定外だがプラグインがあったので大した苦労もなく導入できた。書いたコードは本当に一部だけだった。特になにもしなくて

$ ./rebar3 eqc

だけでビルドとテストができるようになっている。

あなたも無料でQuickCheckが使える

もうほとんど忘れられているが、 msgpack-erlanghttp://quickcheck-ci.com でテストされている。URIはないのだが(マジかよって感じですね)、msgpack-erlang でサイトを検索してもらうと見つかるはずだ。未だに 17.1 だったり、メモリ使いすぎるとすぐ死ぬ(ので肝心のShrinkはあまり使えない)とかまあQuviqがあんまりやる気ないことは百も承知だが、ないよりはマシだ。マシだと思いたい。

頭が痛い問題

Arrays with numbers and {enable_str, true} · Issue #51 · msgpack/msgpack-erlang · GitHubがわりと面倒くさい。気持ちはわかる。Printableな文字列をそのままシリアライザにツッコミたいよね。そらそうだ。Functionを指定させるってのがいいのかなあという気になりつつはあるけど、文字列かどうかを判定させるオーバーヘッドがパフォーマンスにどれくらい効いてくるのか未知数ではある。

iolist() にしてみたい

いまのところシリアライザもデシリアライザも binary() しか使えないし吐かないようになっているが、これを iolist() にしたらどうなるかなというのはちょっと気になっている。もちろん iolist_to_binary() を間に挟むだけだと意味がなくてプログラミングは割と面倒くさいというか、どの粒度でバイナリを切ってリストにするとメモリアロケータを使う頻度を最小化できるかという問題になると思う。まずは erts_alloc をおべんきょするところから始めるべきだと思うんだけど、アロケータ周りをいじるとシステム全体に影響がありそうなのが気になる。という問いを空中に投げてこの記事を締めたい。