2008-02-28

Javaプチテク 住所を都道府県と市区町村以降で分割 / md5sum算出

ただの自分用メモ。無保証なので使う場合は自分でちゃんと検証すること。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
* 住所の文字列を都道府県と市区町村以降に分割する
*/

public String[] splitAddress(String fullAddress)
{
Pattern pattern = Pattern.compile("^.{2,3}?[都道府県]");
Matcher matcher = pattern.matcher(fullAddress); // 分割前住所
matcher.find();

String[] result = new String[2];
result[0] = matcher.group(); // 都道府県
result[1] = matcher.replaceFirst(""); // 市区町村以降
return result;
}

/**
* 文字列からmd5sumを算出して16進表記(32文字)で返す
*/

public String md5sum(String source)
{
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(source.getBytes("UTF-8"));
byte[] d = digest.digest();
return String.format(
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],
d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]);
} catch (NoSuchAlgorithmException e) {
// 来るなよこんなところに
e.printStackTrace();
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
// 来るなってばよ
e.printStackTrace();
throw new RuntimeException(e);
}
}

2008-02-18

Xenで異CPU間ライブマイグレーション

iSCSIで SANを組んだので、せっかくだから Xenのライブマイグレーションを試してみた。

ノード1(命名kagami)
Core2Duo E8400
仮想サーバ運用のため奮発して部品を買いそろえ構築した新マシン

ノード2(命名tsukasa)
Athlon64 3500+
余り物の部品を寄せ集めてひとまず構築

kagamiと tsukasaは iSCSIで SAN上のストレージへログインしており、VMのイメージはそこに配置されている。

ライブマイグレーションのためのポート(8002)はデフォルトでlistenされているが、接続元がlocalhostだけに絞られている(この設定のままだと全く意味がない)。設定ファイル /etc/xen/xend-config.sxpで、

(xend-relocation-hosts-allow '^localhost$ ^localhost\\.localdomain$')
となっている行を

(xend-relocation-hosts-allow '')
に変更。

稼働中のdomUに対し、ライブマイグレーションを実行するコマンドは下記。

xm migrate --live ドメイン名 移動先ホスト名

意外なことに、特に問題なく kagami→tsukasaも tsukasa→kagamiも成功。
全然違うCPUだから無理かと思っていたのだけれど、動いてるプロセスの少ないシンプルな環境のVMだから移動できたのかも。
あと、dom0同士の時計が合ってないと移動されたdomUのカーネルが狂ったように時間が戻ったと騒ぎ出すので注意。

ラベル:

2008-02-11

Linuxと iSCSIで SANを構築する〜前置き〜

iSCSIは SAN(ストレージエリアネットワーク)の技術である。1000base-Tや10GbEといった一般的なネットワークのインフラを使用するため、ファイバーチャネルと比較して安価に構成出来るのが特長といえる。そのかわり、比較的高レベルなトランスポートプロトコルである TCPの上に成立しているためオーバーヘッドが大きく、性能が出にくいとされる。

しかしながら、(適切なソフトウェアを組み合わせれば)家電量販店で普通に売っているハードウェアだけで SANが構築出来るわけで、従来ファイバチャネルの守備範囲だったハイエンドの市場がより一般に近いところまで「降りてくる」可能性には注目すべきものがあるだろう。(といわれ続けてはや何年)

そもそも SANは何故必要なのか。いくつかのケースが考えられるが、ひとつは並列コンピューティング(クラスタリング)に関するものだ。
計算機資源のスケーラビリティを求めるときに取り得る戦略はいくつかあるが、いずれの戦略を用いるにせよ単体の計算機ではその計算能力に限界があるため複数の計算機を並列に動作させるという部分では共通する。しかし計算機の処理能力を必要とするビジネス上の諸問題は、多くの場合何らかの共有されたビジネス・オブジェクトの状態を無矛盾に保った上で解決される必要があるため、単純に機械を多く用意して並べれば良いということにはならない。つまり、ある口座へ入金する処理と、同じその口座から出金する処理は別々の計算機で同時に処理されることはあっても、その結果が矛盾しないことを保証されなくてはならない。

この問題に対するアプローチの一つは、記憶領域(ストレージ)を一カ所に集中させつつ計算能能力となる各ノードを分散し、適切な排他制御の元に処理を実行させる方式である。この時、ストレージと各ノードを接続するネットワークが SANである。

普通に各ノードを LANで接続して共有フォルダ(これは現在一般家庭にも普及しつつある形で、NASという)を使うのでは駄目なの?という疑問が沸くかもしれない。面倒なので詳しい理由は説明しないが、高速な並列処理に必要なのは「共有のフォルダ」ではなく「共有のディスク」、もっと言うならば共有のブロックデバイスであり、NASは主に性能上の理由で SANの代わりにならない。

クラスタリング以外にも SANの用途はある。最近急速に普及してきているサーバ仮想化技術がそれだ。仮想サーバに必要なリソースである CPUとRAMとストレージのうち、CPUとRAMは(極端な話をすれば)幾らでも換えの効く使い捨てのものであるのに対し、ストレージだけは中に永続データを保持する以上そういうわけにもいかないため、物理的に一カ所へまとめて集中的かつ大切に運用管理できる方が良い。つまり多数のノード(CPU,RAM)と一つの共有ストレージ、そしてそれらを接続するネットワークという構図が出来る。
この事から、サーバ仮想化技術は SAN、とりわけ iSCSIと組み合わせて用いられるケースが多くなっている。並列コンピューティングと違い仮想化技術は中小規模の事業者にとっても必要かつ導入しやすく、また費用対効果の高い技術であるため、低コストで構築できる iSCSIはこの分野において存在感を増しているのだろう。なおVMWareも商用版Xenも iSCSIをサポートしている(Virtuozzoはストレージを仮想化しないためSANと直接は関係ない)。

さて、SANと iSCSIの話を延々としてきたのは、Linuxの iscsitarget (ited) と open-iscsiを組み合わせて主にXen用に SANを構築運用する方法のメモを記そうと思ったため、その前置きである。前置きだけで終わるかもしれない。続くかもしれない。

ラベル:

int15デバイス以外にgrubをインストールする


Linuxのブートローダといえば昔は LILOだったが今は grubである。私は遅くまで LILOで頑張っていた方なのだが、64bitアーキテクチャへの移行を機に grubへ移行せざるを得なかった。
ブートローダというものは普通、OSのインストーラがよろしくやってくれるため自分でインストールする必要はない。
が、インストーラを使わずに Linux環境をセットアップするのがスタンダードになってしまった我が社では grubも自分でインストールするのである。

grubのインストール方法を普通に調べると、BIOSが認識しているディスクドライブ(つまりint15デバイス)へインストールする方法が紹介されているのが一般的である。ブートするためのディスクにインストールするのだから当然なのだが、写真のような起動デバイスを用いる場合は既に Linuxが稼働しているマシンを使って USBのカードリーダーなどを経由してブートローダーをインストール出来た方が簡単だ。

(今更ながら繰り返し断っておくと、あくまでインストーラを使わずに Linux環境を構築する場合の話である。主に Gentooが該当する)

BIOSによって認識されていないディスク、つまり USBなどで接続された記憶装置(のMBR)へ grubをインストールする方法は下記のとおり。

/dev/sdaが対象デバイスだとしたら、fdiskでパーティションを作って ext2でフォーマットし /dev/sda1 とする。
てきとうな場所に boot という名前のディレクトリを作成してこの /dev/sda1をそこへマウントし、grub-installコマンドを実行することで grubとその構成ファイルがインストールされる。

mount /dev/sda1 /mnt/boot
grub-install --no-floppy --root-directory=/mnt /dev/sda

後はこのパーティションにカーネルやらinitramfsやらをコピーする。
さらに、grubにメニューを表示させる場合は /mnt/boot/grub/menu.lstを作成すること。

GentooのXenで network-bridgeが上手くできない場合

xendの起動時に実行される network-bridgeスクリプトは元の物理的な eth0を peth0 にリネームしたうえでIPアドレスを剥奪し、代わりの eth0を作成して元のIPアドレスを付け直すという動作をする(SSHで接続した端末から xendの起動をすると切断されてしまうのはこのためだ)。

しかし Gentooの場合、普通に emergeしたての xendを起動すると、peth0は出現するものの元の eth0 が作成されず通信できない状態になってしまうことがある(私の所だけなのか?)

この場合、network-script内で addr_pfxを取り出している部分を書き直すことで問題を回避できる。
get_ip_info() {
# addr_pfx=`ip addr show dev $1 | egrep '^ *inet' | sed -e 's/ *inet //' -e "s/$1//"`
addr_pfx=`ip addr show dev $1 | sed -n 's/^ *inet \(.*\) [^ ]*$/\1/p'`
gateway=`ip route show dev $1 | fgrep default | sed 's/default via //'`
}

ラベル: ,

2008-02-10

lspci, lsusb, lsscsi

自作機でLinuxを使っているときに便利なコマンド。

PCIバスに刺さっているハードウェアの一覧を出力する lspci
USBに刺さっているハードウェアの一覧を出力する lsusb

そして今日発見したのは、SCSIバスにつながっているデバイスの一覧を出力する lsscsi
[0:0:0:0]    disk    HPT      DISK_0_0         4.00  /dev/sda
[2:0:0:0] disk ATA WDC WD5000KS-00M 07.0 /dev/sdb
[4:0:0:0] cd/dvd PIONEER DVD-RW DVR-212D 1.21 /dev/sr0
[6:0:0:0] disk ATA Hitachi HDT72505 V56O /dev/sdc
[7:0:0:0] disk Multi Flash Reader 1.00 /dev/sdd
[8:0:0:0] disk Generic- Compact Flash 1.00 /dev/sde
[8:0:0:1] disk Generic- SM/xD-Picture 1.00 /dev/sdf
[8:0:0:2] disk Generic- SD/MMC 1.00 /dev/sdg
[8:0:0:3] disk Generic- MS/MS-Pro 1.00 /dev/sdh
こんな風に出る。

RAIDコントローラやらUSBストレージやらシリアルATAやらてんこ盛りで接続しているホストで、デバイスが行方不明になった時に便利。

2008-02-09

iscsitarget 0.4.15をカーネル2.6.24用にビルドする

Linuxカーネル 2.6.22, 2.6.23, 2.6.24 で行われたSCSI周りの変更でそれぞれアオリを受け毎回ビルドできなくなってしまったかわいそうな iscsitarget なのであった。そのせいかどうか知らないが、Portageのメンテナもやる気なさそう。

というわけで 2.6.24で iscsitargetをビルド出来るように自分に頑張ってみた(だって、これがないとうちの Macは TimeMachineできないのだよ)。幸い、コンパイルエラーとなる部分はiSCSIサービスを提供するためのカーネルモジュール部分 (iscsi_trgt.ko)に集中している。

最初は自分でコンパイルエラーとカーネルヘッダファイルを追いかけて修正を進めていたのだが、処理の意味を理解していないままの機械的修正では行き詰まってしまい何とかなるまいかと iscsitarget-develメーリングリストを確認したところ、数日前に 2.6.24用パッチが投稿されていたのを発見する。オーノー。無駄な労力を払いましたか?

がーしかし。これは trunk用のパッチなので、リリースされてるバージョン(iscsitarget-0.4.5)のソースツリーにそのままでは使えないのである。仕方ないのでひたすら trunkと 0.4.5をdiffしつつ 0.4.5用に作成しなおしたパッチがこれ。努力の結晶。多分こんなもん俺しか使わないけどね。っていうか Portageのメンテナがやる気になるまでの間しか価値ないけどね。

iscsitarget-0.4.15-kernel.2.6.24.patch
注:無保証!!うちの環境でしかテストしていない。

・・・2.6.25でまたコンパイル出来なくなるってオチも無しでお願いしたいところ。

(2008-3-1追記)
Portageのほうにパッチが追加され、解決した模様。
下記は今後似たような状況が起こったときのためにメモとして残しておく。

---ここから
Gentooユーザーのために、これを ebuildにくっつけて emergeする方法をメモしておく。多分そういう人少ないけど。
ebuildの fileディレクトリにこのパッチを入れ、ebuildファイルの src_unpack() 内に

epatch ${FILESDIR}/${PN}-0.4.15-kernel.2.6.24.patch

を挿入する。
ebuildファイルを変更したので、

ebuild iscsitarget-0.4.15-r1.ebuild digest

として digestを更新する。(これをやらないと ebuildファイルが改ざんされてるぞ!とエラーが出て emergeできない)
後は普通に emerge iscsitarget すればよし。unmaskとかは適宜すること。

ラベル:

2008-02-06

debootstrapで作ったUbuntuでdevelopment

UbuntuだけじゃなくてDebianもそうなのかもしれないけど、debootstrapで作った環境は本当に最小限だけの構成になっているので

make
gcc
libc-dev

を入れないと仕事に使えないのだった。

2008-02-05

Rails+WebORBがものすごく遅い時

Ruby 1.8.6のビルド時に pthreadsが組み込まれていると、なぜか RailsでWebORBを動作させた時にものすごく遅い。
ldd /usr/bin/ruby してみて libpthread.soがリンクされていたらそういう状態。
Portageならば emergeするときに USE="threads" があるとそうなる。

vmstatを見たところ、pthreadがリンクされている場合は systemが特にCPU時間を使っている(userはあまり変わらない)ようだ。
Rubyでは、pthreadの有無で動作を分けている箇所は eval.c に集中しているみたいだが、ソースをチラ見したところで原因になりそうなところがどこかはわからなかった。

とにかく、Rubyの動作が遅くて systemにCPU時間が取られているようなら pthreadがリンクされていないバイナリへ取り替えることを試してみた方がいいかもしれない。

YARVなら(Giant Lockで排他的にしか実行されないとはいえ最初からネイティブスレッドを使っているため)こういう問題なさそうだなあ。はやく Ruby1.9で Railsが動くようになればいいな。(いまは動かないよね?)

ラベル: ,