読者です 読者をやめる 読者になる 読者になる

古代ギリシア展に行ってきたら奇しくも都知事選に思いを馳せることになってしまった

国立博物館で開催されている古代ギリシア展に行ってきた。

行ってきた

A photo posted by Kota UENISHI (@kuenishi) on


古代ギリシアの民主制

Lamport が失敗だったという The part-time parliament の話を聞いてる人とか、世界史に興味を持っている人なら当然だし、民主主義国家に住んで市民権を持っているなら、民主主義の源流は古代ギリシアにあることは常識だと思うのだが、それがどのように実施されているかを具体的にイメージできずにいた人は多いと思う。私が撮った写真ではないが、引用させてもらおう。

kleroteria - allotment machine for jury service. Agora Museum, Athens.

Jury duty in ancient Greece

この2枚の写真の右下にある丸いものが Ballot といわれる投票器だ(ancient greek ballot - Google 検索)。円盤に棒を刺したような形をしている。棒が中空になっているか、そうでないかで賛否を表現するのだが、投票するときはこの棒の先端を指で隠して持って行ったのだそうだ。いまの御札とは全然違う。

2枚の写真にある、短い溝が沢山ついた石版は、裁判員をランダムに選択するためのクジ "allotment machine" というそうだ。

pinakia - bronze allotment plates for jury duty. Agora Museum, Athens.

この写真のような銅板に名前を書いて挿しておいて、裁判員を決めるときに適当に銅板をとって裁判員を選出していたようだ。

さてこれが、都知事選に関わりそうな展示物だ。その名前をオストラコン(陶片)という。

Voting Potsherd to Banish Aristides "The Just"

古代ギリシアの都市では、僭主(デマゴーグ)が登場して政治を徒にすることがあった。それを防ぐ目的で、年に一回陶片に名前を書いて投票を行う。名前を書かれた政治家のうち、得票数が多かった者はなんと10年間その都市を追放されるのだ *1 。いわゆる陶片追放の仕組みである( Wikipedia には諸説書かれている )。これだよこれ、こういうのがほしかったのだよ。選挙はいままで通りやってほしいから、コイツを年に一回日本でやったらどうだ、などと妄想しながら都知事選の選挙公報を見たときの苦々しい記憶を思い出していたのであった。だからのこのブログを書いたのである。

アルテミス像とその他の展示

ギリシア展は撮影禁止なので写真は特にないのだが、個人的に一番気に入ったのは307のアルテミス像だ。最後のセクションで本物を拝むことができる。ネット上にはいくつか写真もある:その1その2いくつかエピソードがWikipediaにも載っていてそれがまた傑作だ。エピソードや写真ではちょっと暗く厳しい表情をしているようにみえるが、実物は明るい照明に照らされていてもうちょっとかわいい。好意的に解釈すれば憂いのある表情だ。ギリシア彫刻の男女ともにムキムキとしたマッチョな感じがなく、どちらかというと繊細というか今風の体型になっていて現代人の好みに合うだろう。

その他の展示については、アレクサンドロス大王の彫像だ。男前という風でも、野蛮でもないし、精悍な若者という風でもない、どちらかというと飄々とした表情で、今でいうとマーク・ザッカーバーグのように野心と情熱だけがそこから湧いてくる、今でいうとシリコンバレーにいそうな若者の顔だ。とアリストテレスの彫像が近くに置かれていて、髭面がジッと弟子を見つめているのもおもしろかった。

ドラクマ貨幣の実物もあったし、ドラクマの由来といわれる鉄の棒も展示されていた。ちょうど人間が片手で掴めるのが6本だそうで、鉄棒ひとつかみ分が1ドラクマの由来なのだそうだ。通貨とはつくづく、交換可能性と信用なのだなと思う。別に悪貨が入ってきても、信用の媒体を変えてしまえばよいのだな…などと思って近年やけに取り沙汰されていた某塊鎖的技術に思いを馳せるなどしてしまった。鉄の某が通貨になるんだから、まあ別になんだっていいよね。塊鎖が実用的かどうかは別だけど。

おまけ

特別展のチケットを買うと写真の本館で総合文化展(通常展示)も見ることができる。

101ND610-DSC_3716

本物の刀剣とか、

101ND610-DSC_3655

どうもまだ使われているっぽい黒電話とか、

101ND610-DSC_3663

意外にも綺麗な庭園とか、

101ND610-DSC_3666

毛の生えた兜(写真では赤っぽいが本物はもっと黒い、撮影技術ェ…)とか、

101ND610-DSC_3671

本物の日本漆で作られた江戸時代の箱とか、

101ND610-DSC_3681

愉快な能面とか、

101ND610-DSC_3704

かわいい根付とかを見ることができる。

101ND610-DSC_3713

何よりそこいらのケチな博物館と違って、展示物のほとんどは撮影可能なのがよい。

*1:財産などは没収されなかったらしいし、戻ったらまた政治に復帰することもできたようだ

GPG鍵を作って運用し、Git(hub)やMercurialで自分が書いたコードに署名をする

自分が書いたコードに署名をしておくことはプログラマの常識であり基本動作です(かくいう私もメールは署名してないけど…)。なので私も一人前のプログラマになるべく、自分が書いたコードに署名をするようにしてみた。

GPG 鍵を作ったり準備したり

GnuPGのインストール@MacOS

$ sudo port install gnupg

鍵をつくります。有効期限は2年間。もし秘密鍵が漏れた場合でも、2年経てばほとぼりが冷める。

$ gpg --gen-key
gpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

ご希望の鍵の種類を選択してください:
   (1) RSA と RSA (デフォルト)
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
選択は? 
RSA 鍵は 1024 から 4096 ビットの長さで可能です。
鍵長は? (2048) 4096
要求された鍵長は4096ビット
(中略)
鍵の有効期間は? (0)2y
鍵は木  7/12 00:41:58 2018 JSTで期限切れとなります
これで正しいですか? (y/N) y

あなたの鍵を同定するためにユーザIDが必要です。
(中略)
gpg: 鍵8CD45203を究極的に信用するよう記録しました
公開鍵と秘密鍵を作成し、署名しました。

gpg: 信用データベースの検査
gpg: 最小の「ある程度の信用」3、最小の「全面的信用」1、PGP信用モデル
gpg: 深さ: 0  有効性:   2  署名:   0  信用: 0-, 0q, 0n, 0m, 0f, 2u
gpg: 次回の信用データベース検査は、2018-07-11です
pub   4096R/8CD45203 2016-07-11 [有効期限: 2018-07-11]
 フィンガー・プリント = FF7E B3FF 4AEE ADEA 764D  2F33 BD95 145F 8CD4 5203
uid                  Kota UENISHI (h) <kuenishi@gmail.com>
sub   4096R/B99B64AE 2016-07-11 [有効期限: 2018-07-11]

kuenishi@mineva.local> $ gpg --list-keys
/Users/kuenishi/.gnupg/pubring.gpg
----------------------------------
pub   4096R/8CD45203 2016-07-11 [有効期限: 2018-07-11]
uid                  Kota UENISHI (h) <kuenishi@gmail.com>
sub   4096R/B99B64AE 2016-07-11 [有効期限: 2018-07-11]

鍵をバックアップして保存しておく。失効証明書とあわせて、この3つのファイルがマスターになるらしい。

$ gpg --export-secret-keys --armor kuenishi@gmail.com > secret-key.backup
$ gpg --export -armor kuenishi@gmail.com > public-key.backup

インポートは簡単に "gpg --import (secret|public)-key.backup" とやってよいようだ (追記: インポート後に鍵の信頼度を設定しないとずっと信用できないと言われ続ける。方法はオマケ参照)。

GitHub にGPG鍵を登録する

これを登録しておくとGithubで Verified と出てかっこいい。

$ gpg --list-secret-keys --keyid-format LONG
/Users/kuenishi/.gnupg/secring.gpg
----------------------------------
sec   4096R/BD95145F8CD45203 2016-07-11 [有効期限: 2018-07-11]
uid                          Kota UENISHI (h) <kuenishi@gmail.com>
ssb   4096R/883A16F6B99B64AE 2016-07-11
$ $ gpg --armor --export BD95145F8CD45203
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1

mQINBFeDvmgBEADkjeoWVk9AbsOeSdCxHQGtyHEiFvXn+7dEGvw3yqs7IHk4dYil
GbcTp/CcWxk2QnrG3UXleohARh+jEx5MDMfGAf3hOGCtHrQrOd4RfvEtShgRf5kP
...
-----END PGP PUBLIC KEY BLOCK-----

と出る。これをGithubに登録する。具体的には "Settings > SSH and GPG keys" のメニューから登録する。こんな感じ。

f:id:kuenishi:20160712010215p:plain

Git にGPG鍵を設定する

これも簡単。

$ gpg --list-keys
/Users/kuenishi/.gnupg/pubring.gpg
pub   4096R/8CD45203 2016-07-11 [有効期限: 2018-07-11]
uid                  Kota UENISHI (h) <kuenishi@gmail.com>
sub   4096R/B99B64AE 2016-07-11 [有効期限: 2018-07-11]

$ git config --global user.signingkey 8CD45203 
$ git config --get user.signingkey
8CD45203

署名つきコミットやタグを作る

このあたりはGitの公式ドキュメントが詳しい。まずは署名つきのコミットをつくる。 "-S" をつけると署名をGPGの設定に従ってつけてくれる。

$ emacs README.md
$ git add README.md
$ git commit -S -m "Fix docs"

次のユーザの秘密鍵のロックを解除するには
パスフレーズがいります:"Kota UENISHI (h) <kuenishi@gmail.com>"
4096ビットRSA鍵, ID 8CD45203作成日付は2016-07-11

[master 6f12b24] Fix docs    
 1 file changed, 3 insertions(+), 3 deletions(-)

コミットが署名されているかどうかは git-show で分かる。

$ git log --show-signature -1
commit 6f12b24585f997cdf405ef38e00392bfdf3f4193
gpg: 火  7/12 01:07:56 2016 JSTにRSA鍵ID 8CD45203で施された署名
gpg: "Kota UENISHI (h) <kuenishi@gmail.com>"からの正しい署名
Author: UENISHI Kota <kuenishi@gmail.com>
Date:   Tue Jul 12 01:07:56 2016 +0900

    Fix docs

普段使っている git-tag コマンドに "-s" オプションをつけることで、署名つきのタグを作ることもできる。署名は git-show で確認できる。

$ git tag -s 0.0.1 -m "First signed relase 0.0.1"

次のユーザの秘密鍵のロックを解除するには
パスフレーズがいります:"Kota UENISHI (h) <kuenishi@gmail.com>"
4096ビットRSA鍵, ID 8CD45203作成日付は2016-07-11

$ git show 0.0.1
tag 0.0.1
tag 0.0.1
Tagger: UENISHI Kota <kuenishi@gmail.com>
Date:   Tue Jul 12 01:11:34 2016 +0900

First signed relase 0.0.1
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAABAgAGBQJXg8U2AAoJEL2VFF+M1FIDkeYQAOCOtjX2q5Ai+uq5/S+Rh0uE
K4xR4VlbUriPb376fweLNglct5dgSSxU151Auq36kWAiEKkEZR3mEdtYbMmEqEXV
Srx0+4b/Z3WFCh6A9B2mjdjMNBs3gGuQJvkGEAeseHBOOoM+jyxHtZFG4032HZgw
tag 0.0.1
Tagger: UENISHI Kota <kuenishi@gmail.com>
Date:   Tue Jul 12 01:11:34 2016 +0900

First signed relase 0.0.1
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAABAgAGBQJXg8U2AAoJEL2VFF+M1FIDkeYQAOCOtjX2q5Ai+uq5/S+Rh0uE
K4xR4VlbUriPb376fweLNglct5dgSSxU151Auq36kWAiEKkEZR3mEdtYbMmEqEXV
Srx0+4b/Z3WFCh6A9B2mjdjMNBs3gGuQJvkGEAeseHBOOoM+jyxHtZFG4032HZgw
t2g1GS7BPIoas2azrKRWY9Jt4hCfEQ5TQpmbm9lbtbMDK9JRZ6mxkdoTyUdHM3c5
8chHTvXW+6yRbIEA3MKLzA+r/4crjLDOm/UqLpggRw3e0+mEpPeN40ifrq6MyBwy
82VBuAw/38qAsO2OXNeRwNbNPXPmTT4S/OQ09cAu7CjgHQ7/X6ZYb2/9w01BvAEn
5XdA4oaMeFq8/4W1W+jFSUBlrEM7YWEoE7ZPjLeln7iFND+mTfV2OU92ftOku0ou
IOP8l1/NzphLTJJR3nvqMzCzX+sONgeyfc8wT81yyOgAyR1uwgy9svyDHdEfvqM2
hulOuJ+HhzbuhLZ0rmXot+gXCGoAE7oXP4wFXHQ+NP1iTKP1flSHtXnFiUs19ikm
MspL75R29ATz7lAaWM1vv5AKivIy3Xsu7ngE69fnHa6R28frBPvfTbY+m2dxBiNd
I0npPtpAUS/FMQvZCFzACumZ5LdWCNx1uE7K2sUJv5zaMXTsTbB+XfMbvyOH0Hoe
jtP4uzxY324qTrj8gtxV
=AvrO
-----END PGP SIGNATURE-----

commit 6f12b24585f997cdf405ef38e00392bfdf3f4193
Author: UENISHI Kota <kuenishi@gmail.com>
Date:   Tue Jul 12 01:07:56 2016 +0900

    Fix docs

diff --git a/README.md b/README.md
index 19af36d..97490a4 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
(snip)

タグの確認は -v オプションだ。

$ git tag -v 0.0.1
object 6f12b24585f997cdf405ef38e00392bfdf3f4193
type commit
tag 0.0.1
tagger UENISHI Kota <kuenishi@gmail.com> 1468253494 +0900

First signed relase 0.0.1
gpg: 火  7/12 01:11:34 2016 JSTにRSA鍵ID 8CD45203で施された署名
gpg: "Kota UENISHI (h) <kuenishi@gmail.com>"からの正しい署名

これを git-push すると… こうなる

f:id:kuenishi:20160712011555p:plain

Verifyされた!これで私もVerified Engineerだ(??)

タグの方も無事にVerifyされている

f:id:kuenishi:20160712011709p:plain

Mercurial と Bitbucket

Mercurialには素晴らしい日本語ドキュメントがついており、使い方も簡単な ので*1、それに従うだけでよい。Mercurial は gpg というエクステンションが公式パッケージに含まれているので、これを有効化して設定するとよい。わたしの ~/.hgrc はこうなっている。レポジトリ毎に使い分けたい場合は .hg/hgrc を以下のように設定すればよいと思う。

username = UENISHI Kota <kuenishi@gmail.com>

[extensions]
hgext.gpg=

[gpg]
cmd=/opt/local/bin/gpg
key=8CD45203

署名するには hg-sign だ。tip の代わりに特定のリビジョンをつけてもいいと思う。

$ hg sign tip
signing 3116:3dacfa73a0f7

次のユーザの秘密鍵のロックを解除するには
パスフレーズがいります:"Kota UENISHI (h) <kuenishi@gmail.com>"
4096ビットRSA鍵, ID 8CD45203作成日付は2016-07-11
$ hg log -r 3117
changeset:   3117:d7d5cf15a1b3
tag:         tip
user:        UENISHI Kota <kuenishi@gmail.com>
date:        Tue Jul 12 01:22:52 2016 +0900
summary:     Added signature for changeset 3dacfa73a0f7

Mercurialの場合は、直前のコミットの署名を .hgsigs というファイルに追加した変更をコミットするという形での署名になる。

$ hg diff -r 3116
diff -r 3dacfa73a0f7 .hgsigs
--- a/.hgsigs   Mon Jul 11 23:25:41 2016 +0900
+++ b/.hgsigs   Tue Jul 12 01:25:36 2016 +0900
@@ -1,1 +1,2 @@
(snip)

署名の確認は、署名対象のコミットを引数にして hg-sigcheck を呼ぶ。

$ hg sigcheck 3116
3dacfa73a0f7 is signed by:
 Kota UENISHI (h) <kuenishi@gmail.com>

これをBitbucketに投稿してみたのだが、Bitbucketのコミットのページになんか出るということもなかったので、なんだかつまんなかった。

まとめ

  • GnuPGを使って鍵を作り、自分のコードに署名する方法をまとめた
  • Github は署名をサポートしている(Mercurial @ Bitbucket はイマイチ)
  • 署名はプログラマーの基本動作
  • できればメールも署名くらいはしたい

おまけ

Fingerprintも出しておこう!!

$ LANG=C gpg --fingerprint 8CD45203
pub   4096R/8CD45203 2016-07-11 [expires: 2018-07-11]
      Key fingerprint = FF7E B3FF 4AEE ADEA 764D  2F33 BD95 145F 8CD4 5203
uid                  Kota UENISHI (h) <kuenishi@gmail.com>
sub   4096R/B99B64AE 2016-07-11 [expires: 2018-07-11]

追加

鍵を公開鍵サーバーに登録する

$ gpg --keyserver pgp.nic.ad.jp --send-keys 382AF48A 
gpg: sending key 382AF48A to hkp server pgp.nic.ad.jp

鍵のバックアップ

$ gpg --export --armor kuenishi@gmail.com > gpg-public-key.backup
$ gpg --export-secret-keys --armor kuenishi@gmail.com  > gpg-secret-key.backup
$ gpg --gen-revoke kuenishi@gmail.com > gpg-revoke-key.backup

鍵をインポートする

$ gpg --import gpg-public-key.backup
$ gpg --allow-secret-key-import --import gpg-secret-key.backup

このままだと、インポートした鍵は信用されていないので、ローカルで信用度をつけておく

$ gpg --edit-key kuenishi@gmail.com
(snip)
> trust
pub  4096R/8CD45203  作成: 2016-07-11  有効期限: 2018-07-11  利用法: SC  
                     信用: 未知の     有効性: 未知の
sub  4096R/B99B64AE  作成: 2016-07-11  有効期限: 2018-07-11  利用法: E   
[  未知  ] (1). Kota UENISHI (h) <kuenishi@gmail.com>

他のユーザの鍵を正しく検証するために、このユーザの信用度を決めてください
(パスポートを見せてもらったり、他から得たフィンガー・プリントを検査したり、などなど)

  1 = 知らない、または何とも言えない
  2 = 信用し ない
  3 = まぁまぁ信用する
  4 = 充分に信用する
  5 = 究極的に信用する
  m = メーン・メニューに戻る

あなたの決定は? 5
本当にこの鍵を究極的に信用しますか? (y/N) y

pub  4096R/8CD45203  作成: 2016-07-11  有効期限: 2018-07-11  利用法: SC  
                     信用: 究極        有効性: 未知の
sub  4096R/B99B64AE  作成: 2016-07-11  有効期限: 2018-07-11  利用法: E   
[  未知  ] (1). Kota UENISHI (h) <kuenishi@gmail.com>
プログラムを再起動するまで、表示された鍵の有効性は正しくないかもしれない、
ということを念頭においてください。

gpg>quit

*1:ここは英語だけど…

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

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

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型のデータベースではできて当たり前になると思うのだけどどれが生き残るかはちょっと分からない。

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