Apache Pig和Solr問題筆記(一)

記錄下最近兩天散仙在工做中遇到的有關Pig0.12.0和Solr4.10.2一些問題,總共有3個,以下: 

(1)問題一: 如何Pig中使用ASCII和十六進制(hexadecimal)的分隔符進行加載,和切分數據? 

注意關於這個問題,在Pig中,會反應到2個場景中, 
第一: 在Pig加載(load)數據時候 。 
第二: 在Pig處理split,或則正則截取數據的時候。 

先稍微說下,爲啥使用十六進制的字段分隔符,而不是咱們常見的空格,逗號,冒號,分號,#號,等,這些字符,雖然也可使用,可是若是咱們數據中有和這些符號衝突的數據,那麼在解析時,就會發生一些出人意料的Bug,因此,爲了保險起見,選用肉眼不可讀的十六進制的數據,是一個不錯的選擇,固然這也是,針對場景來講的,看狀況決定。 

關於詳細的ASCII和十六進制,二進制,八進制,十進制的文檔介紹,請參考維基百科全書。 

下面繼續回到正題,本例中,咱們的數據格式是這樣存儲的: 

Java代碼   複製代碼  收藏代碼
  1. 每行一條記錄,UTF-8編碼;   
  2. 每條記錄都包括字段名和字段內容;   
  3. 字段之間用ascii碼1分隔;   
  4. 字段名與內容之間用ascii碼2分隔;  


一個在eclipse中的小例子以下:  
Java代碼   複製代碼  收藏代碼
  1. public static void main(String[] args) {   
  2.     //注意\1和\2,在咱們的IDE中,NotePad++中,Linux的終端設備的界面中,都會呈現不一樣的   
  3.     //顯示方式,你們能夠在維基百科中,詳細瞭解下   
  4.     //數據示例   
  5.     String s="prod_cate_disp_id 019";   
  6.     //split規則   
  7.     String ss[]=s.split("\2");   
  8.     for(String st:ss){   
  9.         System.out.println(st);   
  10.     }   
  11. }  



關於load函數,加載時支持的分隔符類型,你們能夠參考官網的文檔 
下面看在Pig腳本的代碼: 

Java代碼   複製代碼  收藏代碼
  1. --Hadoop技術交流羣:415886155  
  2. /*Pig支持的分隔符包括:  
  3. 1,任意字符串,  
  4. 2,任意轉義字符  
  5. 3,dec的字符\\u001 或者 \\u002  
  6. 4,十六進行字符 \\x0A  \\x0B  
  7. */  
  8. --注意這個load時的分隔符,表明ASCII的1,做爲Pig裏面的dec直接解析方式   
  9. a = load '/tmp/dongliang/20150401/20150301/tmp_search_keywords_cate_stat/' using PigStorage('\\u001') ;   
  10.   
  11. /**  
  12.  
  13. 注意下面的分割符^B,這個符號是脫元字符,只會在終端設備上  
  14. 顯示,這個符號,表明ASCII的2  
  15. */  
  16. a = foreach a generate   REGEX_EXTRACT ($0'(.*)^B(.*)'2) as time ,   
  17.                          REGEX_EXTRACT ($1'(.*)^B(.*)'2) as kw ,   
  18.                          REGEX_EXTRACT ($2'(.*)^B(.*)'2) as ic ,   
  19.                          REGEX_EXTRACT ($3'(.*)^B(.*)'2) as cid,   
  20.                          REGEX_EXTRACT ($4'(.*)^B(.*)'2) as cname,   
  21.                          REGEX_EXTRACT ($5'(.*)^B(.*)'2) as pname,   
  22.                          REGEX_EXTRACT ($6'(.*)^B(.*)'2) as snt,   
  23.                          REGEX_EXTRACT ($7'(.*)^B(.*)'2) as cnt,   
  24.                          REGEX_EXTRACT ($8'(.*)^B(.*)'2) as fnt,   
  25.                          REGEX_EXTRACT ($9'(.*)^B(.*)'2) as ant,   
  26.                          REGEX_EXTRACT ($10'(.*)^B(.*)'2) as pnt ;   
  27.   
  28. --獲取字符串長度   
  29. a = foreach a generate SIZE(cid) as len;   
  30. --按長度分組   
  31. b = group a by len;   
  32. --統計各個長度下的數量   
  33. c = foreach b generate group, COUNT($1);   
  34. --輸出打印   
  35. 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代碼   複製代碼  收藏代碼
  1. 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}   
  2. INFO  - 2015-04-01 21:08:36.098; org.apache.solr.update.DirectUpdateHandler2; No uncommitted changes. Skipping IW.commit.   
  3. 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   
  4. 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或者拋出的異常提示,進行修復 。 

相關文章
相關標籤/搜索