メモ
メモじゃないエントリは余り無い。
書き込み可能な分散ブロックデバイスを作る。OCFS2を併用。
たとえばこんなデータ。
0123456789012345 ***** * *** ---------------- n1 ** * n2 **** n3 ** * * n4 **** n5 ***
nがノードで、*がデータ(のブロックかもしれない)で、上の数字はデータの位置(の1の位)。
全体のデータの内、n1は0〜2と9を持っている。
*が無いところは、データが書き込まれていない部分。ここにread()が来たときは0を返す。
X-Table。X-Tableはすべてのノードで同期する。
開始位置 サイズ ノード 0 2 n1, n2 3 2 n2, n3 9 1 n1, n3 11 1 n3, n4 12 3 n4, n5
0から2コはn1とn2、3から2コはn2とn3が持っている、と表現。開始位置をキーにしてツリー構造でメモリ上に保持。ディスクには書かない。
でもすべてのノードが同じ情報を常に同期するのは難しいかも。
n1のS-Table。
開始位置 サイズ ディスク上の開始位置 0 2 0 9 1 2
実際のデータを、ローカルディスク(またはメモリ)に書き込むときの表。XFSのExtentを参考に。@IT エクステント(Extent)方式
これも開始位置をキーにしてツリー構造で保持。ディスクにも書き込む。1エントリは64ビット整数2つと32ビット整数一つで20バイト。これ自体をどこに書くか決めてないな…。
S-Tableのエントリには書き込み日時を入れる必要があるかもしれない。違うノードが同じ部分のデータを持っていて、そのデータが同じでないときに、どちらが新しいデータか分からない。(その点RAID1のアレイを復旧させるときも同じで、RAID1だと「最初に指定された方」を優先する模様)
これでデータが増えても対処できる。V-FIELDのように1つのノードが連続した範囲しか保持できないという制限もない。それからたぶん、X-Tableからデータを検索するのはV-FIELDよりスケーラビリティは高い(まぁ意味があるかどうかは不明)。が、X-Tableを作るのに手間がかかる。特にノードが増えるとX-Tableを全面的に作り直さないといけなくなってしまう。しかもこれを全ノードで同期しないといけない。うーむ…。
データの完全同期もなかなか難しい。と言ってもX-Tableが同期されていれば問題ないわけで、X-Tableの同期がやっぱり一番問題か。
X-Tableが変化するのは、
- ノードが増えたとき
- ノードが減ったとき
- データが増えたとき
- データが減ったとき
このうち、ノードが減るのは突然かもしれない。が、これは問題ない。減ってしまったノードにデータを同期する必要はないし、ノードが減ったことの同期が遅れて、それを知らないノードがデータを書き込もうとしたとしても、データに不整合は生じない。
データが増えるときと減るときは、データを増やそうとした or 減らそうとしたノードが1台に限定されるので、このノードを仲介に(サーバー的に)使えばいいから、できそう。 増やそうとした or 減らそうとしたノードが、X-Tableを変更するように、要求→要求→要求→コミット→コミット→コミット。でも要求成功からコミットまでの隙間で処理がブロックするのはイヤだな…。しょうがないか。いやでもでも、全ノードに対して2相コミット?遅延が大きそうだ。
それからもう一個困るのが、データの書き込み順の保証。ある部分にノードAが書き込もうとして、すぐ後にノードBが同じところに書き込もうとしたときに、Aが書き込もうとしているデータがその部分を保持しているノード全部に伝播する前に、Bが書き込みを開始してしまうと、Aからの要求が先に届いたノードと、Bからの要求が先に届いたノードとで、データが食い違ってしまう。これはマズイ。
2 フェーズコミットのしくみ〜これが参考になる?
割り切って「同時に書き込んだらデータは"不定"になりますよ!」というのもアリか?普通同時に書き込んだらファイルシステムが壊れるわけで、そのためのOCFS2だったりするわけで。うーん…でもブロックデバイスで不定になるのは…
…もしかしたらこれは要求→要求→要求→コミット→コミット→コミットで問題なし?
2カ所から同時に書き込みがあったら、どちらもロールバックするのが1つ。片方を活かすのが一つ。どちらを活かすかが問題。IPアドレスの小さい方で良い?
あと、書き込み中に読み込まれた場合。物理デバイスの場合は書き込み中には読み込めなかったりする(読み込みが書き込みが終わるまでブロックする)けど、分散しているからそうでもない。要再考。