GitBookを使って社内向けの文章を書く

社内向けのドキュメントを書きたいが、バイナリをGitリポジトリに突っ込んでバージョン管理したくない。 でもバージョン管理はしたいという煩悶を乗り越えるためにGitBook で書いてみました。便利。

GitBookは日本語の記事でもいくつか紹介されています。

GitBookを使うとGitBook.IOに公開しなければビルドできないと思っていたのですが、2つ目の記事にあるようにcliも提供されています。
ローカルでビルドできるのであれば公開したくない文章も書けるし、ちょっと工夫すればPDFやepubもビルドできます。便利。

検証した環境はWindows 8.1 Pro x64です。

インストール

  1. Node.jsインスコ
  2. gitbookをインスコ $ npm install -g gitbook
  3. PDFやepubをビルドしたい場合はcalibreインスコする

使ってみる

  1. 適当にディレクトリを掘る $ mkdir sample-ebook && cd sample-ebook
  2. とりあえず目次を作る $ notepad SUMMARY.md
    適当に * (Introduction)[README.md] とかで良い
  3. $ gitbook initでSUMMARY.mdに記述したディレクトリ構造が作成される
  4. $ gitbook serveした後に http://localhost:4000 にアクセスするとビルドしたドキュメントが表示される
  5. PDFやepubにビルドする場合は $ gitbook pdf$ gitbook epubでOK

これで社内リポジトリにたまっているMarkdownドキュメントも配布しやすい形式にビルドできます。やりましたね:)

AngularJSでDraggable directiveを作った

AngularJSでjQuery UI Draggableみたいなディレクティブを探していたんだけど、要件にあうものがなかったので自分で作った。

fumitoito/angular-draggable

要件としては

  • ドラッグできる
  • ドラッグ可能な軸を任意に指定できる
  • 拡大・縮小できる

という感じ。

できること

  • 要素を任意の位置にドラッグできる
  • 要素のドラッグ可能な軸を任意に指定できる(X軸もしくはY軸)
  • 要素を拡大縮小できる

インストール

bower.jsonのdependenciesに追加

"dependencies": { "angular-draggable": "git@github.com:fumitoito/angular-draggable.git" }

インスコ

$ bower install

そのうちやるかも

  • bowerのレジストリに登録
  • Droppableなディレクティブがあったほうが便利かもしれない
  • 拡大縮小は別のディレクティブに切り出すべきなのかもしれない

Issueやぷるりを貰えると喜びます。

Hadoop Conference Japan 2014にいってきた #hcj2014

Hadoop Conference Japan 2014

AMと夕方に予定があって、昼間がすぽーんと暇だったので会社を休んで行ってみた。 というか、SQLによるバッチ処理とストリーム処理があったのでこれを聞きにいった。

よかったこと

何よりもHadoop(というかストレージとか、データストア)周りがDB, Batch, Short Batch, Streamというカテゴリで綺麗に整理されていたのがすごく良かった。
カテゴリ自体というよりもその分割観点がすごく良くて以下の3つで分けているんだけど

  • Target Window
  • Total throughput
  • Query latency

ああ、なるほどなぁというか腹に落ちた感じ。Target WindowってStreamというかCEP的なことをやるまで全然意識しなかったんだけど、Target Windowを軸に分けるとDBとかBatchとの違いをすごい説明しやすいんだなということに気がついた。これはパクろう(確信)

あとはストリームの供給元はやっぱり fluentd がいいなぁっていう。自分で作っているものはWebSocketでデータを渡しているわけなんだけど、Web Serverとの結合がだるいし、ボトルネックになる場所が増えたりして正直しんどい。

Windowsなので本当はSemantic Logging Application Blockとか使うべきなのかもしれないけど、 fluentd のエコシステムは魅力的だなと思う。 C#じゃないとだるいけど

そうそう、自分はC#でCEP的なことをしているのでStreamに対するQueryもStorageに対するQueryもLinqで記述している。 あれはなかなかいいものですよ。1回書けばそれで済むしね :)

よくなかったこと

Sparkの発表をひとつも見れなかった。SQLによるバッチ処理とストリーム処理でも「SparkはShort BatchなのかStreamなのかよく知らん」みたいな話があったけど、自分も全くしらなくて。

見られればよかったなぁ。。。という感じ。

Hyper-VをVagrantで動かすメモ

Vagrantが1.5からHyper-Vをproviderとして利用できるようになりました。

ちょうどDockerに触ってみたかったり、Hyper-Vのためだけに家のPCをWindows 8.1 Proにアップグレードしたりしていたので、これ幸いと触ってみました。

Vagrantのドキュメントにも簡単に書いてありますが、自分向けの作業ログを残します。

What's todo ?

今回は

  1. Linux 14.04 LTS を使って
  2. Hyper-V向けのBoxを作成し、
  3. vagrantから利用できるようにする

ことを目的とします。

setup

1. Ubuntu ServerのページからUbuntu 14.04 LTS(Trusty)のisoをダウンロードします 2. Hyper-Vで新しい仮想マシンを作成し、ダウンロードしたUbuntu Serverをインストールします。今回は言語を日本語に設定し、インストール時にOpenSSLサーバーを追加しました 3. アップデートをします

$ apt-get update

4. rootを有効化して、パスワードをvagrantに変更

$ sudo passwd root
  vagrant

5. bashの日本語が文字化けしていたので .bashrc を編集して対応

$ vim ~/.bashrc
# 末尾に以下を追加
# case $TERM in
# linux) LANG=C ;;
# *) LANG=ja_JP.UTF-8 ;;
# esac
$ soruce ~/.bashrc

6. sudo をパスワードレスで実行可能に

$ visudo
# Defaults:vagrant !requiretty   # loginするさいにttyを不要にする
# vagrant ALL=(ALL) NOPASSWD:ALL # sudoのパスワード入力を不要にする。末尾に追加すること

7. vagrant用のSSH Keyを設定

$ mkdir .ssh
$ chmod 0700 .ssh & cd .ssh
$ curl -Lo authorized_keys https://raw.github.com/mitchellh/vagrant/master/keys/v$ agrant.pub
$ chmod 0600 authorized_keys

8. SSH接続を高速化

$ sudo vim /etc/ssh/sshd_config
# UseDNS no # 末尾に追加

9. 作成した仮想マシンをExport シャットダウン後にHyper-Vマネージャーから「エクスポート」でエクスポート
10. 仮想マシンのパッケージング

> cd path/to/exported-virtual-machine
> rmdir .\Snapshots /r/s # 作成されたディレクトリに移動して Snapshots ディレクトリを削除
> vim metadata.json
    {
      "name" : "fumitoito/trusty64jp",
      "description" : "This box contains Ubuntu 14.04 LTS 64-bit (Japanese locale)",
      "provider: "hyperv"
    }

tar でパッケージしようとするとなぜか失敗するので 7zip でパッケージした

> ls
trusty64jp.box

11. vagrantに登録してテスト起動

# 管理者権限で実行する必要があります
> vagrant box add fumitoito/trusty64jp .\trusty64jp.box
> vagrant init trusty64jp
> vagrant up --provider hyperv
> vagrant ssh # SSHで接続ができればOK!

少々手番は多いですが、そんなに詰まることなくVagrantHyper-Vにデプロイすることができました。 素敵ですね:)

StreamInsightでクエリテンプレートを使ってデータを出力する

注意

この記事は諸般の理由から、悲しい結論になります。「StreamInsightのデータ入出力で複雑な前処理を扱いたい」という方以外は次にアップする記事を参照してください。

クエリテンプレートって何?

StreamInsightでは入力データをOutputAdapterに渡す際にLINQで記述したクエリロジックによるフィルターをかませることができます。この際のクエリロジックのことを「クエリテンプレート」と呼んでいます。

クエリテンプレート登録の流れ

大まかな流れは以下のようになります。

InputAdpterのオブジェクトを生成 -> LINQでフィルター -> OutputAdapterにバインド

1. InputAdapterのオブジェクトを生成

AdapterFactoryDataType は適切に定義してあるとします。
FactoryとConfigを特定のメソッドに渡すことで、InputAdapterのオブジェクト(実際にはCepStreamオブジェクト)を生成することができます。

var inputStream = CepStream<SampleDataType>("streamName",
                                            typeof(SampleAdapterFactory),
                                            new SampleAdapterConfig { hoge = "fuga" },
                                            EventShape.Point);

最後の引数で渡している EventShape.Point はAdapterのイベントタイプと合わせておく必要があります。

2. LINQでフィルター

ここは普通にLINQを記述すればおkです。実際にどのような記述が可能なのかについては こちらのページ を参照してください。

var filteredStream = from s in inputStream
                     where s.name = "ito"
                     select s;

ここでは「名前が "ito" の人のみを抽出する」フィルターを記述しています。

3. OutputAdapterにバインド

filteredStreamをOutputAdapterにバインドすればクエリテンプレートの登録は完了です。

var query = filteredStream.toQuery(app, "queryName", "queryDescription",
                                   typeof(SampleOutputAdapterFactory),
                                   new SampleOutputAdapterConfig { foo = "bar" },
                                   EventShape.Point,
                                   StreamEventOrder.FullyOrdered);

StreamEventOrderにはFullyOrdered(期間イベントの開始時間順に出力)とChainOrdered(期間イベントの終了時間順に出力)がありますが、PointEventを扱っている場合はあまり問題になりません。

で、最後に

Queryを開始することで各Adapterからの入出力が開始されます。

query.Start();

ちなみに

これまで何回かに分けてブログを書いてきたInput/OutputAdapterによるデータフローの制御ですが、 StreamInsight 2.1 では「レガシーモデル」として扱われています。 なんということでしょう…。

これまでは気がつかずにStreamInsight 2.0のドキュメントを見ていたわけです。(白目)

もちろんInput/OutputAdapterを使った方法も複雑な前処理・後処理が必要な場合は有効ですが、次回からはより新しい IEnumerable/IObservableクラスを用いたStreamInsightのストリーム処理を見ていきます。

StreamInsightでデバッグする

StreamInsightのEvent Flow Debuggerをつかう

こちらの記事を参考にEvent Flow Debuggerを使ったStreamInsightのデバッグについて書きました。

イベントストリームをデバッグするには?

StreamInsightではイベントストリームを扱っています。当然、アプリケーションを作成する上ではコードの挙動を確認したり、イベントが意図通りに流れているかデバッグをする必要があります。

しかし、イベントストリームは非同期に流れてきますので、コードにブレークポイントを貼っても全体の流れがよくわかりません。また、デバッグのためにログをコンソールに出したりファイルに吐いたりしたものを毎回確認するのもなかなか面倒です。

StreamInsightには標準でEvent Flow Debuggerというデバッガーが付属しており、これを使うことでストリームを保存して再生したり、ストリームを途中で止めて挙動を確認したりすることができます。

StreamInsightでのデバッグの流れ

StreamInsightでイベントストリームをデバッグするための流れは、だいたい以下の様な感じです。

  1. (初回のみ) 既存のコードにStreamInsightのサーバーエンドポイントを実装する処理を追加します
  2. Event Flow Debuggerでサービスマネジメントホストに接続し、StreamInsightアプリケーションで動作しているクエリを保存します
  3. Event Flow Debuggerで保存したクエリを読み込み、ステップ実行したりブレークポイントを設置したりしながらデバッグを行います

1. StreamInsightのサーバーエンドポイントを追加する

Event Flow DebuggerからStreamInsightアプリケーションに接続するためには、StreamInsightアプリケーションが紐づくサーバーエンドポイントに接続する必要があります。通常のサンプルプロジェクトではサーバーエンドポイントを立ち上げる処理は記述されていませんので、自前で作成しましょう。

おおまかな実装は以下のようになります。

using (cepServer = Server.create(instanceName)) {
    // create management host service
    ServiceHost host = new ServiceHost(cepServer.createManagementHost());

    // add endpoint to access
    host.AddServiceEndpoint(typeof(IManagementService), new WSHttpBinding(SecurityMode.Message), "http://localhost/StreamInsight/{Service Name}");

    host.Open();

    // and other functions...
}

参照設定で System.ServiceModel, Microsoft.ComplexEventProcessing.ManagementService を読み込む必要があります。エンドポイントを公開するURLはとくに決まりがあるわけではありませんが、Event Flow Debugger起動時のデフォルトURLが http://localhost/StreamInsight/{Service Name} になっていますのでそちらを利用しました。

2. Event Flow Debuggerで動作しているクエリを保存する

StreamInsightのクエリが実行されている状態でEvent Flow Debuggerを立ち上げて先ほど指定したURLに接続します。正常に接続ができている場合は左ペインの「Applications」フォルダの下に、起動中のStreamInsightアプリケーションの一覧が表示されているはずです。

[Applilcations] -> [Application Name] -> [Queries] を選択していくと、アプリケーション上で定義されているクエリの一覧が表示されていると思います。適当なクエリをダブルクリックすると以下の様なクエリグラフが表示されます。

Query Graph

このようにクエリを選択した状態で左上の時計ボタンを押すとストリームの記録が開始されます。適当にストリームを流してから記録を停止すると、記録した内容をETF(Event Trace File)形式のファイルとして保存することができます。保存ダイアログが出ない場合は左上の[File]メニューから保存してください。

ETFはいろいろと使いようがあるみたいですが、今回はひとまず普通にデバッガーで読み込む方法を試します。

3. Event Flow Debuggerで保存したクエリのデバッグを行う

では、先ほど保存したETFを読み込んでデバッグを行いましょう。左上の[File]メニューからETFファイルを開くことができます。ファイルを開くと以下の様にクエリグラフが表示されます。

Event Flow Debugger

タブの上部に表示された矢印をクリックすることで、どのデータがどのフローをどの順番で流れていったのか確認することができます。

Debugging Image

CTIイベントやInsertイベントで挿入されたデータの詳細も同時に見ることができます。

まとめ

Event Flow Debuggerを利用することでStreamInsightで処理するイベントストリームの保存、デバッグを容易に行うことができます。また、特定のクエリのフローにデータが流れてきた原因分析など、より高度なデバッグも用意されているようです。素敵ですね :)

今回はデバッガーに寄り道しましたが、次回はLINQによるクエリテンプレートを見ていきます。

データサイエンティスト養成読本 [ビッグデータ時代のビジネスを支えるデータ分析力が身につく! ] (Software Design plus)

データサイエンティスト養成読本 [ビッグデータ時代のビジネスを支えるデータ分析力が身につく! ] (Software Design plus)

StreamInsightでOutputAdapterを作ってみる

さて、前回の記事ではStreamInsightの入力アダプター(InputAdapter)を実装することでアダプターの構成や開発の流れを確認しました。

今回は出力アダプター(OutputAdapter)を見ていきます。

OutputAdapterの構成

  • OutputAdapter Class
  • OutputAdapterFactory Class
  • OutputAdapterConfig Class

基本的にInputAdapterの構成と同じです。OutputAdapter, OutputAdapterFactoryは型の有り/無し、回復性サポートの有る/無し、イベントの種類に応じて適切な基本クラスを継承して作成することになります。

OutputAdapterFactoryクラス

以下の様な命名規約にしたがって定義されている基本クラスを継承します。

I[回復性サポート有り/無し][型指定の有り/無し]OutputAdapterFactory

例えば回復性サポートありの型指定有りなOutputAdapterFactoryを作成する場合は、以下のようになります。

public class SampleOutputAdapterFactory : IHighWarterMarkTypedOutputAdapterFactory<SampleOutputAdapterConfig> {}

OutputAdapterFactoryはInputAdapterFactoryと同じように Create, Dispose メソッドを実装する必要があります。 Create メソッドではイベントの種類に応じて適切なOutputAdapterを生成し、 Dispose メソッドでは生成したAdapterの停止処理を行います。

OutputAdapterクラス

以下の様な命名規約にしたがって定義されている基本クラスを継承します。

[型指定の有り/無し][イベントの種類]Adapter

例えば型指定有りのエッジイベントを扱うOutputAdapterを作成する場合は、以下のようになります。

public class SampleOutputAdapter<T> : TypedEdgeOutputAdapter<T> {}

Start, Resume, Disposeなどのメソッドを実装することでアダプターが開始した時、再開するとき、アダプターを削除するときの処理などを定義することができます。 StartResume メソッドの中では Dequeue メソッドを呼び出すことで、InputAdapterによってEnqueueされたPayloadを取り出すことができます。

[Enqueue|Dequeue]OperationResult

そうそう、この前までわかっていなかったのですが、Adapterクラスの Queue, Dequeue はそれぞれ EnqueueOperationResult, DequeueOperationResultオブジェクトを返します。

これらはEnqueue, Dequeueの結果を表しているわけですが、DequeueではAdapterが Suspended, Stoppingの場合に DequeueOperationResult.Empty を返しますので、この値をチェックすることで不要になったAdapterを停止したり、後処理的を実行したりすることができるようです。なにげに便利ですね。

アダプターの状態管理についてはおいおい勉強していくこととして、次回はInputAdapterから入力されたストリームをOutputAdapterに渡すための、LINQによるクエリテンプレートを見ていきます。

そういえば

「作ってみる」と言いながらOutputAdapterを一行も作っていませんでした。自分でデバッグするときは出力が簡単にわかるといいので、Sampleに含まれているConsolePointOutputクラスを流用しています。

実はStreamInsightにはストリームを記録・再生したり、ブレークポイントを設置してデバッグできるようなツールが付属しているようなので、そちらも今後試していきます。