python cgi 入門…

由於 PHP 在 Thrift 連接 hdfs 的時候上傳檔案一直怪怪的,不曉得是哪裡的問題,

又鑑於 Python 的熱門(GAE,框架..)等等原因,還是得學一下

裝了 mod_python 以後就能開始寫了,好像 mod_wsgi  也可以,只是不太懂幹麼用的…再亂設一堆 http.conf 設到能跑為止…

//httpd.conf
LoadModule python_module modules/mod_python.so
PythonDebug On
AddHandler cgi-script .py

Python 不像 PHP 一樣專門用來寫 Web 所以基礎環境沒辦法很輕鬆的開發 Web,連錯誤訊息也看不太到

所幸好像 cgitb.enable() 以後就有錯誤訊息debug了?!

import cgi,cgitb,os
cgitb.enable()

要寫一個可以顯示在瀏覽器的網頁要自己輸出 http header 與宣告自己的直譯器位置,

跟以往用 c 寫 cgi 應該視差不多的方式,範例:

#!/usr/bin/python
print 'Content-type: text/html\n'
print 'Hello World!'

好險資源不少,官方網站就有不錯的教學[2],又有網站[1] 將基礎動態網頁長寫的範例都寫出來…馬上能夠對應至原先 PHP 的經驗,

不熟悉的函式如同php去查 reference[3] ,又有較完整的物件與 package 結構,唯一的缺點就是有點稍嫌古怪的語法,

比較不相容以往一系列學過基礎語法同種的語言…C , Java , PHP , JavaScript。

等基礎 cgi 寫法 熟悉後再來學 django 吧!

參考資源

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();

[參考資源]

宮崎駿 魔法公主

今天看完了這部宮崎駿的魔法(幽靈、生靈)公主,
此片與其他作品比起來,比較不適合兒童觀看,包含了一些較血腥與表達方式較外放的畫面,

曾經看到影評解釋,這部1997年的片子在當時是90年代他的低潮,在他富有環境關懷的作品下,
不斷的思考,無法獲得解答的情況,不停的加深他對人類與自然搏鬥的呈現,
所以採用較外放的暴力、衝突、誇張的方式讓劇情顯得相當驚悚,
而之後的神隱少女才開始慢慢融合二十年來的過程,將理念暗喻在較閤家觀賞的劇情內,
但我覺得如果要看他最真摯的情感,應該要從這部片中得以看出來,
一個人的成長,或許都類似影評描述的,可能會從成長直至瓶頸,再至突破,

但在這過程中,瓶頸的部份是最不被人所關注,但是作者可能最耗盡自己心力力求突破,
把所有的心情都寄放在作品之中,想要表達給世人…,所以顯得特別令人動容,
而此部的音樂 久石讓 – アシタカとサン 磅礴的氣勢搭配大片的森林與生靈的氣勢,
讓人不經意的深深投入故事劇情內跟著主角們在森林奔跑…

主角是一個被自然詛咒的部落王子,為瞭解除詛咒,踏上旅途尋找自然憤怒的原因,
而女主角是狼犬的女兒,生長在森林中,與麒麟族一同保護麒麟森林,

而劇情主要演著是人類為了追求科技與幸福,在自然演化下不停奪取自然資源,
而造成森林內生靈的憤怒,但卻無法改變的現況。
劇情中的森林守護神,可以奪走生命,也可以賦予生命,我另外想到的暗喻是就像植物一樣,晚上吸取二氧化碳,白天行光和作用一般…

另外一個讓我突然想到的地方是,人類追求耗費資源開發科技,真的有讓人們的生活過得更好嗎?
都市裡的人們汲汲營營的工作著,搭著最新的交通工具,做著最新的工作,跟數十年前比較起來,增加的工作量,增加的科技有帶來更好的生活品質與幸福嗎?
有的! 對那些少數的富有企業家們~,大部份的人們努力工作,似乎都只是金字塔下的齒輪,不斷運轉只求讓自己生存,但是堆起的卻是上層似是而非的幸福,
而少數真實為了人們追求幸福的上位者如同電影裡面的達達拉的黑帽,看似無情的對待自然,但其實也是對世間的無力,只能盡自己所能的照顧一群人的幸福…

更另我想到就像經濟學裡說的政治力介入市場控制價格,最終只會造成稀有資源的分配不均與不正常的匱乏而已…
人們生存的方式與慾望,不停的耗費自然資源,最終連自己都無法替自己定義出幸福 …故事裡令人難過的不只是森林…