近期由於公司需要,研究了druid.io,下面是我遇到的一些問題以及解決辦法,當做記錄。
使用的druid.io版本爲0.12.3
1、使用druid-hdfs-storage擴展將hdfs用於深度存儲。使用Map / Reduce作業從hadoop批量加載數據。
公司已有的集羣是CDH-5.10.1版本,該版本的cdh使用hadoop2.6.0,druid.io的0.12.3版本中自帶的hadoop版本爲2.7.3,網上有資料說可以通過修改配置文件的方式改變hadoop版本,但是我一直沒有測試成功,所以最後採用的方法是重新編譯了druid.io,修改源碼中hadoop的版本爲2.6.0,具體的操作過程可以看這個鏈接https://blog.csdn.net/aubdiy/article/details/78270195
編譯完成之後會發現在extensions目錄下,mysql-metadata-storage擴展已經自動生成了,不需要格外添加。
將hadoop-dependencies/hadoop-client/2.6.0/目錄下的jar包替換成cdh安裝目錄下的jar包,jar包大概在****/CDH-5.10.1/lib/hadoop/lib地址可以找到。Druid中的每個節點都要替換掉。
修改/conf/druid/middleManager和/conf-quickstart/druid/middleManager目錄下的runtime.properties,在druid.indexer.runner.javaOpts後面添加-Dhdp.version=2.6.0 -Dhadoop.mapreduce.job.classloader=true
將Hadoop的core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml放到Druid每個節點的conf/druid/_common/目錄下。
2、使用kafka攝入數據
使用kafka攝入數據時經常出現12009 ms has passed since last append的報錯,這時候修改/config下的server.properties,
添加request.timeout.ms 和timout.ms ,這兩種配置默認值爲30000,可以適當增大這個值,但是這種方法好像治標不治本,我沒有找到其他的解決辦法,有其他解決辦法的話希望可以留言給我。
3、刪除數據
curl -XDELETE http://ip:8081/druid/coordinator/v1/datasources/{dataSourceName}
curl -X 'POST' -H 'Content-Type:application/json' -d @quickstart/deletedata.json http://ip:8081/druid/indexer/v1/task
deletedata.json的結構大致如下:
{
"type": "kill",
"dataSource": {dataSourceName},
"interval" : <all_segments_in_this_interval_will_die!>
}
關於interval的值,可以通過查看segment的詳細信息獲得:
curl -POST http://ip:8081/druid/coordinator/v1/metadata/datasources/{dataSourceName}/segments?full
4、更新數據
關於更新數據,我只在官方文檔上看到了解決方法,分爲3種,下面是文檔翻譯過來的:
1、更新維度值
如果您的維度需要經常更新值,請先嚐試使用 lookups。 lookups的經典用例是當您將一個ID維度存儲在Druid段中,並希望將ID維度映射到可能需要定期更新的可讀字符串值。
2、重建細分(重建索引)
如果查找不充分,您可以在特定的時間間隔內完全重建德魯伊片段。重建段稱爲重建索引數據。例如,如果要在現有細分中添加或刪除列,或者要更改細分的彙總粒度,則必須重新編制數據索引。
我們建議您保留原始數據的副本,以備您需要重新編制數據索引時使用。
3、處理延遲事件(Delta攝取)
如果您有批處理提取管道並且有延遲事件進入並希望將這些事件附加到現有段並避免使用重建索引重建新段的開銷,則可以使用增量提取。
粗略的可以理解爲:
第一種:更新 lookups,在 lookups中查詢數據,這種方法不會改變實際存儲在segment中的值。
第二種:直接重新攝入某一時間間隔的數據,這樣可以改變存儲在segment中的數據。
第三種:向舊段添加新行。
下面要說明的是第一種方法:
我是先向druid中註冊的lookup,然後再進行使用
如果你以前從來沒有配置查找,必須使用一個空的JSON對象{}
來/druid/coordinator/v1/lookups/config
初始化配置。
註冊查找:
curl -X 'POST' -H 'Content-Type:application/json' -d @quickstart/registerlookup.json http://ip:8081/druid/coordinator/v1/lookups/config
registerlookup.json的結構大致如下:
{
"__default": {
"org_no_customer1": {
"version": "v0",
"lookupExtractorFactory": {
"type": "map",
"map": {
"111": "222"
}
}
}
}
}
map中的‘111’即key值,是存儲在segment中的值,是舊數據,‘222’即value值,是要更新的新數據。
更新查找:
curl -X 'POST' -H 'Content-Type:application/json' -d @quickstart/updatelookup.json http://ip:8081/druid/coordinator/v1/lookups/config/__default/org_no_customer1
updatelookup.json的結構大致如下:
{
"version": "v1",
"lookupExtractorFactory": {
"type": "map",
"map": {
"111": "333"
}
}
}
在查找中查詢數據:
curl -X 'POST' -H 'Content-Type:application/json' -d @quickstart/querylookup.json http://ip:8082/druid/v2?pretty
querylookup.json的內容大致如下:
{
"queryType": "groupBy",
"dataSource": "energytest",
"granularity": "day",
"dimensions": [{
"type": "lookup",
"dimension": "org_no",
"outputName": "org_no",
"outputType": "STRING",
"name": "org_no_customer1"
},
{
"type": "default",
"dimension": "pap",
"outputName": "pap",
"outputType": "DOUBLE"
},
{
"type": "default",
"dimension": "id",
"outputName": "id",
"outputType": "STRING"
}
],
"filter": {
"type": "selector",
"dimension": "id",
"value": "1515016369"
},
"aggregations": [{
"type": "doubleSum",
"name": "papadd",
"fieldName": "pap"
}],
"intervals": ["2016-01-01T00:00:00.000Z/2016-01-02T00:00:00.000Z"]
}
三次查詢結果如下:
id | org_no | |
第一次查詢 | 1515016369 | 111 |
第二次查詢 | 1515016369 | 222 |
第三次查詢 | 1515016369 | 333 |
第一次的查詢結果是存儲在segment中的數據,未使用查找,第二次的查詢結果是註冊了查找之後,從查找中獲取出來的值,第三次查詢更新了查找之後,查詢出的值。
刪除查找:
curl -X DELETE http://ip:8081/druid/coordinator/v1/lookups/config/__default/org_no_customer1
下面是查找部分的官方文檔地址,講解的更詳細:
http://druid.io/docs/0.12.3/querying/lookups.html