ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

Asakusa Frameworkで10億件のFizz Buzz

2017-12-25 00:00:00 | PG(分散処理)

FizzBuzz Advent Calendar 2017の25日目です。
Asakusa FrameworkでFizz Buzzを書いてみました。

Asakusa FrameworkはJavaでバッチアプリケーションを開発・実行する為のフレームワークです。
特徴は、大量のデータ(いわゆるビッグデータ)を処理するのに適していること(分散並列処理)と、
実行基盤としてApache Hadoop・Apache SparkM3BPを使用できることです。(同一のソースから、それぞれの基盤で実行できるバイナリー(jarファイル等)を生成できます)

AsakusaFWは結構重厚なフレームワークなので、本来はFizz Buzzのようなシンプルなアプリケーションには向いていないのですが、面白そうなので作ってみましたw
ソースは長くなるのでそちらを参照してもらうとして、ポイントだけ挙げておきます。


入出力

AsakusaFWはファイル(HadoopのHDFS上のファイルが基本だが、ローカルファイルやAmazon S3、RDBのテーブルでもよい)を読み込んで加工し、ファイルを出力する構造になっています。
つまり、入力が全く無い状態からデータを作り出すという事は出来ません。

そこで、数値が入ったファイルを用意し、その数値をFizz/Buzzに変換したCSVファイルを出力することにします。

↓入力ファイルの例

1
2
3
4
5

↓出力結果

1,1
2,2
3,Fizz
4,4
5,Buzz

データの並び順

AsakusaFWは分散処理を行う(入力データを行毎に分割して並列で処理する)ので、基本的にはデータの並び順に依存しないコーディングをしなければなりません。
ファイル出力時にソートして出力することは出来ますが。

1行に1つの数値という入力データを変換していくFizz BuzzはAsakusaFW向きの処理と言えます。


処理のコーディング方法

AsakusaFWは処理本体をJavaで書きますが、そのメソッドの事を演算子と呼びます。
関数型プログラミング言語によるあるStream系処理に似ており、mapやfilterに渡す関数を演算子(メソッド)として定義していくイメージです。

演算子の種類はいくつかあるので、どの演算子を選ぶかがコーディングの肝になりますが、例えば以下のようになります。

private final FizzBuzzModel result = new FizzBuzzModel();

@Convert
public FizzBuzzModel convertFizzBuzz(NumberModel in) {
    long number = in.getNumber();

    result.reset();
    result.setNumber(number);
    result.setFizzBuzzAsString(getFizzBuzz(number));
    return result;
}

実行時間

最初に書いたとおり、基本的にAsakusaFWは大量のデータを処理することを目的としているので、100件程度の入力データではあまり有り難味がありません^^;

AsakusaFWの実行基盤がM3BPならデータ量が数十~数百GB、SparkならTB級も扱えるので、Fizz Buzz換算だと10億件以上ですかねw


Asakusa Framework 1.0への妄想

2017-12-24 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2017の24日目です。

AsakusaFW 0.10.0のリリースノートの今後の予定を見ると、「将来リリース予定の Asakusa Framework バージョン 1.0 では」という言葉があります。バージョン1.0!
今まで0.nで10まで来たわけですが、そろそろ1.0になるんですね~。

というわけで、もし1.0になるなら、切りがいいので、ぜひStringOptionの中身をStringに…という事を妄想しましたw
今はStringOptionの中身はHadoopのTextクラスなので、Hadoop以外の実行基盤が主になってきた現在では、ちょっといまいちだと思うんですよね…。
データモデルのgetter/setterも、今はStringでアクセスする場合はメソッド名にAsStringが付いていますが、それを無しにする。

とはいえ、もしそうなると、今までのバージョンとは互換性が無くなってしまいますorz
ソースの後方互換性(あるバージョンで作ったソースは、後のバージョンでコンパイルできる)はAsakusaFWが守ってきた特徴のひとつですからね。これは失って欲しくないですね。

ということは、オプションで従来モードと切り替えられるようにするとか、過去バージョンからの変換ツールを用意するとか?
でもStringOptionUtilといった「Textを前提としたユーティリティークラス」もあるので、簡単には解決できそうにないですね…。


DMDL EditorX Vanillaコンパイル 0.10.0対応

2017-12-23 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2017の23日目、拙作DMDL EditorXの今年の振り返りです。

AsakusaFW 0.10.0からAsakusa Vanillaという実行基盤が使えるようになりました。
主にフローのテストで使用されるものですが、pure Javaなので、Windows上でAsakusaアプリケーションを実行してみるのにも使う事が出来ます。

DMDL EditorXではツールバーに「バッチをコンパイルするボタン」がありますので、Vanilla用コンパイル(vanillaCompileBatchapps)を追加しました。
(それにしても、いまだにDMDL EditorXの「バッチをコンパイルするアイコン」に違和感があります。コンパイルって、Eclipseではどういうアイコンを使うのが良いんでしょうねぇ?)


DMDL EditorX 文字列補完0.10.0対応

2017-12-22 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2017の22日目、拙作DMDL EditorXの今年の振り返りです。

Eclipseにはソースコードの補完機能があります。Windows版だとCtrl+Spaceで補完候補が出ます。
Eclipseプラグインでも補完機能を作る事が出来るので、DMDL EditorXでもデータモデルのプロパティー名を指定する文字列でプロパティー名を補完できるようにしています。

つまり、以下のような箇所で補完できます。

Operatorのメソッドの@Key

@Key(group = { "プロパティー名" }, order = { "プロパティー名" }) List<Model> list

Exporter

@Override
public List<String> getOrder() {
  return Arrays.asList("プロパティー名");
}

Operatorのテスト用GroupViewの作成(←New!)

OperatorTestEnvironment resource = new OperatorTestEnvironment();
GroupView<Model> view = resource.loader(Model.class, objects).group("プロパティー名").order("プロパティー名").asView();

DMDL EditorX Xtext 0.9.2対応

2017-12-21 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2017の21日目、拙作DMDL EditorXの今年の振り返りです。

DMDL EditorXはAsakusaFWのdmdlファイルの編集を補佐するツールで、Xtextというフレームワークを使って作っています。

XtextはDSL(ドメイン特化言語)のエディターを簡単に作る事が出来るフレームワークです。
DMDLの文法を定義し、dmdlファイル内のキーワードに色を付けたり補完したりソースへジャンプしたりする機能に使っています。
このため、一旦Xtextの定義が完了した後は、そこを変更することはほとんど無かったのですが、AsakusaFW 0.9.2で新文法が追加になったので、今年はそれに対するXtext定義の修正を行いました。

昨日のaoetkさんのAsakusaFWアドベントカレンダーでも紹介されている@directio.text.csv (@directio.text.tabular)ですが、これに関してescape_sequenceという属性がマップのような文法で値を設定するようになっています。これが新文法です。

他にもプロパティー参照という文法が増えていますね。

DMDLの文法が変わる事は滅多に無い為、Xtextを修正するのも久しぶりになってしまい、毎回どこを直せばいいのか忘れてしまいます^^;