hadoop 0.21.0 ant build thrift php

名詞解釋
hadoop : 分散式檔案系統與 MapReduce 運算軟體框架
HDFS : 分散式檔案系統
ant : Java 自動編譯工具
thrift : 跨語言 API 介面,由 Facebook 開發用來銜接各語言 api 。

編譯 hadoop 建立 thrift server 

$ install ant
$ cd ./hdfs ;
$ ant compile

if error

[ivy:resolve] module not found: org.apache.hadoop#hadoop-common;0.21.0

原先的 repo snapshot 檔名都換過了,將 build.xml 內 repo 網址改成

https://repository.apache.org/content/repositories/snapshots/ => https://repository.apache.org/service/local/repositories/orgapachehadoop-042/content/

從 https://repository.apache.org/index.html 找到的

編譯 again

warning ‘includeantruntime’ was not set

錯誤 依照錯誤行數 在 javac 加上 includeantruntime=”false” 屬性就略過了 (http://www.coderanch.com/t/503097/tools/warning-includeantruntime-was-not-set)

接著會有 lib not fount 的錯誤

搬移 $hadoop/lib to hdfs/lib 應該是因為 抓的是 release 不是 dev 的版本 目錄位置有些差異,

然後發現缺了 conf ,所以對著 $hadoop/common 造著編譯一次,

然後混和兩個資料夾,我是建了一個 $hadoop/build

然後 cp $hadoop/common $hadoop/build -r ; cp $hadoop/hdfs $hadoop/build -ru

hdfs thrift server 環境就差不多了,thrift 負責建立一個 socket ,然後用各種語言透過 socket 連接 API 。

為什麼要自己編譯 hadoop 呢?我也不知道…感覺可以把編譯好的 hadoop-thrift.jar 拿來用,但是沒有地方有教…

只好照著有人有教的方式做,就編譯吧,順便瞭解一下原始碼路徑,大略看一下程式邏輯,並且之後還能做修改。

編譯 thrift-php ext

接著要建立 php 連接 thrift 的環境,可以先裝 thrift (http://thrift.apache.org/) 只是用不到= =,

thrift 應該是用來把寫好的 *.thrift(抽象API描述) 編譯成各種語言適用的API,只是 hadoop 已經都編譯好了,在 gen-php 裡面,

thrift 下載好以後,裡面有附 php-ext module 的程式,就一樣phpize;./configure;make ;make install;

他好像會在 /usr/lib/php/ 下面複製好對應的程式,./protocol/ , ./transport/ , ./Thrift.php …應該是吧 如果沒有就自己從 Thrift 原始碼裡面 co 出來吧,

然後建立一個 /usr/lib/php/packages/ 然後把 gen-php 丟進去 改名字叫…XD…原始碼裡面有寫…自己看…

example

進資料夾跑 build/src/contrib/thriftfs/scripts/start_thrift_serve.sh $port & 吧 ,可以指定 port,他會連結哪台伺服器一樣在 conf/core-site.xml 裡面設定,

然後在跑 client demo ..應該還ok,只是不知道 thrift_protocol 有作用嗎…

<?php
//include thrift路徑
$GLOBALS['THRIFT_ROOT'] = '/usr/lib/php';
require_once( $GLOBALS['THRIFT_ROOT'].'/Thrift.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/packages/hadoopfs/ThriftHadoopFileSystem.php' );
//建立連線
$socket = new TSocket( 'localhost', 50000 );
$socket->setSendTimeout( 10000 ); // Ten seconds
$socket->setRecvTimeout( 20000 ); // Twenty seconds
$transport = new TBufferedTransport( $socket );
$protocol = new TBinaryProtocol( $transport );
$client = new ThriftHadoopFileSystemClient( $protocol );
//啟動
$transport->open();
/*程式碼寫在這*/
try {
$pathname = new Pathname(array("pathname" => "/mlwmlw/"));
print_r($client->mkdirs($pathname));
<div>$pathname = new Pathname(array("pathname" => "/"));
<div>//列表
print_r($client->listStatus($pathname));
//用帳號名稱相同就能跨伺服器存取資料 權限很弱喔?!
} catch(Exception $e) {
print_r($e);
}
$transport->close();
?>

接著測 create and write 的部份就出錯了,錯誤訊息有兩種,第一次都是
TException: TSocket: Could not write 4 bytes
接著都是 TScoket timeout,在某篇資源裡面有提到他猜測是 php 處理 64bit 的整數時造成的錯誤,
因為 Thrift 有定義 64bit 整數的型態,然後API裡面有一個 readI64 的函式,好像是在合成兩個 32bit 的整數,
我自己試著去把 create 產生的 fileid 印出來,跟 HadoopThriftServer 進行比對,
發現總是對不起來,因為 create 產生的是 getRandom().nextLong() 好像都是滿滿 64bit 的長整數,
將他替換成 nextInt() 重新編譯就沒有問題了。

#org/apache/hadoop/thriftfs/HadoopThriftServer.java 50行
-- private long nextId = new Random().nextLong();
++ private long nextId = new Random().nextInt();

[參考資源]

PHP 5.3.3 Closure

心血來潮,把本來伺服器上 yum 裝的 PHP 換成 5.3.3 ,搭配 yum 安裝的 httpd 遇到一些小問題,都好解決,紀錄一下

yum install httpd-devel mysql-devel

./configure –with-apxs2=/install-path –with-mysql=/install-path

再裝就沒什麼問題了

然後就來寫一下

$curry = function($a) {
   return function($b) use ($a) {
      return $a+$b;
   }
}
$curry_add= $curry(1);
echo $curry_add(2);// result = 3
($curry(1))(2); //error

感覺學的跟 JavaScript 很像,又多了一些蠻麻煩的語法 (use),本身感覺又不像 Js 開發流程的輕便,感覺有點不太適合這樣寫..

有點怪..

codeIgniter Module 模組擴充

codeIgniter 的mvc模式,要分別在Controllers,views,models下分別建立對應的程式,實際上程式都是有單位的存在的,一個部落格會有blog_controller blog_models blog_views..等等 mvc 的程式,但被分散在三個資料夾,當程式的單位不只有 blog 而已,越來越多時就變的不太好管理。

剛開始在官網wiki上看到 http://codeigniter.com/wiki/Modular_Extensions_-_HMVC/ 這個library,他引入一種 HMVC 的觀念,將原始資料夾結構增加了 Modules 資料夾,並在內部每個資料夾下都有個 mvc 的資料夾,稱之為 Hierarchical-Model-View-Controller模式,也就是階層式的 MVC 引入一種模組的概念,每個子功能都是一個模組,分別管理維護,互不影響運作。

但是當初為了專案擴充的需要,想讓模組內還有模組,就無法單純使用這個 Lib 來滿足,有對他核心做些簡單的修改,但是其實這個library幾乎把 codeIgniter 核心都覆寫過了,所以更新 ci 版本時應該會有一些問題,後來發現一套 http://codeigniter.com/wiki/Matchbox/ matchbox,似乎提供更完整的載入函式,可以指定要載入的模組,但沒實際使用過,但看起來也一段時間沒更新了,而 hmvc 甚至還搬家了, http://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc,蠻久沒有看過他的更新,但 ci 模組的擴充應該就這兩套較完整。

如果要用 modules ~也可以考慮使用 Kahana 看看,他是 codeigniter 的分支但是內建支援以模組為單位。

PHP – null 妙用無窮…

  自從開始使用codeIgniter之後,在產生SQL時都藉由他的ActiveRecord來產生,一來是不用自己輸入又臭又長的SQL外,在某些時候又可以方便的將Update與Insert的差異降到很小,新增寫好要加上修改瞬間變得很容易,只需要補上一個條件式來分開處理ActiveRecord的最後一行。

  而當這種時候當然view也是同時可以共用的機會囉,將欄位的預設值都寫入於控制器撈出來的值以後,就可以共用同個介面將值都載入了,但是一直以來在這都有個難堪的地方不好解決,就是當要新增的時候自然不會有預設值,那預設值那些$value所產生的未定義變數的警告訊息要怎麼解決呢?

  最近在php看到剛好有人討論,可以透過將預設值的陣列丟入一個null來解決!實在是很神奇又簡單的解決這個問題,仔細想也挺有道理,雖不太理解null運作的細節,但還是大致可以理解為何可以運作,同時處理這兩件事變得輕鬆又優雅~!

codeIgniter with tcpdf , Integration 

tcpdf 是一套在php上很完整與活躍的開放原始碼程式,用於產生pdf函式庫,當要和codeIgniter搭配時好像沒那麼容易,需要有一個可直接連接的網址,官方wiki上有人寫了一個連接器,做了完整的接合,與設定的說明,

http://codeigniter.com/wiki/TCPDF-CodeIgniter_Integration/ 

但是裝上去以後發生了這個錯誤訊息,

Use of undefined constant K_CELL_HEIGHT_RATIO – assumed ‘K_CELL_HEIGHT_RATIO’

後來在這篇看到解決方案,http://codeigniter.com/forums/viewthread/133243/#661005

主要是這這回覆提出的,

I’ve seen this problem too, and I adjusted the tcpdf.php file around line 948 (version 4.6.013):

protected $cell_height_ratio = 1.25; //K_CELL_HEIGHT_RATIO;

So I just hardcoded the value 1.25 – got the value from tcpdf_config.php.

仔細追蹤後發現,為什麼會出現這個問題呢?

因為聯接器裡面主要在做的事就是重新定義他的config檔,放在codeIgniter的configs資料夾下,然後透過lib內的檔案將參數讀進來並設定初始化,在某個的tcpdf版本下可能可行,在5.3版下就發生了這個錯誤訊息,主要是因為常數集的定義順序,被這一行給破壞了,

protected $cell_height_ratio = K_CELL_HEIGHT_RATIO;

他寫在不是建構子的地方,所以定義常數時來不及在這個常數使用之前,所以我決定不改變原始程式碼,在lib內物件繼承上方寫上 define(‘K_CELL_HEIGHT_RATIO’, 1.25); 在較不破壞的情況下解決這個問題。