prasinos' work memo

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

GRIB 電文採取範囲の拡大

気圧と気温だけでは実用的でないので、/^([HXYZ][BEPHTUV]|OT)/ まで拡大した。今のところ激変はないが、テキスト電文の遅延が起こらないか24時間は監視する必要がある。
スポンサーサイト

計算機モニタ状況

昨日12時以来テキスト電文の大規模遅延は発生していない。めでたい。 db-stn-day-060330.png
それから、古いデータの削除を進めている finch だけど、10万レコードづつ削除する batch スクリプトは約5分間隔で起動していた模様。LDM の大量入電などで負荷が高まると当初はロードが跳ね上がるが、その後 batch 起動が遅延するので、大局的には負荷の一様化の機能を無事果たす、というシナリオが実証されている。100万レコードづつ削除したときより10万レコードの時のほうが負荷の動向にすばやく反応するので15分平均ロードアベレージを下げることが出来る模様。 cpu-day-060330f.png
とすると、非緊急性の大規模計算をやろうとすると、5分程度で batch で区切るということになるのだろうか。なかなか5分で終らせるのは難しいのではないか。そうすると SIGSUSP/SIGCONT 作戦という手もありうるが。

格子配置がいっぱい

まずは NCEP proc=96 についてみる。 200番台は米国特有のランベルト・正軸平射図法の格子。 こいつらとはあんまり御友達になりたくないなあ。
select gridcode, count(nx) as count from tmp_grb where proc = 96 and rt = '2006-03-29 00:00:00' group by gridcode
gridcode	count
37	40
38	40
39	40
40	39
41	40
42	39
43	40
44	39
201	32
202	76
203	99
211	61
213	18
ECMWF は次の通り。10番台がよくわからない。
select gridcode, count(nx) as count from tmp_grb where ctr = 98 group by gridcode
gridcode	count
1	46
2	46
3	47
4	47
9	44
10	44
11	43
12	43
UKMO は 30/40 番台。
select gridcode, count(nx) as count from tmp_grb where ctr = 74 group by gridcode
gridcode	count
37	45
38	44
39	46
40	44
41	44
42	45
43	44
44	44
255	7

高度と要素の関係

高度ごとに与えられる要素が決まっている。 ヘッダの2文字目は要素、末尾2文字が高度に対応する。 カウントが少ない組み合わせは限られた時間にしか配信されないのだろう(... と思ったらそうではなかった。 どうやら色々のプロダクトがあるようだ)。
select lev1, lev, param, hdrs, count(nx) as count from tmp_grb where proc = 96 and rt = '2006-03-29 00:00:00' group by lev1, lev, param, right(left(hdrs,2),1), right(hdrs,2)
lev1	lev	param	hdrs	count
0	1	1	YPAD98	4
0	6	7	HHLK96	3
0	7	1	ZPIV97	3
0	102	2	YPJK89	15
2	105	11	HTLK98	4
100	100	7	YHIE10	21
150	100	7	YHJK15	8
150	100	11	YTHG15	1
200	100	7	YHIE20	20
200	100	11	HTKD20	2
250	100	7	YHAE25	14
250	100	11	YTJL25	1
300	100	7	ZHJV30	24
400	100	7	YHJK40	13
400	100	11	HTIJ40	1
500	100	7	YHAN50	34
500	100	11	HTII50	73
600	100	11	HTII60	76
700	100	7	YHAE70	20
700	100	11	HTII70	77
725	100	7	YHQX72	1
775	100	7	YHQG77	1
800	100	7	ZHQT80	1
850	100	7	YHHM85	33
850	100	11	HTII85	77
875	100	7	YHQD91	3
900	100	7	ZHQZ90	3
925	100	7	YHQH92	12
950	100	7	YHQN95	9
975	100	7	YHQH93	15
1000	100	7	YHHB99	32
1000	100	11	HTLK99	2

NCEP 全球モデルの構造: 予報時間

面白いことに 00Z と 06Z/12Z でサブセンターが違うらしい。 時間ごとにカウントが微妙に違うのは取りこぼしがあるようだ。
select distinct sub, rt, ft1, count(nx) as count from tmp_grb where proc = 96 group by sub, rt, ft1
sub	rt	ft1	count
0	2006-03-29 00:00:00	6	46
0	2006-03-29 00:00:00	12	47
0	2006-03-29 00:00:00	18	47
0	2006-03-29 00:00:00	24	45
0	2006-03-29 00:00:00	30	45
0	2006-03-29 00:00:00	36	40
0	2006-03-29 00:00:00	42	47
0	2006-03-29 00:00:00	48	46
0	2006-03-29 00:00:00	54	13
0	2006-03-29 00:00:00	60	46
0	2006-03-29 00:00:00	66	13
0	2006-03-29 00:00:00	72	44
0	2006-03-29 00:00:00	78	12
0	2006-03-29 00:00:00	84	15
0	2006-03-29 00:00:00	90	12
0	2006-03-29 00:00:00	96	13
0	2006-03-29 00:00:00	102	11
0	2006-03-29 00:00:00	108	13
0	2006-03-29 00:00:00	114	12
0	2006-03-29 00:00:00	120	14
0	2006-03-29 00:00:00	126	2
0	2006-03-29 00:00:00	132	2
0	2006-03-29 00:00:00	144	2
0	2006-03-29 00:00:00	156	2
0	2006-03-29 00:00:00	168	2
0	2006-03-29 00:00:00	180	2
0	2006-03-29 00:00:00	192	2
0	2006-03-29 00:00:00	204	2
0	2006-03-29 00:00:00	216	2
0	2006-03-29 00:00:00	228	2
0	2006-03-29 00:00:00	240	2
0	2006-03-29 06:00:00	36	6
0	2006-03-29 06:00:00	66	1
0	2006-03-29 06:00:00	78	1
0	2006-03-29 06:00:00	90	2
0	2006-03-29 06:00:00	114	1
2	2006-03-29 12:00:00	6	1
2	2006-03-29 12:00:00	18	2
2	2006-03-29 12:00:00	24	1
2	2006-03-29 12:00:00	30	1
2	2006-03-29 12:00:00	42	2
2	2006-03-29 12:00:00	48	2
2	2006-03-29 12:00:00	60	2
2	2006-03-29 12:00:00	66	1
2	2006-03-29 12:00:00	72	1
2	2006-03-29 12:00:00	84	1

データセットの種類

さてデータセットの種類はどれだけあるのだろうか。 作成処理番号をみればよい。
select distinct ctr, sub, proc, count(nx) as count from tmp_grb group by ctr, sub, proc order by ctr, proc
ctr	sub	proc	count
7	0	10	32
7	0	39	151
7	4	44	7
7	2	80	103
7	0	80	104
7	0	81	46
7	0	82	14
7	0	84	135
7	0	86	15
7	0	94	231
7	0	96	614
7	2	96	14
7	0	105	4
74	0	15	39
74	0	45	324
98	0	127	360
NCEP の資料から抜きだしてみると
10
	Global Wind-Wave Forecast Model
39
	Nested Grid forecast Model (NGM)
44
	Sea Surface Temperature Analysis
80
	62 wave triangular, 28 layer Spectral model from "Medium Range Forecast" run
81
	Spectral Statistical Interpolation (SSI) analysis from  GFS model
82
	Spectral Statistical Interpolation (SSI) analysis from "Final" run.
84
	MESO ETA Model (currently 12 km)
86
	RUC Model, from Forecast Systems Lab (isentropic; scale: 60km at 40N)
94
	T170/L42 Global Spectral Model from MRF run
95
	T126/L42 Global Spectral Model from MRF run
96
	Global Forecast System Model (formerly known as the Aviation)
T382 - Forecast hours 00-180
T190 - Forecast hours 192 - 384
105
	RUC Model from FSL (isentropic; scale: 20km at 40N)

データの構造

さてデータを絞る必然性はあまりなくなったが、それでも知りたいのでデータの構造を調査する。とりあえず LDM のスプールに転がっているファイルからヘッダや PDS の情報を抽出する。

LDM で着信した GRIB の一覧 (reftime 03/29/06)

こんなテーブルを作ってロードしたら調査開始。 続きを読む

pqact.conf の書き順が優先度

のようである。 試しに GRIB のファイル書き出しの順位を下げてみると、あら不思議、あの憎たらしい 「後回し→GRIBが来なくなったらバースト投入」 が起こらなくなった。 db-msg-day-060329r2.png 最後の12時以降バーストが起こっていない。この間も大量にGRIBが着信している

ファイルの記述順による優先度管理は限界もあるだろうけど、まあとにかく実現できないよりできるほうがマシ。よかったよかった.... かな? 明日も様子をみるべきだろう。

ロードアベレージは下がったが

Pqact からファイルに書かせることにしたら、ロードアベレージは劇的に下がった。
2日 CPU 利用率の低減に成功
1週 ロード(一週間ぶん)
しかし副作用があった。GRIB 着信時に警報データがそっちのけになってしまい、DB更新が滞るのである。次のグラフのスパイク(緑の突出した線)は滞っっていた期間に溜まった警報電文がGRIBの着信後に一括処理されている様子である。 GRIB着信時に警報DB更新が滞っている
次のグラフは同じ時期の finch の警報データベースの更新速度。比較的一様に着信していることがわかる。
GRIB負荷のない警報DB更新状況

抜本的対応策はいまのところない。LDM に優先度の概念がないようだから、結局のところサーバを分けるしかあるまい。 対症療法としては、警報電文の遅延が許容できる程度に収まるまで、GRIB電文の処理量を削減するしかない。Pqact が問題なので pqact.conf のパターンを制約するほかない。すでに /^[HYZ][PHT]/ くらいまでは絞っているので、ヘッダと電文内容の対応関係をさらに調査する必要がある。昨日気が付いていたことだが、ついにやらなければならない時が来た。

SELECT ... INTO OUTFILE は速い (あたりまえだ)

finch のディスクがいっぱいになりかかっているのを忘れていた。つまり、データを消さねばならない。そこで (追記: 消す前にはバックアップということで) SELECT ... INTO OUTFILE を試してみた。(5 カラム 100 バイトくらいのデータを書き出すのに) 100万レコード当り1分52秒くらいかかるようだ。直接くらべることはできないが、データベースのレコード毎コピーを行なう ruby プログラムが100万レコードあたり25分くらいかかったのを思えば劇的に速い。

やっぱしソケットを通さないと速いんだわな。

(追記) やっぱり削除はすごい遅い。一応、CD-R に焼いた部分だけ削除することにした。で、10万レコードづつ削除する mysql コマンド行を 100 個くらい生成してそれぞれ batch(1) に喰わせておくと、ロードアベレージが下がったときだけ実行される。これはうまくいっているようである。

なんと、データ抜けなし

GRIB データベースの処理負荷でマシンが半死半生になっていた。その間テキスト系データベースの遅延が酷かったのだけれど、調べてみるとなんと METAR はデータ抜けがなかった。LDM の同期能力は恐るべきことだ。

しかし、データ量にしてみればより小さいはずの警報のほうがデータ抜けを起こし易いのはなぜだろうか? 警報は改行がデータ境界になっていないから pqact のブロックを起こし易いのかなあ。しかしよくわからん。

ともあれ、一日いろいろやって得た結論は、「動いているプログラムはいじらないほうがいい」という凡庸なものになりそうだ。

つづき

どうも話が奇麗にまとまらない。なんか欝だ。 これは早く帰って寝るべきシチュエーションだとは思う。

負荷低減策として、pqact の一時格納先をディスクにすべき。 とりあえず、安易に全保存して負荷およびデータ流量の状況をウォッチすることにしよう。

で、ディスクに保存されたデータを監視してDB登録するプログラムを書くんだろう。データ本体はあくまで生ファイルで、DB はファイル名とオフセット(始点・長さ)だけ管理する。 保存データは誰が消去するかは悩ましいところだが、simple is the best で scour にやらせてしまうのがいいような気がする。Scour でいけない理由があるとすれば、長期保存ができないということだが、これは DB からファイルを参照する際に一段別の表をかましてファイル名を相対化すればいいことである。

ところで先日の名前つきパイプと sysread の議論の成果はいきなり使われないことになる。これはもったいないので、早めに metar & 警報データベースに活かさないといけない。そっちが先か。

データサイズとの戦い

人生は甘くない。

LDM の HDS フィードで流れてくる GRIB をまるごと MySQL データベースに投げこむ想定で今まで設計してきた。 で、とりあえず安直にプログラム作って走らせてみると、ロードアベレージが恒常的に 5.0 をキープしてコンピュータが使いモノにならない状態になってしまった。 他のデータベースの更新も滞っている模様だ。 あまり正確なデータではないが、少くとも1日2000通以上やってくるようだ。1時間1566通というのが記録されていて、その後は恐らく過負荷で取りこぼしを起こしているのだと思う。

とりあえず、

  • データの種類を目茶苦茶絞る
  • 1GRIB を格納するごとに 60 秒 sleep して他タスクを動かす時間を作る
という安易な方策をとって負荷は問題にならない程度に抑え込んでいるが、ダメだこりゃ。

したがって、もうちょっとマシな形態を考えないといけない。

生GRIBをとりあえずとっておくデータベースの作り

これから考えようと思って、 ふと立ち止まって自分のブログを検索すると、 出て来るんですね。 昔の俺って偉い。

要変更点は、

  • time という名前はけしからんので vt1 との整合性から rt に変更
  • 名前をちょっと長くしようと思った (がやっぱりやめた。la1 とかとの整合性がある)。
  • いかにも長過ぎるので、ldmbfile(ctr, sub, proc, rt), ldmpfile(bfile, vt1, vt2, lev1, lev2, param), ldmraw(pfile, nx, ny, la1, lo1, la2, lo2, code, asof) に分割。これはどっちかというと unique key を短くする目的かも。
  • 完成したか否かを表わす表 ldmrecv(bfile, asof) を追加。これは pfile に対して作成してもいいかもしれないが。

つづき: File::NONBLOCK を忘れずに

前項のつづき。 実験してみて考え足らずがわかった。

pqact が生きているが沈黙しているとき、EAGAIN が起こるはずなのに、ほとんどの場合 IO#sysread でブロックを起こしてしまった。 なぜだろうと思ったら、ファイルを開くときに File.open(pipe, 'r') などと書いていた。 正しくは、 File.open(pipe, File::RDONLY | File::NONBLOCK) である。 続きを読む

この道はいつか来た道

名前つきパイプに断続的に書かれるデータを追跡するプログラム。以前に作った weatherdb では IO#read が nil? を返したら sleep するという安易な作りだった。当然 IO.select を使うべき局面であると思われる。何故こんな作りにしたのか思いだすのにかなり時間がかかった。 続きを読む

[障害] robin の weatherdb 止まってました

やっちゃった。 LDM パッケージの入れ換え後しばらく robin で DB 更新が止まっていました。 METAR DB の更新速度 (2006-03-26) METAR DB
警報DB更新状況 2006-03-26 警報DB

原因はパスワードファイルの生成忘れ。馬鹿すぎる。 今までは cron で動かしていたものだったのでバシバシメールが出て来ることで問題に気が付いたのだけど、デーモンだったので気が付かなかった。これは悩ましい問題である。

一方、失われたデータを finch からコピーバックしようとしたら、SQL クエリが死ぬ程遅い。慌てて調べてみると finch の nwp.stnbull に time インデックスがないことが判明。あうー。

インチキ時系列 WMS 完成

WMS には本来時系列を表現する次元というものが備わっている。が、どうせそんなもんマトモにサポートするクライアントは少いだろうし、それでも時系列が見たいときは見たいのだ。という安易な想定のもと(もうちょっとリサーチすべきだけど)、サーバ URL に時刻をまぜこんでしまうやっつけ仕事をしてみた。要するに、時刻別の WMS がある恰好で、利用者はウェブの一覧から WMS の URL をいちいちコピペして使うことになる。 クライアントに手を入れないと、どうしてもこういう不便なことになってしまうが、しかたないだろう。

ともあれこういうことができるようになった。 uDig: 前線の重ね書き 3/22 21Z, 3/23 09Z, 21Z
3/22 21Z, 3/23 09Z, 21Z の前線を重ねて描いたもの

Shapefile の文字列を UTF8 に変換するスクリプト

あまり意味ないと思いますが、いちおう。

uDig の出来がよいことはわかったので、日本語のファイルを表示してみるとやっぱり化けてしまいました。で、現在 UTF8 ロケールなので UTF8 にするといいことあるんじゃないかと思ってこのスクリプトで変換したけどだめでした。Java のことはよくわかりませんが、シェープファイルから拾って来たバイト列を String にするところで latin1 をあてにしているようです。化け方を観察すれば Latin1 扱いされていることはすぐわかったはずなのですが、このところ腕が鈍っていることがわかってしまいました。 続きを読む

[RHEL4] OpenEV はまじめにコンパイルしないとダメぽい

OpenEV も試してみようと思った。 どうやら、本体ではなく python スクリプトのアドオンで WMS をサポートするという方向のようである。

まずは本体のインストールから。バイナリ配布が2種類ある。でも FWTool は mapserver とか要らないものをいっぱい含んでいるので、とりあえず Vexcel 版にしてみることにした。要するに単体では動く。Mesa も python も全部入っているみたい。

[追記: OpenEV のスクリーンショット。UI は ArcView 3 に似ているような気がする。たしかにたくぼさんの言う通り、ちょっとこなれていないというか、ArcMap から入ったぼくはまごつくところがあります] OpenEV のスクリーンショット

ところがその後がいけない。 続きを読む

いいかげん覚えよう AutoReqPriv

udig パッケージを作ろうとしてはまったこと。

かたじけなくも RPM 様はビルドルートを全探索して、パッケージに必要な共有ライブラリとスクリプト言語をすべて検出して依存性に追加してくださるのだそうです。したがって、 udig の片すみに libodbc.so に依存する何かが落ちていたら、 Requires: に何も書かなくても (何か書いても) libodbc.so に依存することになります。ここまでは何も間違っていません。

ところがどういうわけだか RedHat 様の作って下さる unixODBC パッケージは腐っていて libodbc.so が入っているのに libodbc.so が provide されていません。一体どうやったらこんな RPM が作れるのかわからないけれど、

$ rpm -ql unixODBC | grep libodbc.so
/usr/lib/libodbc.so
/usr/lib/libodbc.so.1
/usr/lib/libodbc.so.1.0.0
$ rpm -q --whatprovides libodbc.so
libodbc.so を提供するパッケージは存在しません
という始末。そこで、何も間違っていない udig パッケージがインストールできないわけ。 こういうときは RPM 様に「俺が依存関係を正しく指定するからお前は黙ってろ」と言うしかありません。 具体的には SPEC ファイルでこうします。
Requires: unixODBC, unixODBC-devel
AutoReqProv: no
この術は Maximum RPM ( このページのいちばん下)に書いてありました。

uDig ナイス!

さて、WMS クライアントになる GIS. たくぼさんのコメントに従い、まず uDig を使ってみました。ナイスです。

Walkthrough くらい試してみればいいのだけど、スットバして自前データを表示してみます。 先日の天気図WMSを表示
先日の天気図WMSを表示(データは06年2月28日03Zのまま)。 なぜか透明モードで読もうとするので Geography Network から取って来た植生データから「海」だけを下に敷いて青くした(あ、安易...)。
陸地のカラー表示高度を追加
天気図WMSの真白な陸地を消して、オランダの demis.nl からとってきた「陸地の高度 topography」レイヤを海の上にさし込んでみた。 続きを読む

はてブを rubyco さんが読んでいた件

はてなブックマークのコメント欄にはけっこうぞんざいなことを書いてきました。以前問題にされていたほどではないと自分では思っていますが。

先日 rubyco の日記の「Signal.list」というエントリをブックマークしたときに「errno のリストもほしい」と書いておいたら、rubyco さん読んでいたようで書いてくれました。別に悪いことはなにもないのですが、rubyco さんが読んでいると思っていたらもうちょっと丁寧に書いたかなあ。これはちょっと恥ずかしい。

はてブを rubyco さんが読んでいた件

はてなブックマークのコメント欄にはけっこうぞんざいなことを書いてきました。以前問題にされていたほどではないと自分では思っていますが。

先日 rubyco の日記の「Signal.list」というエントリをブックマークしたときに「errno のリストもほしい」と書いておいたら、rubyco さん読んでいたようで書いてくれました。別に悪いことはなにもないのですが、rubyco さんが読んでいると思っていたらもうちょっと丁寧に書いたかなあ。これはちょっと恥ずかしい。

mapserver で作った絵を自分で描いたふりをして返す CGI 完成

というわけで、一見 RDB のテーブル閲覧 CGI が ついでに絵まで描いちゃいましたよ的な動きをしていながら、 実は内部で
  • ディスクキャッシュに同じキー(時刻)の絵があったらそれを読むだけ
  • そうでなかったら
    • DB から shapefile を掘り出して
    • テンプレートからファイル名だけ置喚した mapfile をでっちあげ
    • WMS 風の URL でローカルホストの UMN mapserver にアクセスして絵をゲット
    • いちおうそいつはディスクキャッシュにしまっておいて、
    • ディスクキャッシュがいっぱいになったら一番古いファイルを消す
なんてのをやっちゃいます。

しかしここまで頑張ったのに応答がいまいち遅いのが気に喰わん。もひかして、CGI だとブラウザのディスクキャッシュが効かないとかいう問題かなあ。 だとすると、viewer.cgi/foo/bar/baz みたく CGI のクエリ文字列をパスみたくみせかけることで解決するかもしれないが、ちょっと今日は疲れたからおしまい。

天気記号のパッケージを分ける

データベース本体から記号アイコン類を分けることにした。 表の理由は複数の異なるパッケージから共有できるように記号類を充実していきたいから。 裏の理由はは非常に遅いスクリプトで描画されているのであんまり RPM のリビルドをしたくないから。

クラス数の制限

mapserver のクラス数に制限がある問題だが、メッセージに対応するソースコードを追うと
  • mapfile.c:2368: レイヤあたりのクラス数が MS_MAXCLASSES を超えると "Maximum number of classes reached.", "loadLayer()" と言って死亡
  • layerobject.c:67: 同上の条件で "Max number of classes, %d, has been reached.", "msInsertClass()" と言って死亡
といったあたりのようだ。 MS_MAXCLASSES は map.h で 250 に指定されている にもかかわらずなぜ 40 クラスくらいしか指定できないのかは 謎であるが、ともあれここを拡張すればよいのであろう。

しかしだね、realloc するとかなんとかできんのかね。

引き続き調査課題。

[AS3] subversion はやぱし自力パッケージングだなこりゃ

昨日 RHEL AS3 に subversion がないのではまった。そのときはファイル転送でごまかしたが、こういうことを放っておいてはいけない。で、わけわかにならないように RPM 化しないといけない。

製造元のほうでいくつか RPM が紹介されているので独断と偏見により http://dag.wieers.com/packages/subversion/ のものをためしてみる。 気持ち悪いのでこういうときは必ず SRPM から... しかしビルドできない。 neon-devel が必要だと言う。 ソースコードに neon が入っているくさいのでそこらへんをいじってみると、なにやら python がらみの syntax error とかで make が落ちる。python は使わないのでこれ以上の追究を断念。

やはりこれは SPEC をスクラッチアップするしかなさそうだ。うざい。

[LDM/RPM] 一応動いている

昨日こういった。
一応動くようになったが、robin にインストールする前に一晩様子を見よう。共倒れになるのはいけない。
一応動いているようである。でも、思いだしてみると手動で /etc/ldm/daemon.d/* を上げたので気持がわるい。 もいっぺん /etc/init.d/ldm stop と /etc/init.d/ldm start だけでやりなおしてみる。 2006-03-22-db-msg-day.png

なお、流量が激減しているのは DB に転送する正規表現パターンを絞ったから。米国以外の警報はとりあえず利用の見通しが立たないのでやめておく。

これで 1pm 以降のデータが入っていれば大丈夫なので robin もアップデートしてしまおう。

[RHEL4] sendmail のバージョンアップ

があった。up2date の挙動がまた怪しいが、
$ rpm -q sendmail sendmail-8.13.1-3.RHEL4.3
といっているのでいいことにする。

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。