Apache Pig和Solr問題筆記(一)
記錄下最近兩天散仙在工做中遇到的有關Pig0.12.0和Solr4.10.2一些問題,總共有3個,以下: (1)問題一: 如何Pig中使用ASCII和十六進制(hexadecimal)的分隔符進行加載,和切分數據? 注意關於這個問題,在Pig中,會反應到2個場景中, 第一: 在Pig加載(load)數據時候 。 第二: 在Pig處理split,或則正則截取數據的時候。 先稍微說下,爲啥使用十六進制的字段分隔符,而不是咱們常見的空格,逗號,冒號,分號,#號,等,這些字符,雖然也可使用,可是若是咱們數據中有和這些符號衝突的數據,那麼在解析時,就會發生一些出人意料的Bug,因此,爲了保險起見,選用肉眼不可讀的十六進制的數據,是一個不錯的選擇,固然這也是,針對場景來講的,看狀況決定。 關於詳細的ASCII和十六進制,二進制,八進制,十進制的文檔介紹,請參考維基 百科全書。 下面繼續回到正題,本例中,咱們的數據格式是這樣存儲的:
Java代碼
每行一條記錄,UTF-8 編碼;
每條記錄都包括字段名和字段內容;
字段之間用ascii碼1 分隔;
字段名與內容之間用ascii碼2 分隔;
一個在eclipse中的小例子以下:
Java代碼
public static void main(String[] args) {
//注意\1和\2,在咱們的IDE中,NotePad++中,Linux的終端設備的界面中,都會呈現不一樣的
//顯示方式,你們能夠在維基百科中,詳細瞭解下
//數據示例
String s="prod_cate_disp_id 019" ;
//split規則
String ss[]=s.split("\2" );
for (String st:ss){
System.out.println(st);
}
}
關於load函數,加載時支持的分隔符類型,你們能夠參考官網的文檔 下面看在Pig腳本的代碼:
Java代碼
--Hadoop技術交流羣:415886155
/*Pig支持的分隔符包括:
1,任意字符串,
2,任意轉義字符
3,dec的字符\\u001 或者 \\u002
4,十六進行字符 \\x0A \\x0B
*/
--注意這個load時的分隔符,表明ASCII的1 ,做爲Pig裏面的dec直接解析方式
a = load '/tmp/dongliang/20150401/20150301/tmp_search_keywords_cate_stat/' using PigStorage('\\u001' ) ;
/**
注意下面的分割符^B,這個符號是脫元字符,只會在終端設備上
顯示,這個符號,表明ASCII的2
*/
a = foreach a generate REGEX_EXTRACT ($0 , '(.*)^B(.*)' , 2 ) as time ,
REGEX_EXTRACT ($1 , '(.*)^B(.*)' , 2 ) as kw ,
REGEX_EXTRACT ($2 , '(.*)^B(.*)' , 2 ) as ic ,
REGEX_EXTRACT ($3 , '(.*)^B(.*)' , 2 ) as cid,
REGEX_EXTRACT ($4 , '(.*)^B(.*)' , 2 ) as cname,
REGEX_EXTRACT ($5 , '(.*)^B(.*)' , 2 ) as pname,
REGEX_EXTRACT ($6 , '(.*)^B(.*)' , 2 ) as snt,
REGEX_EXTRACT ($7 , '(.*)^B(.*)' , 2 ) as cnt,
REGEX_EXTRACT ($8 , '(.*)^B(.*)' , 2 ) as fnt,
REGEX_EXTRACT ($9 , '(.*)^B(.*)' , 2 ) as ant,
REGEX_EXTRACT ($10 , '(.*)^B(.*)' , 2 ) as pnt ;
--獲取字符串長度
a = foreach a generate SIZE(cid) as len;
--按長度分組
b = group a by len;
--統計各個長度下的數量
c = foreach b generate group, COUNT($1 );
--輸出打印
dump c;
(2)問題二:如何在Apache Solr中,查詢某個不分詞的field的長度,有多少個記錄? Solr裏面並無直接提供這樣相似JAVA裏的lenth這樣的函數,或者Pig裏面的SIZE這樣的函數,那麼咱們應該如何查詢呢? Solr雖然不直接支持這樣的查詢,可是咱們能夠經過正則查詢,來變相的實現這個目的,用法以下: (1)查詢固定長度 cid:/.{6}/ 只過濾長度爲6的記錄 (2)查詢範圍長度 cid:/.{6,9}/ 只過濾長度6到9的記錄 (3)查詢最少多少長度以上的cid:/.{6}.*/ 長度最少爲6的 (3)問題三:在使用Pig+MapReduce,向Solr中,批量添加索引時,發現,無任何錯誤異常,可是索引裏卻沒任何數據? 這是一個比較詭異的問題,原本,散仙以爲應該是程序出問題了,可是後來發現,一樣的代碼向另一個collection裏添加數據,就很正常,查看solr的log,發現裏面打印的一些信息以下:
Java代碼
INFO - 2015 -04 -01 21 :08 :36.097 ; org.apache.solr.update.DirectUpdateHandler2; start commit{,optimize=false ,openSearcher=true ,waitSearcher=true ,expungeDeletes=false ,softCommit=false ,prepareCommit=false }
INFO - 2015 -04 -01 21 :08 :36.098 ; org.apache.solr.update.DirectUpdateHandler2; No uncommitted changes. Skipping IW.commit.
INFO - 2015 -04 -01 21 :08 :36.101 ; org.apache.solr.core.SolrCore; SolrIndexSearcher has not changed - not re-opening: org.apache.solr.search.SolrIndexSearcher
INFO - 2015 -04 -01 21 :08 :36.102 ; org.apache.solr.update.DirectUpdateHandler2; end_commit_flush
解釋下上面的信息的意思,大概就是說在數據索引完了,可是沒有發現有commit的數據,因此跳過commit,這一點在程序跑的時候是很是奇怪的,由於數據源HDFS裏最少有110萬的數據,怎麼會沒有數據呢? 而後散仙經過谷歌搜索發現也有人發現相似的奇怪狀況,無任何異常的狀況下,重建索引成功,卻在索引裏沒有看見任何數據,並且最爲疑惑的是,這幾個網上已經有的案例,居然沒有一個有解決方案。 沒辦法了,只好再次查看程序,這一次散仙,把中間處理好須要建索引的數據,給打印出來看一下,到底什麼狀況,結果打印出來的都是一行行空數據,原來在使用正則截取數據時,原來的分隔符失效了,因此致使截取不到數據,這下問題基本定位了,solr索引裏沒有數據,確定是由於原本就沒有數據提交,致使的那個奇怪的log發生,結果在散仙把這個bug修復以後,再次重建索引,發現此次果真成功了,在Solr中,也能正常查詢到數據。若是你也發生了相似的狀況,請首先確保你能正確的獲取到數據,不管是從遠程讀取的,仍是解析word,excel,或者txt裏面的數據,都要首先肯定,可以正確的把數據解析出來,而後,若是仍是沒建成功,可根據solr的log或者拋出的異常提示,進行修復 。
歡迎關注本站公眾號,獲取更多信息