Hudsonで「java.io.IOException: Cannot run program "mvn"」

タイトルのエラーがでたら、
/etc/profileに以下の設定をすれば直るよ。

export JAVA_HOME=/usr/local/java
export MAVEN_HOME=/usr/local/maven

export PATH=${JAVA_HOME}/bin:${MAVEN_HOME}/bin:${PATH}


まあ、確実にもっといい方法ありそうだけど、
とりあえずできたからいいや。


しかし、Hudsonの管理画面でJAVA_HOMEとMAVEN_HOMEを
設定する場所あるけど、なぜそれを設定しても直らなかったんだろう。


なんか知らんけど、すげーはまった。。

RubyからHiveサーバ経由でHiveを使う

HiveサーバはThriftでできてるんで当然Rubyからも使えます。
が、ひどくはまったんでメモしときます。


環境は、CentOS 5.5です。


Thriftのインストール
id:brfrn169:20101010:1286699822


Hiveサーバの立ち上げ方など
id:brfrn169:20100312:1270530644

クライアントコードの生成

まず、http://archive.cloudera.com/cdh/3/ からソースを落としてきます。


落としてきたら、IDLからクライアントコードを生成します。

tar xvzf hive-0.5.0+20.tar.gz 
thrift -gen rb hive-0.5.0+20/src/service/include/thrift/fb303/if/fb303.thrift
thrift -gen rb hive-0.5.0+20/src/ql/if/queryplan.thrift
thrift -gen rb -I hive-0.5.0+20/src/service/include hive-0.5.0+20/src/ql/if/queryplan.thrift
thrift -gen rb -I hive-0.5.0+20/src/ -I hive-0.5.0+20/src/service/include hive-0.5.0+20/src/service/if/hive_service.thrift


一応、落としてきたソースの中にクライアントコードはありますが、
うまく動かなかったので生成しなおしてます。


gen_rb/にコードが吐かれます。

動作テスト

以下のように使えます。

$: << 'gen-rb'

require 'thrift_hive'

transport = Thrift::BufferedTransport.new(Thrift::Socket.new("localhost", 10000))
protocol = Thrift::BinaryProtocol.new(transport)
client = ThriftHive::Client.new(protocol)

transport.open()

client.execute("CREATE TABLE test (a STRING, b STRING, c STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\\t' STORED AS TEXTFILE")
client.execute("LOAD DATA INPATH 'data' OVERWRITE INTO TABLE test")

client.execute("SELECT * FROM test")
client.fetchAll.each do |row|
  p row
end

client.execute("SELECT count(1) FROM test")
p client.fetchOne

transport.close()

Thriftのインストール

だいぶ今更ですが、はまったのでメモしときます。
環境は、CentOS 5.5 です。

ダウンロード

下記URLからダウンロードします。
http://incubator.apache.org/thrift/download/

現在の最新版は、0.5.0です。

インストール

まず、依存ライブラリをインストール

sudo yum install automake libtool flex bison pkgconfig gcc-c++ boost-devel libevent-devel zlib-devel python-devel ruby-devel


Thrift本体をインストール

tar xvzf thrift-0.5.0.tar.gz
cd thrift-0.5.0
./configure --prefix=/usr
make
sudo make install


ここで、make中に以下のようなphp系のエラーがでました。

/home/brfrn169/thrift-0.5.0/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp: In function ‘void createObject(char*, zval*, int, zval*, zval*)’:
/home/brfrn169/thrift-0.5.0/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp:390: error: ‘zend_std_get_constructor’ was not declared in this scope


どうやら、php5.2系じゃないとエラーになるようです。
http://www.mail-archive.com/thrift-user@incubator.apache.org/msg01111.html


以下のサイトを参考にしてphp5.2系を入れたらエラーがでなくなりました。
http://kfactory.net/?p=833

Error Recovery for block null bad datanode[0] nodes == null

hadoopをインストールしたあとに、
ファイルをputしようとすると下記のようなエラーがでる。

Error Recovery for block null bad datanode[0] nodes == null


http://your_host:50070/dfshealth.jsp にアクセスすると直る。。

オブジェクト指向設計の原則 - パッケージ設計の原則

少し勉強したんで、メモ。

たぶん、今後更新していきます。


まず、パッケージとは、機能のグループ単位、サブシステムのこと。
Javaだと、パッケージの概念はあるけど、もっと広い意味でJarもパッケージに含まれる。

パッケージ内部の凝集度に関する原則

再利用・リリース等価の原則(REP:Reuse-Release Equivalency Principle)


再利用の単位とリリースの単位は等価になる。
パッケージに含まれるクラスは、すべてが再利用されるか、すべてが再利用できないかのどちらかにすべきだ。


リリースの単位はパッケージ毎に行う。
再利用できるパッケージは別に切り出しといて、再利用できないパッケージでそれを使うイメージ。

全再利用の原則(CRP:Common Reuse Principle)


パッケージに含まれるクラスは、すべて一緒に再利用される。
つまり、パッケージに含まれるいずれかのクラスを再利用するということは、その他のクラスのすべてを再利用するすることを意味する。


同じパッケージに含めるクラスは、一緒に使われる傾向にある。
逆に言えば、互いに強い関連性を持たないクラスを同じパッケージにまとめるべきではない。

閉鎖性共通の原則(CCP:Common Closure Principle)


パッケージに含まれるクラスは、みな同じ種類の変更に対して閉じているべきである。
パッケージに影響する変更はパッケージ内のすべてのクラスに影響を及ぼすが、他のパッケージには影響しない。


単一責任の原則のパッケージ版。パッケージの変更理由は一つであるべきだ。

パッケージ同士の結合度に関する原則

非循環依存関係の原則(ADP:Acyclic Dependencies Principle)


パッケージ依存グラフに循環を持ち込んではならない。


パッケージ間はインターフェースのみに依存すべきである。

安定依存の原則(SDP:Stable Dependencies Principle)


安定する方向に依存せよ。


安定度の高い(変更しにくい)パッケージに依存するべき。
当然、不安定なパッケージに依存するとそのパッケージに変更があったときに
影響を受けてしまう。

安定度・抽象度等価の原則(SAP:Stable Absstractions Principle)


パッケージの抽象度と安定度は同程度でなければならない。


安定度の高い(変更しにくい、依存されている)パッケージは抽象度が高くなければならない。
不安定な(変更することを意識して作られた、依存ばかりしている)パッケージは具体的でなければならない。

まとめ

あまり、クラス設計の原則と変わらない印象。
クラスは全く他のクラスに依存しないのは不可能なので、
パッケージ単位で扱う(リリース、再利用)必要がある。
その中で、いかに、オープン・クローズド(拡張に対して開いていて、
修正に対して閉じている)にするかが大切ということだろう。



アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技

アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技

オブジェクト指向設計の原則 - クラス設計の原則

少し勉強したんで、メモ。

たぶん、今後更新していきます。

単一責任の原則(SRP:the Single Responsibility Principle)


クラスを変更する理由は1つ以上存在してはならない。


クラスが持つ責任は1つってこと。
まあ、当たり前のことだけど、難しいよね。


Proxyパターン, Facadeパターン, Iteratorパターンをつかうと、
うまく責任を分割できる。

オープン・クローズドの原則(OCP:the Open-Closed Principle)


ソフトウェアの構成要素は、拡張に対して開いていて、修正に対して閉じていなければならない。


開いているとは、モジュールの振る舞いを拡張できるっていうことで、
閉じているとは、モジュールの振る舞いを変更しても、
そのモジュールを利用しているソースを変更する必要もないし、
バイナリも再コンパイルする必要ないってこと。


StrategyパターンやTemplate Methodパターンを使うといい。

リスコフの置換原則(LSP:the Liskov Substitution Principle)


派生型はその基本型と置換可能でなければならない。


派生クラスが基本クラスとして使われるときに、常に正常に動作することを保証しなければならない。
つまり、プログラマが派生クラスを意識して実装しなくてはならない状況はダメ。


注意したいところは、派生クラスのみが投げる例外とか、
派生クラスにおいて退化している機能。
Javaなんかだと派生クラスでUnsupportedOperationExceptionを投げるメソッドがあるけどLSP違反だね。

依存関係逆転の原則(DIP:the Dependency Inversion Principle)


上位のモジュールは下位のモジュールに依存してはならない。どちらのモジュールも「抽象」に依存すべきである。
「抽象」は実装の詳細に依存してはならない。実装の詳細が「抽象」に依存すべきである。


クラス同士の関係は、一旦、抽象クラスかインターフェースを噛ませろってこと。
DIみたいな。
でも、バランス考えないと、インターフェースだらけのソースコードになって読みづらいよね。

インターフェイス分離の原則(ISP:the Interface Segregation Principle)


クライアントに、クライアントが利用しないメソッドへの依存を強制してはならない。


要は、太った(多機能な)インターフェースは変更があったときに、
その機能をつかってないクライアントにまで変更を強いてしまうことがある。
クライアントに応じて、インターフェースをきちんと分解しましょう。

まとめ

それぞれの原則が互い関連している感じ。
結局一番大切なのは、オープン・クローズドの原則だね。



アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技

アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技

HadoopでGanglia

Hadoop0.20で、Ganglia3.1以降を使うには、
org.apache.hadoop.metrics.ganglia.GangliaContextではなくて、
org.apache.hadoop.metrics.ganglia.GangliaContext31を使う。


hadoop-metrics.properties

dfs.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
dfs.period=10
dfs.servers=@GANGLIA@:8649

mapred.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
mapred.period=10
mapred.servers=@GANGLIA@:8649

jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
jvm.period=10
jvm.servers=@GANGLIA@:8649

rpc.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
rpc.period=10
rpc.servers=@GANGLIA@:8649


こんな感じ。