2014年12月11日 星期四

Hadoop Sequence file 看起來怪怪的?

有時候,透過 Flume 傳送file (使用spool soruce) 給 HDFS 儲存,內容如下:
a.txt
a file is here
b.txt
b file is here

當查看 HDFS上的 Hadoop squence file 時
使用
$ hdfs dfs -cat <SEQUENCEFILE>
 顯示

SEQ!org.apache.hadoop.io.LongWritableorg.apache.hadoop.io.TextK▒*▒▒     ▒▒▒▒͇J<▒▒a file is herJ<▒▒b file is here


這是因為存的是 sequence file ,所以前頭會顯示"SEQ" 而"!org.apache.hadoop.io.LongWritableorg.apache.hadoop.io.Text" 則是包含此sequence data中,key/value的 class type。

如果想要看到文字內容,可使用
$ hdfs dfs -text <SEQUENCEFILE>

1418355275278   a file is here
1418355275280   b file is here


如果下載下來(仍然是squence , 必須透過一些轉換指令才能觀看例如: strings, od .. 等)
$ hdfs dfs -get <SEQUENCEFILE>
$ strings <SEQUENCEFILE>

!org.apache.hadoop.io.LongWritable
org.apache.hadoop.io.Text
a file is here
b file is here

[Reference]
http://stackoverflow.com/questions/23827051/sequence-and-vectors-from-csv-file

2014年12月1日 星期一

Python 處理 generator所產生的Dictionary Result

在 Django 中,
當我們想將 python 透過 HappyBase scan function 取得的 HBase Table scan resualt,
呈現在網頁上時

Example: 'pytest' Table
RowKey    f:id
"John"    "a"
"Mary"   "b"
"Tom"    "c"

views.py (回傳 HBase scan result 給 detail.html)
...
connection = happybase.Connection('192.168.0.7')
connection.open()
table = connection.table('pytest')
result = table.scan(columns=['f:id'], filter="SingleColumnValueFilter('f', 'id', !=, 'binary:a')")
template = loader.get_template('app1/detail.html')
context = Context({'messages': result, })
return HttpResponse(template.render(context))
...

connection = happybase.Connection('192.168.0.7')
connection.open()
使用HappyHBase連結到HBase(實際上是連結到Zookeeper,尚不知為何不用設定zookeeper的Port)

table = connection.table('pytest')
result = table.scan(columns=['f:id'], filter="SingleColumnValueFilter('f', 'id', !=, 'binary:a')")
對HBase上的 "pytest" Table 做 scan,篩選出 'f:id'不等於"a" 的row,並只回傳row的 id那欄

template = loader.get_template('app1/detail.html')
context = Context({'messages': result, })
return HttpResponse(template.render(context))
將result回傳包成HttpResponse,並回傳給指定的html template

-----------------HTML 顯示方法 1 ---------------------
若直接在html中顯示值:
detail.html
{% for v in messages %}
    {{v}}
    <br>

{% endfor %}

會顯示
('Mary', {'f:id': 'b'})
('Tom', {'f:id': 'c'})

(X1,X2, ...) => python的 Tuple 型態
{a1:b1, a2:b2, ...} => python的 Dictionary型態(類似java的Map)
--------------------------------------------

----------------HTML 顯示方法 2 -------------------
但如果我們只需要呈現 rowkey以及 id的值 則必須

views.py中再加入

@register.filter
def get_item(dictionary, key):    
     return dictionary.get(key)

並且於 detail.html中加入

{% for k, v in messages %}  <-- k, v對應tuple中的兩個值
    {{ k }}
    {% for id in v %}
        {{ v | get_item:id }} <-- Dictionary type的只能用這種方式取值
    {% endfor %}
{% endfor %}

就會顯示
Mary  b
Tom   c
--------------------------------------------