2/27 (月)
[Book] トーマス・ヘイガーの「大気を変える錬金術――ハーバー、ボッシュと化学の世紀」
トーマス・ヘイガー著「大気を変える錬金術――ハーバー、ボッシュと化学の世紀」を読了した。 この本は中西 準子先生の書評で知ったのだがこれは評判通り凄い本だった。
内容は空気からパンを作る技術、つまりフリッツ・ハーバーとカール・ボッシュが完成させた窒素固定法(ハーバー・ボッシュ法)に関する科学技術史の解説だ。 一応理系なのでハーバー・ボッシュ法は知っていけど、窒素固定法が発明される前の前史、ハーバーとボッシュが発明以降に辿る数奇な運命はほとんど知らなかった。
ヨーロッパは火薬の原材料や農業生産性を高めるための肥料として硝石を必要とする。 人間の尿を集めることである程度硝石を集めることが出来たが、それでは足りない。 自然の中にある硝石の鉱脈を求めて世界中が探索される。 やがてペルーのグアノ(海鳥の糞由来のリン酸肥料のもと)やチリの硝石が発見されヨーロッパに輸出されるようになる。
このような肥料はペルーやチリに莫大な収入をもたらした。 1859年にはペルーの歳入の3/4がグアノから来たそうだ。 そしてグアノの所有権を巡って戦争(グアノ戦争1863)が起きることになる。 戦争はペルーが勝利するが、グアノはやがて取り尽くされてしまう。 グアノが尽きると次に南米のアタカマ砂漠にあった硝石が注目を浴び、この領有権を巡ってチリとペルー・ボリビアとの間で硝石戦争(1879)が発生することになる。 この前史が本書の序盤のストーリーとなる。
このような背景の中で植民地獲得に出遅れたドイツは、農業力と軍事力に直結する硝石が海外からの輸入に頼っていることに危機感を抱き、窒素原料のもととなるアンモニアを工学的に合成する方法を探索しはじめる。 このアンモニアの実用的な合成方法を世界で初めて発見したのが化学者のハーバーであり、ハーバーの手法を現実のプラントとして完成させたのが化学会社BASFの技術者ボッシュだった。 このプロジェクトX的な二人の努力が本書の中盤に描かれる。
そして完成したハーバー・ボッシュ法とハーバーとボッシュという二人のユダヤ人が、第一次大戦・第二次大戦の中で時代に翻弄されてゆく様が終盤のストーリだ。
ハーバー・ボッシュ法は人類の食糧生産にとって最も重要な技術で、これがなければ増えすぎた人類は20世紀の半ばに飢餓のために大混乱に陥り今とは違った歴史を辿っていたはず。 そういう意味では電話やコンピュータと並ぶ発明であるべきで扱いが小さいのは不当だ。 是非読むべし。
P.S.
グアノを巡っては1856年に米国が「グアノ島法」という法律を成立させている。
この法律はと言うとあらゆる島、岩、珊瑚礁に堆積するグアノを米国市民が発見した際は、他国政府による法的管理下になく、他国政府の市民に占領されておらず、平和裡に占有してその島、岩、珊瑚礁を占領したときはいつでも、米国大統領の裁量で米国が領有したと判断して差し支えない。
という凄い内容。
この法律は今でも有効。
今も昔もジャイアンなのね。
2/23 (木)
GlusterFS のリバランスが改善されていた
オープンソースの分散ファイルシステム GlusterFS は複数のノード、これを brick と呼ぶ、を束ねて一つの大きなファイルシステムを作成する。 基本的にはディレクトリを除いたベースファイル名から 32 ビットのハッシュ値を求め、ハッシュ値からどの brick に格納するのかが決められる。
- 同一ベースファイル名(ディレクトリを除いたファイル名)は同一のハッシュ値になる。
- Brick がどのハッシュを受け持つかはハッシュ値の範囲で決める。例えば brick が 4 つしかなければ 0x0000,0000 〜 0x3FFF,FFFF が brick0、0x4000,0000 〜 0x7FFF,FFFF が brick1、0x8000,0000 〜 0xAFFF,FFFF が brick2、0xA000,0000 〜 0xFFFF,FFFF が brick3 のように。これがファイルの分散方法を決定する。
- Brick がどのハッシュ値範囲を担当するかは、ディレクトリによってランダムに決まる。これはディレクトリの拡張属性(xattr)である trusted.glusterfs.dht に記録される。
- ディレクトリの trusted.glusterfs.dht は、そのディレクトリに最初にファイルが配置された時(?)に決まるようだ。以降、brick の追加・削除や容量不足が起きなければ、この trusted.glusterfs.dht は変更を受けない。ディレクトリが移動されても trusted.glusterfs.dht は変わらないので、ファイルの分散方法に変更はない。
上記をひっくるめて GlusterFS は Elastic Hash Algorithm(EHA) と呼んでいる。
GlusterFS は brick を追加することで容量を増やすことができる。 この場合、追加された brick を含めてファイルの分散方法を変更し、新しい分散方法に従うようにファイルを移動する。 この操作を リバランス(rebalance) と呼んでいる。
ここから本題
最初、10 台のノードで運用していた分散ファイルシステムが +1 台加わって 11 台になる場合、各既存ノードが 1/11 だけデータを新ノードに移すのが理想的である。 この場合、既存のノードのうち 9.1 % だけが移動し、90.9% はリバランス前のノードに残ることになる。
しかし GlusterFS のリバランス処理が非常にお馬鹿。 ハッシュ値を brick 数で単純に N 分割していたのを、M 台の brick を追加する場合 N + M 分割に変えていたのである。 さらにリバランス前後で brick 毎のリバランス範囲をシャッフルしてしまう。 その結果、リバランスによって内部データの大移動が起きていた。
ところが GlusterFS の 3.3 のベータバージョンからこれが大幅に改善している。 10 bricks のところを +1 して 11 bricks にした場合と、10 bricks から +2 して 12 bricks した場合の、元の brick に残るデータ量の割合を求めてみた。 これを下の表に記載する。 割と劇的だ。
10→11 | 10→12 | |
---|---|---|
3.2.5 | 9.2% | 未計測 |
3.3 beta2 | 73.3% | 68.2% |
理想的 | 90.9% | 83.3% |
ソースコードを見たわけではないが、おそらく下の図のように 3.2.5 まではランダムにハッシュ範囲が変わっていたのを、3.3 からファイル量が最小になるようにリバランス前の状態を加味してハッシュ範囲を決めるようになったと思われる。
![]() |
[Food] エル・アミーゴ@武蔵小杉
武蔵小杉にメキシコ料理の店があると気づき行ってみた。 エル・アミーゴ(食べログ)という。 場所は中原区役所の裏ぐらい。
夕刻だが店の中に客は私独りきり。 1/2ポンドビフテキとエルチラダスというのを頼んでみる。
エルチラダスはトルティヤの肉巻き煮込みだがラザニアっぽい。 熱いうちはいいのだが冷めてくると悲しい味になる。 ビフテキはまあビフテキだった。
メキシコ料理をあまり食べたことがないが、こんなものなのかしら?
2/22 (水)
渋谷は大騒ぎ
午後4時頃に JR 渋谷駅で通り魔事件があり、6時に渋谷に出た時は構内は大騒ぎだった。 TV 局のカメラも来ていた。
JJUG Night Invokedynamic 命令
Java SE7 から導入された invokedynamic 命令が話題の JJUG Night Seminar 2012年2月 に参加。
- Java 7 Invokedynamic の概要
- JRuby における InvokeDynamic の利用パターンと性能評価
- Groovy と indy
- Kink: プロトタイプベース言語で inovkedynamic (構想)
[Food] 北海道らーめん味源 熊祭@渋谷
再び渋谷に戻って「北海道らーめん味源」を食べてゆく。
「金のとりから」。 ソースはいろいろ置いてあるので自由につけて食べれる。
2/18 (土)
第6回JVMソースコードリーディングの会(OpenJDK6)
今回のコンカレントGC部分のソースリーディングの資料をアップロードしておく。
ソースコードリーディングの会でしゃべったことを以下にちょっと補足しておく。
Topic1: Linux の Transparent Hugepage
x86 や x86-64 は基本的にページサイズが 4KB だが、CPU には 4KB よりも大きなラージページをサポートしている(x86 の場合は 4MB、x86-64 の場合は 2MB)。 Linux は Hugepage と呼ばれる機構でこれをサポートしているが使うのが結構面倒だった。 どう面倒なのかは下記の日記を参照ください。
- 2005年4月21日 Linux のヒュージページ(huge page) の覚え書き
- 2005年5月31日 IBM Java developer kits 1.4.2 SR1a & 1.3.1 SR8
- 2005年12月15日 Java のラージページ対応のまとめ
Linux は 2.6.38 から Transparent Hugepage が導入された。 これは通常のプログラムを走らせるとカーネルが Hugepage 分の連続的メモリ領域を見つけて自動的に基本ページ(x86系なら4KB)から Hugepage (x86-64 なら 2MB) に変換してくれる機構だ。 この機構は JavaVM のヒープ部分にうまくマッチして使用してくれる。
CentOS 6.2 + Linux kernel 3.2.2 for x8-64 上で OpenJDK 1.6.0_17 をテスト走行する。
$ java -server -Xmx2g -Xms2g Test
JavaVM が動いているプロセスの /proc/<pid>/smaps/
を見ると、Hugepage 化が利いているのが分かる。
7f8341000000-7f83c1270000 rwxp 00000000 00:00 0 ← ヒープの開始アドレス周辺になっているはず Size: 2099648 kB ← ヒープのサイズに適合 Rss: 2066432 kB Pss: 2066432 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 2066432 kB Referenced: 2066432 kB Anonymous: 2066432 kB AnonHugePages: 2066432 kB ← この分だけ hugepage 使っている Swap: 0 kB KernelPageSize: 4 kB ← ここと MMUPageSize: 4 kB ← ここは 4KB でも大丈夫 Locked: 0 kB
Topic2: GC 時に余分に使うメモリ
GC 中にヒープ以外のメモリを消費してしまうという話。
Hotspot VM のオブジェクトは全てのオブジェクトに2ワード分のヘッダーがある。 これは32ビットバージョンでは1ワード=32ビットで8バイト、64ビットバージョンでは1ワード=64ビットで16バイトである。 32ビットバージョンでも64ビットバージョンでも1ワード目は _mark と呼ばれる多目的フィールドで、2ワード目は _klass と呼びクラス情報へのポインタとなっている。
この中で1ワード目の多目的フィールドが問題になる。 32ビットバージョンでは通常 LSB の 2 ビットが 01b になっており、その上で 25 ビット分の hash タグ、4 ビット分の age タグが含まれている。 hash タグは hashCode が呼ばれるまでは 0。hashCode が最初に呼ばれた場合に非0の乱数値が設定され、そのオブジェクトのハッシュコードとなる。 age タグは GC を潜り抜けた回数を記録している(ただし旧世代に移動された後はもう記録を止めて 0 が入っているはずだが自信なし)。
hash(25) | age(4) | 0b | 01b |
ところが1ワード目の多目的フィールドは、GC 時に forwarding pointer を記録する領域に様変わりする。 LSB の 2 ビットが 11b となりこれが「マーク済み」状態を示す。
forwarding pointer | 11b |
GC が _mark を勝手に forwarding pointer として潰すと問題になることがある。
例えば逐次 GC(オプションの-XX:+UseSerialGC
をつけた場合)の Full GC などである。
逐次 GC の Full GC は Mark & Compact で空間内でインプレイスにオブジェクトを移動する。
その関係で移動先の計算を計算して、_mark に移動先(forwarding pointer)を破壊的に代入する必要がある。
もちろん元の _mark の値が失われると困る。 ヒープの外側に退避場所を作って forwarding pointer で潰す前に保存しておくことになる。 下の図中の preserved mark table が保存先にあたる。 このテーブルにオブジェクトのアドレス(_obj)と _mark 値を保存を1組づつ保存しておく。 GC が進むと presrved mark table の _obj 項は移動先のアドレスに書き換えられ、ヒープ中のオブジェクトの移動が完了した後に保存していた _mark 値を書き戻す。
図中の resreved mark table は実際の実装ではもう少し複雑で、最初は _preserved_marks
を使い、不足した場合には スタック構造の _preserved_mark_stack
と _preserved_oop_stack
を使う。
_preserved_marks
は Full GC 中未使用の新世代の TO 領域を潰して使う。
_preserved_mark_stack
と _preserved_oop_stack
はヒープ外になる。
注記: MarkSweep
というクラス名になっているが、これは Mark & Compact GC 用のクラスである。
void MarkSweep::preserve_mark(oop obj, markOop mark) { // We try to store preserved marks in the to space of the new generation since // this is storage which should be available. Most of the time this should be // sufficient space for the marks we need to preserve but if it isn't we fall // back to using Stacks to keep track of the overflow. if (_preserved_count < _preserved_count_max) { _preserved_marks[_preserved_count++].init(obj, mark); } else { _preserved_mark_stack.push(mark); _preserved_oop_stack.push(obj); } }
class MarkSweep : AllStatic { snip static Stack<markOop> _preserved_mark_stack; static Stack<oop> _preserved_oop_stack; static size_t _preserved_count; static size_t _preserved_count_max; static PreservedMark* _preserved_marks;
ただしヒープ外の領域メモリなんてバカバカ使われては困るので、少し細工がしてある。
この presrved mark が必要になるのは must_be_preserved
が true の場合のみである。
もし _mark の hash 部分が 0 の場合には後で 0 に戻せばいいので保存しない。
inline void MarkSweep::mark_object(oop obj) {
// some marks may contain information we need to preserve so we store them away
// and overwrite the mark. We'll restore it at the end of markSweep.
markOop mark = obj->>mark();
obj->set_mark(markOopDesc::prototype()->set_marked());
if (mark->must_be_preserved(obj)) { hash タグが 0 でないとここが true になる
preserve_mark(obj, mark);
}
}
逆に言うと hashCode
を使うと、GC 時にメモリ使用量が増えてしまうことになる。
このメモリ使用量が最も増える最悪のプログラムを考えてみる。
32ビットバージョンの場合、オブジェクトの最小サイズはヘッダー分で 8 バイトになる。 GC を生き延びさせるためにはリンクが必要なので、参照型のフィールド(下記のプログラム中 next)が必要。 これは 4 バイトになる。 Hotspot VM はオブジェクトを 8 バイト境界に丸めてしまうため 16 バイトのオブジェクトを数珠繋ぎにする。 つまり以下のプログラムになる。
全てのオブジェクトに hashCode
を適用すると、各オブジェクト毎に presreved mark のために 2 ワード 8 バイトが必要になる。
つまり Full GC が動き出すと驚くべきことにヒープの約半分のサイズから TO 領域のサイズを引いた分のメモリが必要となる。
class Test { Test next; public Test(Test aTest) { next = aTest; } public static void main(String[] args) { int i = 0; Test aTest = null; while(true) { aTest = new Test(aTest); i += aTest.hashCode(); // この行があるのとないので動作が変わるよ。 } } }
これを 32-bit OS で仮想メモリが確保できる最大あたりにヒープを設定して実行すると Full GC 時にあっさりと落ちる。
-XX:NewRatio
を指定して、New 世代を減らし TO 領域を小さくしておく。
$ java -Xint -XX:+UseSerialGC -XX:+PrintGC -Xmx2400m -Xms2400m -XX:NewRatio=10 Test snip [Full GC# # A fatal error has been detected by the Java Runtime Environment: # # java.lang.OutOfMemoryError: requested 4092 bytes for char in /builddir/build/BUILD/icedtea6-1.9.10/openjdk/hotspot/src/share/vm/utilities/stack.inline.hpp. Out of swap space? # # Internal Error (allocation.inline.hpp:39), pid=2055, tid=363080560 # Error: char in /builddir/build/BUILD/icedtea6-1.9.10/openjdk/hotspot/src/share/vm/utilities/stack.inline.hpp # # JRE version: 6.0_20-b20 # Java VM: OpenJDK Server VM (19.0-b09 interpreted mode linux-x86 ) # Derivative: IcedTea6 1.9.10 # Distribution: Fedora release 14 (Laughlin), package fedora-55.1.9.10.fc14-i386 # An error report file with more information is saved as: # /home/nminoru/hs_err_pid2055.log # # If you would like to submit a bug report, please include # instructions how to reproduce the bug and visit: # http://icedtea.classpath.org/bugzilla #
しかしプログラムの hashCode
を削ると、普通に OutOfMemoryError
で着地する。
$ java -Xint -XX:+UseSerialGC -XX:+PrintGC -Xmx2400m -Xms2400m -XX:NewRatio=10 Test [Full GC 2435264K->105K(2435264K), 0.7354370 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at Test.main(Test.java:12)
つまる所この GC は「Java って全部のオブジェクトに hashCode を適用するわけじゃないよね?」というヒューリスティクスを暗黙に仮定しているのだ。 当てはまらない場合にはドボン。
2/15 (水)
[Book] 思い出せないポワロの言葉
アガサ・クリスティーのポワロシリーズの中のセリフの中でどうしても思い出せなかったものがあった。 「狂人の理論は完全に論理的」というセリフなのだが、どの作品に入っているのかわからずこの半年ぐらい蔵書を読み直していたのだがABC殺人事件に入っていることを発見した。
該当部分を引用してみる。
その男が精神的に異常だというのでは、答えになりません。
ある男が狂っているから狂ったことをするというのは、理知的ではなく、愚かしいだけです。
狂気の人間はその行動において、正気の人間と同じように論理的であり筋が通っているのです―
その奇妙にゆがんだ視点から見てということですが。
たとえば、ある男が腰布だけつけて外に出ていき、そこでうずくまるとしたら、彼の行為はきわめて異常だとみなされるでしょう。
しかし、その男が自分はマハトマ・マンジーだとおもいこんでいることがわかっていたら、彼の行動は完全に論理的であり、筋が通ったものとなるわけです。
非常に含蓄のあるセリフだ。
他にポワロの印象的な言葉として「厩舎街の殺人」の中でガイ・フォークス・デイの花火をみながら「時間が経つと国会議事堂を爆発することが罪悪なのか、称賛されることだったのか分からなくなるだろう」とセリフを言うシーンがある。
「厩舎街の殺人」は死人の鏡に収録されている短編である。
エルキュール・ポワロはしみじみした口調で、
「しかし、愉快な風習が残っているものですな。
記念すべき男と、その男の所業が、とうの昔に忘れられおるのに、いまだに花火を打ち上げる。
ポンポンポンとね」
ロンドン警視庁の警部はうなずいて、
「たしかにそういえますね。
さっきの小僧たちにしても、ほとんどが、ガイ・フォークスとは何者か知ってはいないです」
「そのうちに、まちがいなく、意味の混乱が生じますな。
11月5日には、花火を打ちあげるものだが、それがはたして祝賀の意味か、それとも憎悪のあらわれか、だれも知らない時代がくる。
もっとも、そのころのイギリス議事堂を爆破するのが罪悪であったのか、崇高な行為であったのかは、わたしにもわからんが」
ジャップ警部はくすくす笑って、
「なるほど、崇高な行為説に賛成する者もいるかもしれませんな」
現代ではポワロの言葉通りにガイ・フォークスがどういう人物だったのか知らないままにガイ・フォークスのマスクを被っている人が溢れているよ。
2/13 (月)
Bitcasa を使ってみる
無限ストレージを謳うネットワークストレージのベンチャー Bitcasa からベータ版の使用許可が来た。 ベータ版の申し込み自体は昨年の9月26日に行っていたのだが随分待たされた。
インストールした後に Bitcasa を起動するとタスクトレイにアイコンが載る。
そのアイコンを右クイックして My Bitcasa Folders を選択すると Bitcasa Folders のダイアログが出る。
この中の +Add Folder
と書かれたボタンを押すとローカルディスクから任意のフォルダを Bitcasa Folder に指定できる。
指定したフォルダはネットワークの先にある Bitcasa のクラウドストレージにバックアップされるようになる。
この操作のことを Bitcasa は cloudifying とよんでいるようだ。
下は backup というフォルダと data というフォルダを cloudifiying した状態。 backup はすでに転送済みで、data は転送中である。
Bitcasa Folders ダイアログ内の data フォルダのアイコンは転送中なので下に進捗バーが出る。 アイコンをクリックすると右側にプロパティが表示され、転送状況や転送の一時停止が表示される。
backup フォルダはすでに転送済みである。 一点重要なのはBitcasa が c:\backup\ ディレクトリを転送を完了すると、その後に c:\backup\ は c:\backup.original\ というようにリネームする。 それだけでなくc:\backup.original\ は隠しフォルダ・ファイルになる。 元の c:\backup\ には Bitcasa が作った仮想フォルダができる。
転送済みの backup フォルダの方をクリックすると右側にプロパティが出てくる。
Disconnect
ボタンを押すと backup フォルダに関して、ローカルディスクとクラウドストレージとの同期が断たれ、ローカルディスク内の仮想フォルダ(c:\backup\)は消え、c:\backup.original\ は元の c:\backup\ に戻される。
その後に Connect
というボタンが出てくるので、これを押すと再びフォルダが同期がされる。
Send This
を押すと Bitcasa クラウド上の URL が表示される。
この URL を使って他の Bitcasa ユーザとのフォルダデータの共有ができるようだ。
![]() |
ユーザはクラウド上にアップロードした自分のデータを https://portal.bitcasa.com/login からすることも管理できる。
その他に気づいたこと
- Connect した状態で仮想フォルダにファイルに追加・変更・削除を行うと、しばらくしてからクラウドと同期される。ただしファイルが同期されたかされていないか表示されないので、https://portal.bitcasa.com/login を開いてファイルを確認する必要がある。
参考
- 2011年9月20日 収束暗号化(Convergent Encryption) … Bitcasa が使っている暗号化について。
- Techolog.jp | 容量無制限クラウドストレージ「Bitcasa」ベータ版がついに公開
- TechCrunch | BitcasaのCEO、無限ストレージ暗号化の謎を語る
- TechCrunch | Bitcasa、容量無制限のクラウドディスクが月額10ドルで
2/12 (日)
[Food] スープカレー屋 鴻(オオドリー) 神田駿河台店
スープカレーの店 鴻(オオドリー)の駿河台店(食べログ)に。 去年の神田カレーグランプリで少しだけ食べたことがあるけど、普通サイズを食べるのは今日が初めて。
というのもオオドリーのカレーを前々から食べたいと思っていたのだが、いつ行っても店が閉まっていて食べられなかったのだ。 だけど最近オオドリーは神田に2店あって、私が行っていたのは居酒屋の方(食べログ)だったと気づいた。 居酒屋は土・日・祝がお休みだったようだ。 スープカレーの店は月に1回以外休まないそうな。
で味の方だが期待していたほど美味しく感じられなかった。 刻んだ玉葱があまり炒めてないのでスープに溶けずに残っていて、子供の時分に嫌いだった給食の味噌汁みたいに感じられるのだ…
今日みかけた変な垂れ幕
神保町の三省堂にかかっていた「できたて、あなたの本があったかい」というオンデマンド出版の垂れ幕。 「あったかい」のは印刷したばかりだからだYO!!
2/10 (水)
[MyWeb] Ceph の覚え書きのインデックスを作成
Ceph に関するページをまとめたCeph の覚え書きのインデックスのページを作成した。
[Food] ニャ−ヴェトナムフォ−麺@元住吉店
ブレーメン通りのヴェトナムフォ−麺の店ニャ−でベトナム風のココナッツカレーが期間限定メニューで出ていた。 タイ風カレーのようにだがエビが入っている。
2/4 (土)
[Movie] ベルセルク 黄金時代篇1 覇王の卵
ベルセルクが再アニメ化されたので観に行く(公式)。 映画館はいつもの川崎チネチッタ。
黄金時代篇を三部作で公開し、その最初の一部はプリムローズ館で「夢」を語るところまでで終わっている。 ストーリーは基本漫画をなぞる形なので可もなく不可もなく。 ただ戦闘シーンの 3D のトゥーンレンダリングでぐりぐり動くのに感動した。 ネットでは色々言われているようだけど、ここ10年ぐらいで 2D と 3D の継ぎ目が気にならないぐらいまで進化したのね。
[Food] ティーヌン 川崎ダイス店@川崎
映画を見終わった後は川崎ダイスの中にあるタイ料理のティーヌン(ぐるなび、食べログ)で晩飯を食べてゆく。 「おひとり様専用夜定食」というメニューがあったのでそれで行きます。
Free 版の Dropbox の容量が 5GB 増える
Dropbox 1.3.12 のベータ版の新機能を利用すると無料の追加容量を +5GB まで増やせるという。 はげあたま.org | Dropboxの容量を無料で誰でも4.5GBも増加出来るよ!のページを参考に Dropbox の容量増加を試みてみる。
この方法は Dropbox のディレクトリに直接入れるのではなく、(Windows の場合)リムーバブルメディアを接続した時に出現する自動再生でImporting photos and vidoesを選択するというものである。
リムーバブルディスクの DCIM
以下にあったファイルが Dropbox の Camera Uploads
のフォルダにアップロードされてゆく。
そのため SD カードの DCIM
に 5GB 以上のダミーファイルを入れて差し込むのが一番良いようだ。
最初自宅のWindows7デスクトップでやったのだが、ドスパラで買ったショップブランドマシンはいずれかのソフトが自動再生機能を無効化していて SD カードを挿しても自動再生が動かない。
自動再生を明示的に動かす方法が分からない。Windows XP ラップトップで SD カードを挿しインポートを実行する。 これは成功して +5GB で無料で使える容量が 7.2GB になった。
ところで私はダミーファイルとして5GB分の画像ファイルを大量に用意して、ラップトップ機で Dropbox でアップロードしながら、デスクトップで Camera Uploads
フォルダにアップロードされたファイルをどんどん消してゆくということをやっていた。
そうするとラップトップ機の Camera Uploads
フォルダにはダミーファイルをアップロードしないだろうという読みがあったからだ。
だが実際はラップトップ機の Camera Uploads
フォルダには Importing photos and vidoes がネットワークを介さずに直接ファイルのコピーをしているようだった。
デスクトップ機でファイルを消するとラップトップ機側にダウンロードが起きなくなるが、ラップトップ側にファイルが残っているのでこれを再アップロードするという謎の処理が発生した。
2/1 (水)
Ceph に関する覚書
そのうち独立したページにまとめるつもり。
まず論文の紹介。
- Sage A. Weil 氏の博士論文
- CRUSH: Controlled, Scalable, Decentralized Placement of Replicated Data ... CRUSH アルゴリズムに関する論文
- Ceph: A Scalable, High-Performance Distributed File System ... Ceph ファイルシステムに関する論文
いくつか重要な概念を列挙する。
- まず多数のオブジェクトストレージデバイス(OSD)を束ねて大容量なオブジェクトストレージを構成するというアイデアがベースになる。信頼性を高めるために個々のオブジェクトは複数の OSD に多重にレプリケーションを作成し、個々の OSD が故障した場合は縮退を、故障原因が取り除かれた後は自動的に復元を行う。よってこのオブジェクトストレージを RADOS (Reliable Autonomic Distributed Object Storage) と呼ぶ。
- RADOS を実現には CRUSH (Controlled Replication Under Scalable Hashing) と呼ぶ分散アルゴリズムでオブジェクト(レプリカ)をどこに割り付けるかを決める。これは 2. の論文で詳しく説明されているが、その本質は hierarchical consistent hash である。
- 多数の OSD を単一の階層で管理するのは難しい。多数の OSD から構成された RADOS は、データセンターのラック列、ラック、ラック内のサーバ、サーバ内のディスクというように階層を持っており、CRUSH ではこの階層を(手動で)そのまま記述してオブジェクトの分散配置に利用できるようになっている。
例えばそれぞれ 10 台の HDD を持つ 10 台のサーバがあった場合、そこに 3 多重のレプリケーションをとる RADOS を構成するとする。CRUSH の制御ファイル(crushmap と呼ぶ)には「まず10台のサーバから3台を選び、選ばれたサーバの下にある HDD から 1 台を選ぶこと」というように記述できる。これが hierarchical の意味である。
Crushmap 上のノードは bucket と呼ばれ、例では1段目のルート bucket の下に 10 台のサーバがつき、2段目の bucket の下に 10 台の HDD が付く 2 段階モデルになる。 - ノードの追加や削除によって bucket の下につくアイテム(item)の数が変わる。Bucket の下に item が追加されたら既存の item 下のオブジェクトを新規の item の下に移動してバランス調整を行うが、bucket は consistent hash の機能によってこのオブジェクト移動を最小限にしようとする。
- 多数の OSD を単一の階層で管理するのは難しい。多数の OSD から構成された RADOS は、データセンターのラック列、ラック、ラック内のサーバ、サーバ内のディスクというように階層を持っており、CRUSH ではこの階層を(手動で)そのまま記述してオブジェクトの分散配置に利用できるようになっている。
- RADOS にはオブジェクトの種類によって pool を作成することができる。ただし最初から metadata、data、rbd の 3 種類の pool が設定されている。異なる pool には異なる CRUSH のルールを適用できる。
- Ceph は RADOS 上に作成される分散ファイルシステムである。
ファイルデータは 4MB 単位で別々のオブジェクトとして RADOS に格納される。これは data pool のオブジェクトとなる。
ファイルのメタ情報は metadata pool のオブジェクトとして保持される。このメタ情報を読み書きしてクライアントに返すのはメタデータサーバ(MDS)である。
Ceph をマウントしたクライアントは MDS と通信して、目的のオブジェクトを決定する。- Ceph はオブジェクトを RADOS 上のどの OSD に割り付けるのかを決めるのに CRUSH アルゴリズムを使用する。ただしオブジェクトを毎回 CRUSH にかけるのではない。
これは n 台の OSD から m 多重のレプリケーションをとる場合、選ばれたレプリケーション間に優先順位がある場合 nPm になるが、これは m が 2 以上の場合かなり大きな組み合わせ数になる。管理が大変で面倒なので処理を簡略化するために、あらかじめ決められた組み合わせの中から配置位置を決める。この目的のために Placement Group(PG) が導入された。 - Ceph は最大構成となる OSD 数(ディスク数)をあらかじめ見込んでおき、その100倍程度の PG を設定する。各 PG を CRUSH に適用して、レプリカの配置位置を決めるておく。100 倍というのは、この程度の組み合わせがあれば OSD 間で均一のオブジェクトをばら撒けるまけるという経験則からきていると思われる。
- Ceph はオブジェクトを RADOS 上に配置する場合、オブジェクトの ID を PG 数で剰余をとる(ObjectID % PG_Number)。この剰余値の番目の PG がこのオブジェクトのレプリカの配置位置とする。
- PG は ceph を構成したときに、どの OSD に割り付けるか決定的(deterministic)に決まる。以降、OSD がいっぱいになっても過負荷でオーバーロードしている場合でも組み合わせは変わらない。故障した場合には、PG 中の故障したのを除いた OSD だけを使う(縮退させる)。
- Ceph はオブジェクトを RADOS 上のどの OSD に割り付けるのかを決めるのに CRUSH アルゴリズムを使用する。ただしオブジェクトを毎回 CRUSH にかけるのではない。
まだ良く分かっていないポイントを挙げると
- クライアントはオブジェクトの配置位置を検索(lookup)するのに CRUSH を引くのか、それとも各 PG がどの OSD を使うのかというリストを使うのか?
- PG は ceph の運用中に増やすことができるのか?できる場合、それは性能を落とさずにできるのか?
- リバランスはどのようなロジックで実施するのか?
- リカバリはどのようなロジックで実施するのか?