2018-01-12

(メモ)JMX Atom Feed を追う最小プログラム例

使い方を要件ならべるだけじゃなかなか普及しないので、プログラム例を書いてみようと思ったのです。

以下、ちょっと書きかけも混じりますが。

# 構成
## プログラム構成

+ *jmxpull*: DB作成の低水準フェーズ。Atom Feed をポーリングして電文実体を拾ってきて入電DB(独自設計)に保存するプログラム。
+ (JMH や低解像度 GPV なども同じDBを共用する)
+ *db.cgi*: DBの低水準インターフェイス。単電文抽出と一覧だけをさせて、頻繁な機能改修から隔離する。
+ *jmxindex*: DB作成の高水準フェーズ。電文分類検索のためのインデックス作りを行う。
+ *msg.cgi*: DBの高水準インターフェイス。分類別一覧や種類別スタイルシート適用などを行う。

高水準といっているが、これで終わりじゃなく、この範疇ではない「さらに高水準」を作るための基盤である。

## ファイル構成

RDBMS は使わない。
大前提として、逐次追加されるデータ量が結構大きいので、恒久アーカイブを作るのはディスク量的にかなり高くつく。
FIFO的に古くなったデータをDBからは落としていくことにせざるを得ないのだけれど、そのようなハウスキーピングでDBサーバが一時的に高負荷になって新着が処理できなくなるのはかなりダメだし、
もったいないからアーカイブしておきたいのでトリガーが欲しいなど、いろいろ注文がある。
どうせ古いデータを緊急に消したいときは本当に急ぐので、 rm(1) の所要時間程度で消せるようにしたい。

* データベースディレクトリは /var/local/jmxdb/
..* db/config                        GDBM形式、全体設定
..* db/latest                        後で {yyyymmdd} にリネームされる
..* db/latest/rawdata.1                データ本体を書き出すファイル
..* db/latest/index1.1                GDBM形式、低レベルインデックス1日分
..* db/latest/index2.1                GDBM形式、高レベルインデックス1日分
..* db/{yyyymmdd}/rawdata.1
..* db/{yyyymmdd}/index1.1
..* db/{yyyymmdd}/index2.1
..* db/sindex1.1                        GDBM形式、昨日以前の全期間の低レベルインデックス(参照用)
..* db/sindex2.1                        GDBM形式、昨日以前の全期間の高レベルインデックス(参照用)

新しい日付ディレクトリは jmxpull を起動するスクリプトが冒頭で作る。ディレクトリのローテーションをするタイミングで sindex も差し替える。この間は jmxpull が起動しないよう抑止しておかねばならない。

## DB構成

### rawdata 内フォーマット

### index1

### index2

# アルゴリズム
## 起動タイミング

+ jmxpull は毎分cronで自動起動する。
  正確には4つのフィードについて4回 jmxpull を起動するスクリプトが毎分自動起動する。
  1分で取得処理が終わらない場合は後続が重複起動を検知して終了する。
+ 重複起動検知手法としてはさしあたって、 jmxpull が起動しているあいだじゅう db/latest/index1 をロックしておくことにして、GDBMのロック取得失敗による例外が起こるのでそれを使う。
  いずれ緊急報とバーストデータで別インスタンスを動かせるようにファイル名に何かサフィクス(上記例では .1)をつける。
+ jmxpull の稼動を一時的または恒久的に抑止できるようにするため、 db/config 内にセマフォのような抑止エントリを設ける。抑止解除の日時を %Y%m%dT%H%M%S 形式で書かせることにしておいて、9999年解除とすれば事実上永遠ということでよかろう。
  参照側はロックしなくてよく、ゆえに多数インスタンスで共用してさしつかえない。
+ jmxindex は jmxpull からキックする。 これは db/latest/index2 をロックして排他する。

## 単電文の格納

rawdata ファイルは、FORTRANシーケンシャルファイル(4オクテットのレコード長でペイロードを挟んだシーケンシャルファイル)とする。べつにFORTRANで読むつもりはないが十分効率的。
メタデータ(Atom Feed 内の情報)は重複感があるけれど JSON にして奇数番目のレコード、データ本体を偶数番レコードにするのがよかろう。
防災 XML だけを扱うのであればメタデータなど捨ててしまってもよいのかもしれないが、非テキストなデータを混ぜ込むならメタデータは必要。このさい単レコードにメタデータとデータ本体を詰め込む複雑なレコードフォーマットを開発しないほうがよい。
データ本体をgzip圧縮するかどうかは、ストレージコストを評価するのであれば見合うかもしれない。

単電文を格納する毎に処理をキックすることは、急いで実装しないが、津波だけ緊急処理というようなことを考えると、メタデータを見て分岐ということになる。


## 単電文の検索


## 高レベルインデックス作り

0 件のコメント:

コメントを投稿