最近はもっぱらMarkdownを書くようになり、Bloggerがどんどん使いづらくなってきたのではてなブログに引っ越した。
http://ohbarye.hatenablog.jp/
下記リンク先が大変参考になり、10分ほどで作業を終えることができた。
http://nekonkeo.hatenablog.com/entry/2014/09/23/165817
2015年4月15日水曜日
2015年3月13日金曜日
グラフDB(Neo4j)を試してみる (2)BluePrintsで読み書き
BluePrints
各グラフDBに対するインタフェース、APIを提供するソフトウェア。複数のグラフDBに対応している。
ライブラリ追加
blueprints-core と好きなGraphDB用のライブラリを追加する。今回はNeo4jを選んだので blueprints-neo4j-graph を追加。
手元でちょうどPlay Framework触ってたのでビルドツールはSBT。
libraryDependencies ++= Seq( "com.tinkerpop.blueprints" % "blueprints-core" % "2.6.0", "com.tinkerpop.blueprints" % "blueprints-neo4j-graph" % "2.6.0" )
DB初期化〜読み書き
DBの初期化からデータの追加、検索を行うとこんな感じになる。package app; import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.Graph; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.impls.neo4j.Neo4jGraph; public class GraphDB { public static void main(String[] args) { /** * init * 使用するグラフDB用のディレクトリを指定する。 * このタイミングでロックファイルを作成し、排他制御をかける。 * ディレクトリが存在しない場合は初期化してくれる。 */ Graph g = new Neo4jGraph("data/graphdb"); addData(g); showData(g); /** * close * プログラムを終了する時は必ずshutdown。 * ロックの解放とか諸々やってるっぽい。 */ g.shutdown(); } /** * Add Node and Edge * @param g */ public static void addData(Graph g) { /** * insert * Vertex(頂点、Node)の追加+属性の追加。 */ Vertex v1 = g.addVertex(1); v1.setProperty("name", "Apache"); Vertex v2 = g.addVertex(2); v2.setProperty("name", "Nginx"); /** * insert * Edge(辺、Link)の追加+属性の追加。 */ Edge e1 = g.addEdge(1, v1, v2, "similar"); e1.setProperty("since", 2006); } /** * show graph data * @param g */ public static void showData(Graph g) { /** * select * とりあえず全部取得して表示。 */ for (Vertex v : g.getVertices()) { System.out.println("Vertex id = " + v.getId().toString() + " property 'name' = " + v.getProperty("name")); } for (Edge e : g.getEdges()) { System.out.println("Edge id = " + e.getId().toString() + " property 'since' = " + e.getProperty("since")); } } }Vertex id = 1 property 'name' = Apache Vertex id = 2 property 'name' = Nginx Edge id = 0 property 'since' = 2006
初見の印象
とりあえず触ってみたところ、特に良いなと思ったのが下記。- サーバ構築不要
- 移植性が高い
もちろん、サーバとして起動して外部からのアクセスを待ち受けたりもできるとのこと。
また、移植性も高い。
new Neo4jGraph(“data/graphdb”) で指定したディレクトリの移動だけで移植が完了する模様。
グラフDBにはスケールしづらいという弱点があるらしいが、その分これだけ軽量になっているのは魅力的。
2015年3月12日木曜日
グラフDB(Neo4j)を試してみる (1)グラフDBとは
会社の勉強会でグラフDBが紹介されて興味を持ったので実践してみた。
全然知らない領域だったのでいろいろ整理したい。
グラフ理論をベースとし、ノード(頂点)とエッジ(関係)を構成要素とするNoSQLデータベースの一つ。関係性を表現が目的のため、その探索が用意。また、ノード・エッジはプロパティ(属性)を持つことができる。
とりあえずこんな理解。
一般的な「グラフ」とは意味合いが違うけれども、計算機科学や数学では「グラフ」といえばこちらを指すことが多いのだろうか。ちなみにWikipediaのグラフ理論がだいぶ参考になった。
グラフデータベース、NOSQL、Neo4jを見ると非OSSが多い印象。
ややキモいキャラクターが各プロダクトのトレードマークっぽい。
TinkerPop - http://goo.gl/zpCCC
今回はこのうちBluePrintsとGremlinを使ってグラフDBへアクセス、読み書きを行ってみた。
長くなりそうなのでコードは次の記事で書く。
全然知らない領域だったのでいろいろ整理したい。
グラフDBとは
まずグラフDBとは何か。グラフ理論をベースとし、ノード(頂点)とエッジ(関係)を構成要素とするNoSQLデータベースの一つ。関係性を表現が目的のため、その探索が用意。また、ノード・エッジはプロパティ(属性)を持つことができる。
とりあえずこんな理解。
一般的な「グラフ」とは意味合いが違うけれども、計算機科学や数学では「グラフ」といえばこちらを指すことが多いのだろうか。ちなみにWikipediaのグラフ理論がだいぶ参考になった。
グラフ理論(グラフりろん、英: graph theory)は、数学の一分野。ノード(節点・頂点[1])の集合とエッジ(枝・辺[2])の集合で構成されるグラフの性質について研究する学問である。なお「エッジ」をリンク[3]という場合もある。コンピュータのデータ構造、アルゴリズムなどに広く応用されている。
Wikipedia グラフ理論このグラフ構造はRDBでも実現できるが、リレーションを辿る=結合の繰り返しになるのでクエリが複雑になったりパフォーマンスがひどいものになったりする。FacebookやTwitterに代表されるようなリレーションをコアとするアプリケーションでのデータ管理や表現への注目の高まり、
Neo4j
試してみたグラフDBはNeo4j。この他にもいろいろあるらしいけど未知。グラフデータベース、NOSQL、Neo4jを見ると非OSSが多い印象。
TinkerPop
グラフDBを利用する為のフレームワーク、製品群。ややキモいキャラクターが各プロダクトのトレードマークっぽい。
TinkerPop - http://goo.gl/zpCCC
今回はこのうちBluePrintsとGremlinを使ってグラフDBへアクセス、読み書きを行ってみた。
長くなりそうなのでコードは次の記事で書く。
2015年3月4日水曜日
[play framework] 間違って controllers 内のクラスを削除したらコンパイルエラー
下記コマンドでリビルドしたら解消した。
$ play clean compile stage
2015年3月1日日曜日
[Play Framework] 多対多で自己再帰の関連を持つテーブルのEntity
多対多(Many To Many)で自己再帰的(self recursive)な関係をEbean の Model で表現するのに苦戦した。
あまり良い例ではないけど、
person には似てる人(similarPerson)が複数いる、という設定で書いてみた。
person と person の多対多を解消する中間テーブルは similar_person として定義してみる。
最初これらを書かずにいたら、similar_person テーブルで列名 person_id が重複しています と怒られた。
考えてみたらどちらも外部参照先 (person.id) は同じなんだから、列名指定せずに自動生成したらそうなるよな…。
上記のクラスを定義した上で Evolution を実行すると、下記SQL が自動生成される。
JPA をちゃんと理解してなかったのでけっこうハマった。
あまり良い例ではないけど、
person には似てる人(similarPerson)が複数いる、という設定で書いてみた。
person と person の多対多を解消する中間テーブルは similar_person として定義してみる。
@Entity public class Person { @Id public Long id; @ManyToMany @JoinTable(name = "similar_person", joinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "similar_person_id", referencedColumnName = "id")) public Listポイントは @JoinTable の引数の joinColumns と inverseJoinColumns 。similarPersons; }
最初これらを書かずにいたら、similar_person テーブルで列名 person_id が重複しています と怒られた。
考えてみたらどちらも外部参照先 (person.id) は同じなんだから、列名指定せずに自動生成したらそうなるよな…。
上記のクラスを定義した上で Evolution を実行すると、下記SQL が自動生成される。
# --- Created by Ebean DDL # To stop Ebean DDL generation, remove this comment and start using Evolutions # --- !Ups create table similar_person ( person_id bigint not null, similar_person_id bigint not null, constraint pk_similar_person primary key (person_id, similar_person_id)) ; alter table similar_person add constraint fk_similar_person_person_01 foreign key (person_id) references person (id) on delete restrict on update restrict; alter table similar_person add constraint fk_similar_person_person_02 foreign key (similar_person_id) references person (id) on delete restrict on update restrict; # --- !Downs SET REFERENTIAL_INTEGRITY FALSE; drop table if exists similar_person;
JPA をちゃんと理解してなかったのでけっこうハマった。
【参考】
JPA – Recursive ManyToMany-Relationship | stuetzpunkt -[Play Framework] Play2.2.x で Java8 の記法で書いたらコンパイルエラーになった
Play2.2.x で play new したプロジェクトを素のまま使っていて Java8 の記法で書いたらコンパイルエラーになった。
2.2系は Java8 対応してないとのこと。
SBT のバージョン上げたら動くようにはなったけど、問題がありそうなので正式対応した 2.3系を使おう。
2.2系は Java8 対応してないとのこと。
SBT のバージョン上げたら動くようにはなったけど、問題がありそうなので正式対応した 2.3系を使おう。
【参考】
[play-framework] Error Unknown constant: 18 - Grokbase -2015年2月4日水曜日
[Java][Excel][JETT] Excel帳票出力にJETTを試してみる
シフト表作成アプリ作る中で、Excel帳票を出力したくなったので軽くライブラリについて調べて見る。
Fisshplate …テンプレートを使ってみて、やっぱりコレぐらいサクサク書けない と困ると実感した。ただ、今回出力したい xlsx 形式に対応していない(対応予定なし?)のでスルー。
どのライブラリも POI ベースでそれをラップするのが基本ぽいのに、もしかして皆 POI で頑張ってるのか…??
そんな中 Excel方眼紙を支える技術 - 新・たけぞう瀕死の日記 がかなり参考になった。
本家サイトの jXLS との比較:JETT - Comparison to jXLS
とりあえずテンプレートファイルへの出力を試す。
1.テンプレートファイルを用意する。
2.出力コードを書く。
余分なコードが多いが、テンプレートへの出力処理は ExcelTransformer#transform で JavaBeans を渡すだけでOKなのでかなり簡潔。
テンプレートファイルに記述する構文もシンプルで良い。
個人的に、forEach タグを利用する時にデータの無い行や列にタグを書かなくて良いのは嬉しい。
(今回は play なので build.sbt で管理)
調べる前に、以前に使ったことあるやつ
POI …以前に実務で帳票ガリガリ書いてたけど、かなりプリミティブで結構辛かった。なので生で使うのは本当に必要な時だけにしたい。Fisshplate …テンプレートを使ってみて、やっぱりコレぐらいサクサク書けない と困ると実感した。ただ、今回出力したい xlsx 形式に対応していない(対応予定なし?)のでスルー。
Java × Excel だと POI の話題ばかり
Java8 / play framework でやっており、とりあえず最近だとどんなライブラリがあるのかと思い調べてみると、POI の話題ばかり。どのライブラリも POI ベースでそれをラップするのが基本ぽいのに、もしかして皆 POI で頑張ってるのか…??
そんな中 Excel方眼紙を支える技術 - 新・たけぞう瀕死の日記 がかなり参考になった。
JETT を試して見る
なんとなく先端ぽく、↓の比較も面白かったので今回は帳票出力用ライブラリ JETT を試してみることにした。本家サイトの jXLS との比較:JETT - Comparison to jXLS
とりあえずテンプレートファイルへの出力を試す。
1.テンプレートファイルを用意する。
2.出力コードを書く。
public static File makeShift() { System.out.println(System.getProperty("user.dir")); List<employee> employees = Lists.newArrayList(); Map<string object=""> beans = Maps.newHashMap(); Employee emp = new Employee(); emp.name = "Butcher"; emp.skillLevel = "High"; employees.add(emp); beans.put("employees", employees); String inPath = "resources/shift_template.xlsx"; String outPath = "resources/shift.xlsx"; try (FileOutputStream fileOut = new FileOutputStream(outPath); InputStream fileIn = new BufferedInputStream(new FileInputStream(inPath))) { ExcelTransformer transformer = new ExcelTransformer(); Workbook workbook = transformer.transform(fileIn, beans); workbook.write(fileOut); fileOut.close(); } catch (IOException e) { System.err.println("IOException reading " + inPath + ": " + e.getMessage()); } catch (InvalidFormatException e) { System.err.println("InvalidFormatException reading " + inPath + ": " + e.getMessage()); } return new File(outPath); }
余分なコードが多いが、テンプレートへの出力処理は ExcelTransformer#transform で JavaBeans を渡すだけでOKなのでかなり簡潔。
テンプレートファイルに記述する構文もシンプルで良い。
個人的に、forEach タグを利用する時にデータの無い行や列にタグを書かなくて良いのは嬉しい。
番外
その他、調べて評判良かったのが ExCella だったけど、Maven repository に登録されておらずライブラリ管理を考えるのが面倒になってスルーした。(今回は play なので build.sbt で管理)
2015年1月5日月曜日
[Heroku][Play Framework] New Relic APMを使って、一定時間アクセスが無くても Dyno をスリープさせないようにする
先日公開した Haiku Matcher で使っている Heroku の Dyno(プロセス) は一定時間(1時間?)アクセスが無いとスリープしてしまう。(IDLE状態になってしまう)
New Relic APM を使って叩き起こし続けることにした。
知っておきたい!Herokuを使う上では当たり前?の16の常識 | mah365 -
確かに、暫く放置した後のアクセスにはレスポンスが急激に遅くなっていた。
また、Heroku の Personal Apps ページで対象のアプリケーションの六角形アイコンを見てみると、六角形の中に"zzz" が表示されていた。
Dynoとは
2.は実行用の環境を用意するのが面倒なので今回はパス。
今回は無料プランがあり、Addon ということで簡単に導入できそうな3.を採用。
検索するといろんな言語での導入方法が出てくるが、今回は Java, かつ Play Framework を利用していたので下記を参考に実践した。
adding new relic addon to heroku play framework 2.2.1 java app - Stack Overflow -
Amit Sharma 氏の answered Jan 28 '14 at 6:07 の投稿通りに実行した結果、1時間後でもスリープしていないことが確認できた。
上記内容で導入できたと思っていたら、できていなかった。
New Relic のページ見たらアプリケーション情報が表示されず、newrelic agent がそもそも起動してなかったと判明した…。
Java - Play2.2をherokuで動かした時にはまったポイント - Qiita - を参考にやり直したらうまくいったので、方法をきちんとまとめておく。
1) 決済情報を登録する。Heroku ダッシュボードから [Manage Account] → [Billing] で登録しておく。完了していればスキップする。登録していないと 2) で下記エラーが出る。
2) アドオンを入れる。
3) 依存ライブラリを追加する。build.sbt に下記を追記する。
※最初にてきとうに 3.1.0 を選んだらエラー出て、Java8に対応してなかった。今回はJava8を使っているので、対応しているバージョンを選択した。
4) New Relic 関連のファイルを配置する。
ファイル群は New Relic の管理ページ → Application タブのページから取得できるはず。(自分のアプリが正常に連携されてからそのページが開けなくなった…)
・newrelic.yml のみルートディレクトリに配置する。
・それ以外(jarなど)は lib/ に配置する。
5) Procfile にVM引数を追加する。
6) ここまでの変更をコミット、Heroku へデプロイする。
7) New Relic の Monitoring 対象に自分のサイトを加える。
New Relic の管理ページ → Applications タブ → [自分のアプリ名] → Availability Monitoring → URL Monitor に自分のサイトのURLを入力する。
(参考)1DynoなHerokuをNew Relicでアイドルを回避 - PILOG -
完
(参考)Heroku Scheduler
・Play Framework 2.2.6
New Relic APM を使って叩き起こし続けることにした。
Heroku のスリープについて
会社の元同期に「Dyno寝てるっぽいよ」と教えてもらって、「あ、眠るんだ…」と知りました。知っておきたい!Herokuを使う上では当たり前?の16の常識 | mah365 -
また、Heroku の Personal Apps ページで対象のアプリケーションの六角形アイコンを見てみると、六角形の中に"zzz" が表示されていた。
Dynoとは
Dynoはアプリケーションサーバの1プロセスで、アプリケーションサーバThin(http://code.macournoyer.com/thin/)をベースにしているもののようです。Dynoは追加購入すれば、ユーザは柔軟に増やすことができ、2秒で起動するとのことです。スリープさせないためには。
フレクトのクラウドBlog: Herokuについて調べたことのまとめ -
- Dyno を増設する
- シェルなどで定期的に ping 打つ
- Heroku Addon の New Relic APM を使う
2.は実行用の環境を用意するのが面倒なので今回はパス。
今回は無料プランがあり、Addon ということで簡単に導入できそうな3.を採用。
New Relic APM の導入
上記内容で導入できたと思っていたら、できていなかった。
New Relic のページ見たらアプリケーション情報が表示されず、newrelic agent がそもそも起動してなかったと判明した…。
Java - Play2.2をherokuで動かした時にはまったポイント - Qiita - を参考にやり直したらうまくいったので、方法をきちんとまとめておく。
1) 決済情報を登録する。Heroku ダッシュボードから [Manage Account] → [Billing] で登録しておく。完了していればスキップする。登録していないと 2) で下記エラーが出る。
Adding newrelic:stark on your-app-name... failed ! Please verify your account to install this add-on plan (please enter a credit card) ! For more information, see https://devcenter.heroku.com/categories/billing
2) アドオンを入れる。
$ heroku addons:add newrelic:stark
3) 依存ライブラリを追加する。build.sbt に下記を追記する。
"com.newrelic.agent.java" % "newrelic-agent" % "3.12.1"※newrelic-api は不要だった。
※最初にてきとうに 3.1.0 を選んだらエラー出て、Java8に対応してなかった。今回はJava8を使っているので、対応しているバージョンを選択した。
4) New Relic 関連のファイルを配置する。
ファイル群は New Relic の管理ページ → Application タブのページから取得できるはず。(自分のアプリが正常に連携されてからそのページが開けなくなった…)
・newrelic.yml のみルートディレクトリに配置する。
・それ以外(jarなど)は lib/ に配置する。
5) Procfile にVM引数を追加する。
-J-javaagent:lib/newrelic.jar※Play2.2から JAVA_OPTS に設定してもダメとのこと。
6) ここまでの変更をコミット、Heroku へデプロイする。
$ git add . $ git commit -m "optional message" $ git push heroku master数分後、New Relic の管理ページ →アプリケーションタブのページに自分のアプリ名が表示される。
7) New Relic の Monitoring 対象に自分のサイトを加える。
New Relic の管理ページ → Applications タブ → [自分のアプリ名] → Availability Monitoring → URL Monitor に自分のサイトのURLを入力する。
(参考)1DynoなHerokuをNew Relicでアイドルを回避 - PILOG -
完
感想
簡単だと思ったら色々とハマった。Heroku Scheduler の方が簡単だったかも。(参考)Heroku Scheduler
【環境 】
・Java8・Play Framework 2.2.6
登録:
投稿 (Atom)