記錄下最近兩天散仙在工做中遇到的有關Pig0.12.0和Solr4.10.2一些問題總共有3個以下
1問題一 如何Pig中使用ASCII和十六進制hexadecimal的分隔符進行加載和切分數據
注意關於這個問題在Pig中會反應到2個場景中
第一 在Pig加載load數據時候 。
第二 在Pig處理split或則正則截取數據的時候。
先稍微說下爲啥使用十六進制的字段分隔符而不是咱們常見的空格逗號冒號分號#號等這些字符雖然也可使用可是若是咱們數據中有和這些符號衝突的數據那麼在解析時就會發生一些出人意料的Bug因此爲了保險起見選用肉眼不可讀的十六進制的數據是一個不錯的選擇固然這也是針對場景來講的看狀況決定。
關於詳細的ASCII和十六進制二進制八進制十進制的文檔介紹請參考維基百科全書。
下面繼續回到正題本例中咱們的數據格式是這樣存儲的
html
每行一條記錄,UTF-8編碼 apache
每條記錄都包括字段名和字段內容 api
字段之間用ascii碼1分隔 eclipse
字段名與內容之間用ascii碼2分隔 ide
每行一條記錄,UTF-8編碼 每條記錄都包括字段名和字段內容 字段之間用ascii碼1分隔 字段名與內容之間用ascii碼2分隔
一個在eclipse中的小例子以下
函數
public static void main(String[] args) { ui
//注意\1和\2在咱們的IDE中NotePad++中Linux的終端設備的界面中都會呈現不一樣的 編碼
//顯示方式你們能夠在維基百科中詳細瞭解下
//數據示例
String s="prod_cate_disp_id019";
//split規則
String ss[]=s.split("\2");
for(String st:ss){
System.out.println(st);
}
}
public static void main(String[] args) { //注意\1和\2在咱們的IDE中NotePad++中Linux的終端設備的界面中都會呈現不一樣的 //顯示方式你們能夠在維基百科中詳細瞭解下 //數據示例 String s="prod_cate_disp_id019"; //split規則 String ss[]=s.split("\2"); for(String st:ss){ System.out.println(st); } }
關於load函數加載時支持的分隔符類型你們能夠參考官網的文檔
下面看在Pig腳本的代碼
--Hadoop技術交流羣415886155
/*Pig支持的分隔符包括
1,任意字符串
2,任意轉義字符
3dec的字符\\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;
--Hadoop技術交流羣415886155 /*Pig支持的分隔符包括 1,任意字符串 2,任意轉義字符 3dec的字符\\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發現裏面打印的一些信息以下
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
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中也能正常查詢到數據。若是你也發生了相似的狀況請首先確保你能正確的獲取到數據不管是從遠程讀取的仍是解析wordexcel或者txt裏面的數據都要首先肯定可以正確的把數據解析出來而後若是仍是沒建成功可根據solr的log或者拋出的異常提示進行修復 。