hive-solr4
使用Hive讀寫(xiě)solr4,由于市面上沒(méi)有solr4這個(gè)版本的組件于是我自己根據(jù)hive-solr5的代碼改了一個(gè)
(一)Hive+Solr簡(jiǎn)介
Hive作為Hadoop生態(tài)系統(tǒng)里面離線的數(shù)據(jù)倉(cāng)庫(kù),可以非常方便的使用SQL的方式來(lái)離線分析海量的歷史數(shù)據(jù),并根據(jù)分析的結(jié)果,來(lái)干一些其他的事情,如報(bào)表統(tǒng)計(jì)查詢等。
Solr作為高性能的搜索服務(wù)器,能夠提供快速,強(qiáng)大的全文檢索功能。
(二)為什么需要hive集成solr?
(1)簡(jiǎn)單: 如果單純的使用Hadoop編程或者Spark編程來(lái)構(gòu)建索引,當(dāng)然也是可以的,只不過(guò)比較復(fù)雜而已,而且容易出錯(cuò),如果我們把編程通過(guò)抽象,封裝,簡(jiǎn)化到SQL中,那么整個(gè)流程就會(huì)變得非常簡(jiǎn)單,通過(guò)借助強(qiáng)大的Hive來(lái)駕馭hadoop或spark,是非常方便的。
(2)優(yōu)劣互補(bǔ):有時(shí)候,我們需要將hive的分析完的結(jié)果或者直接對(duì)hive源表,存儲(chǔ)到solr里面進(jìn)行全文檢索服務(wù),比如以前我們有個(gè)業(yè)務(wù),對(duì)我們電商網(wǎng)站的搜索日志使用hive分析完后
存儲(chǔ)到solr里面做報(bào)表查詢,因?yàn)槔锩嫔婕暗剿阉麝P(guān)鍵詞,這個(gè)字段是需要能分詞查詢和不分詞查詢的,通過(guò)分詞查詢可以查看改詞的相關(guān)的產(chǎn)品在某一段時(shí)間內(nèi)的一個(gè)走勢(shì)圖。
有時(shí)候,我們又需要將solr里面的數(shù)據(jù)加載到hive里面,使用sql完成一些join分析功能, 兩者之間優(yōu)劣互補(bǔ),以更好的適應(yīng)我們的業(yè)務(wù)需求。
(3)快速:借助Hadoop分布式特性讓快速構(gòu)建大規(guī)模的索引成為可能。
(4)與時(shí)俱進(jìn):支持新版本hive,hadoop,solrcloud使用,網(wǎng)上已經(jīng)有一些hive集成solr的開(kāi)源項(xiàng)目,但由于
版本比較舊,所以無(wú)法在新的版本里面運(yùn)行,經(jīng)過(guò)改造修補(bǔ)后的可以運(yùn)行在最新的版本。
(三)如何才能使hive集成solr?
所謂的集成,其實(shí)就是重寫(xiě)hadoop的MR編程接口的一些組件而已。我們都知道MR的編程接口非常靈活,而且高度抽象,MR不僅僅可以從HDFS上加載
數(shù)據(jù)源,也可以從任何非HDFS的系統(tǒng)中加載數(shù)據(jù),當(dāng)然前提是我們需要自定義:
InputFormat
OutputFormat
RecordReader
RecordWriter
InputSplit
組件,雖然稍微麻煩了點(diǎn),但從任何地方加載數(shù)據(jù)這件事確實(shí)可以做到,包括mysql,sqlserver,oracle,mongodb,
solr,es,redis等等。
上面說(shuō)的是定制Hadoop的MR編程接口,在Hive里面除了上面的一些組件外,還需要額外定義SerDe組件和組裝StorageHandler,在hive里面
SerDe指的是 Serializer and Deserializer,也就是我們所說(shuō)的序列化和反序列化,hive需要使用serde和fileinput來(lái)讀寫(xiě)hive 表里面的一行行數(shù)據(jù)。
讀的流程:
HDFS files / every source -> InputFileFormat --> <key, value> --> Deserializer --> Row object
寫(xiě)的流程:
Row object --> Serializer --> <key, value> --> OutputFileFormat --> HDFS files / every source
(四)hive集成solr后能干什么?
(1)讀取solr數(shù)據(jù),以hive的支持的SQL語(yǔ)法,能進(jìn)行各種聚合,統(tǒng)計(jì),分析,join等
(2)生成solr索引,一句SQL,就能通過(guò)MR的方式給大規(guī)模數(shù)據(jù)構(gòu)建索引
(五)如何安裝部署以及使用?
非常簡(jiǎn)單,使用git clone https://github.com/wangyongshun98/hive2solr4.git 后,修改少許pom文件后,執(zhí)行
mvn clean package
命令構(gòu)建生成jar包,并將此jar包拷貝至hive的lib目錄即可
例子如下:
(1)hive讀取solr數(shù)據(jù)
建表:
--存在表就刪除
drop table if exists solr;
--創(chuàng)建一個(gè)外部表
create external table solr (
--定義字段,這里面的字段需要與solr的字段一致
rowkey string,
sname string
)
--定義存儲(chǔ)的storehandler
stored by "com.wys.hive.store.SolrStorageHandler"
--配置solr屬性
tblproperties('solr.url' = 'http://192.168.1.28:8983/solr/a',
'solr.query' = '*:*',
'solr.cursor.batch.size'='10000',
'solr.primary_key'='rowkey'
);
執(zhí)行bin/hive 命令,進(jìn)行hive的命令行終端:
--查詢所有數(shù)據(jù)
select * from solr limit 5;
--查詢指定字段
select rowkey from solr;
--以mr的方式聚合統(tǒng)計(jì)solr數(shù)據(jù)
select sname ,count(*) as c from solr group by sname order by c desc
(2)使用hive+單機(jī)solr例子
首先構(gòu)建數(shù)據(jù)源表:
--如果存在就刪除
drop table if exists index_source;
--構(gòu)建一個(gè)數(shù)據(jù)表
CREATE TABLE index_source(id string, yname string,sname string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE;
--向數(shù)據(jù)源里面導(dǎo)入本地?cái)?shù)據(jù)
load data local inpath '/ROOT/server/hive/test_solr' into table index_source;
其次,構(gòu)建solr的關(guān)聯(lián)表:
--刪除已經(jīng)存在的表
drop table if exists index_solr;
--創(chuàng)建關(guān)聯(lián)solr表
create external table index_solr (
id string,
yname string,
sname string
)
--定義存儲(chǔ)引擎
stored by "com.wys.hive.store.SolrStorageHandler"
--設(shè)置solr服務(wù)屬性
tblproperties('solr.url' = 'http://192.168.1.28:8983/solr/b',
'solr.query' = '*:*',
'solr.cursor.batch.size'='10000',
'solr.primary_key'='id',
'is.solrcloud'='0'
);
最后,執(zhí)行下面的sql命令,即可給數(shù)據(jù)源中的數(shù)據(jù),構(gòu)建solr索引:
--注冊(cè)hive-solr的jar包,否則MR方式運(yùn)行的時(shí)候,將不能正常啟動(dòng)
add jar /ROOT/server/hive/lib/hive-solr.jar;
--執(zhí)行插入命令
INSERT OVERWRITE TABLE index_solr SELECT * FROM index_source ;
--執(zhí)行成功之后,即可在solr的終端界面查看,也可以再hive里面執(zhí)行下面的solr查詢
select * from index_solr limit 10 ;
(3)使用hive+solrcloud集群例子
首先構(gòu)建數(shù)據(jù)源表和(2)中步驟一樣
創(chuàng)建關(guān)聯(lián)表:
-- 加上這個(gè)比較保險(xiǎn),否則數(shù)據(jù)量大的時(shí)候,在其他機(jī)器是沒(méi)辦法獲取這個(gè)jar,而拋出空指針的
add jar /ROOT/server/hive/hive-solr.jar;
--存在表就刪除
drop table if exists solr;
--創(chuàng)建一個(gè)外部表
create external table solr (
--定義字段,這里面的字段需要與solr的字段一致
rowkey string,
title string ,
content string ,
dtime string ,
t1 string ,
t2 string ,
t3 string
)
--定義存儲(chǔ)的storehandler
stored by "com.wys.hive.store.SolrStorageHandler"
--配置solr屬性
tblproperties('solr.url' = '192.168.1.187:2181,192.168.1.184:2181,192.168.1.186:2181',
'solr.query' = '*:*',
'solr.cursor.batch.size'='30000',
'solr.primary_key'='rowkey' ,
'is.solrcloud'='1',
'collection.name'='big_search'
);
最后執(zhí)行語(yǔ)句,對(duì)源表進(jìn)行大規(guī)模構(gòu)建索引:
-- 關(guān)閉推測(cè)執(zhí)行
set mapreduce.map.speculative=false;
set mapreduce.reduce.speculative=false;
--set mapreduce.job.running.map.limit=1;
--注冊(cè)hive-solr的jar包,否則MR方式運(yùn)行的時(shí)候,將不能正常啟動(dòng)
add jar /ROOT/server/hive/hive-solr.jar;
--執(zhí)行插入命令
INSERT OVERWRITE TABLE solr SELECT * FROM index_source ;
--執(zhí)行成功之后,即可在solr的終端界面查看,也可以再hive里面執(zhí)行下面的solr查詢
構(gòu)建完畢后,就可以在hive里面查詢solr的數(shù)據(jù)了,當(dāng)然,如果不是join,或者使用sql分析一些solr辦不到的操作時(shí),不建議直接在
hive中查詢solr,因?yàn)樾蕸](méi)有直接在solr中查詢的高
-- 添加依賴的jar
add jar /ROOT/server/hive/hive-solr.jar;
--執(zhí)行sql統(tǒng)計(jì),執(zhí)行跑一個(gè)mr作業(yè)
select count(*) from solr;
(六)他們還能其他的框架集成么?
當(dāng)然,作為開(kāi)源獨(dú)立的框架,我們可以進(jìn)行各種組合, hive也可以和elasticsearch進(jìn)行集成,也可以跟mongodb集成,
solr也可以跟spark集成,也可以跟pig集成,但都需要我們自定義相關(guān)的組件才行,思路大致與這個(gè)項(xiàng)目的思路一致。
(七)本次測(cè)試通過(guò)的基礎(chǔ)環(huán)境
Apache Hadoop2.6.0
Apache Hive1.1.0
Apache Solr4.10.3
(八)感謝并參考的資料:
https://github.com/mongodb/mongo-hadoop/tree/master/hive/src/main/java/com/mongodb/hadoop/hive
https://github.com/lucidworks/hive-solr
https://github.com/chimpler/hive-solr
https://cwiki.apache.org/confluence/display/Hive/DeveloperGuide#DeveloperGuide-HowtoWriteYourOwnSerDe
http://git.oschina.net/dearbaba/hive2solr/tree/master/hive2solr/