<b>3.3 觸發增量建構</b>
<b></b>
3.3.1 web gui觸發
在web gui上觸發cube的增量建構與觸發全量建構的方式基本相同。在web gui的model頁面中,選中想要增量建構的cube,單擊action→build,如圖3-3所示。
不同于全量建構,增量建構的cube會在此時彈出對話框讓使用者選擇“end date”(如
圖3-4所示),目前kylin要求增量segment的起始時間等于cube中最後一個segment的結束時間,是以當我們為一個已經有segment的cube觸發增量建構的時候,“start date”的值已經被确定,且不能修改。如果在觸發增量建構的時候cube中不存在任何的segment,那麼“start date”的值會被系統設定為“partition start date”的值(參見3.2.2節)。
圖3-3 觸發增量建構
圖3-4 選擇增量建構end date
僅當cube中不存在任何segment,或者不存在任何未完成的建構任務時,kylin才接受該cube上新的建構任務。未完成的建構任務不僅包含正在運作中的建構任務,還包括已經出錯并處于error狀态的構任務。如果存在一個error狀态的建構任務,那麼使用者需要先處理好該建構任務,然後才能成功地向kylin送出新的建構任務。處理error狀态的建構任務的方式有兩種:比較正常的做法是首先在web gui或背景的日志中查找建構失敗的原因,解決問題後回到monitor頁面,選中失敗的建構任務,單擊action→resume,恢複該建構任務的執行。我們知道建構任務分為多個子步驟,resume操作會跳過之前所有已經成功了的子步驟,直接從第一個失敗的子步驟重新開始執行。舉例來說,如果某次建構任務失敗,我們在背景hadoop的日志中發現失敗的原因是由于mapper和reducer配置設定的記憶體過小導緻了記憶體溢出,那麼我們可以在更新了hadoop相關的配置之後再恢複失敗的建構任務。
3.3.2 建構相關的rest api
kylin提供了rest api以幫助自動化地觸發增量建構。該api同樣也适用于非增量建構的cube。關于kylin api的更詳細的介紹可以參見kylin官網:http://kylin.apache.org/docs15/howto/howto_build_cube_with_restapi.html和http://kylin.apache.org?/docs15/howto/howto_use_restapi.html。
本節将着重介紹增量建構相關的api。事實上我們在web gui上進行的所有操作,其背後調用的都是同一套rest api,是以在使用rest api觸發建構的時候,應當謹記之前進行web gui建構時所遇到的限制和經驗。
1.?擷取segment清單
首先可以通過以下的rest api來擷取某個cube所包含的所有的segment清單資訊。傳回的清單資訊可以幫助用戶端分析cube的狀态,并且決定下一步增量建構的參數:
get http://hostname:port/kylin/api/cubes?cubename={cubename}
path variable
cubename – 必須的,cube名字
舉例而言,假設在本地的7070端口啟動了kylin server,那麼可以通過如下的rest請求擷取名為test_kylin_cube_without_slr_empty的cube的segment清單:
curl -x get -h "authorization: basic qurnsu46s1lmsu4=" -h "content-type: application/json" http://localhost:7070/kylin/api/cubes?cubename=test_kylin_cube_ ? without_slr_empty
格式化之後,該請求的傳回結果如下所示:
[
{
"uuid": "daa53e80-41be-49a5-90ca-9fb7294db186",
"version": "1.5.3",
"name": "test_kylin_cube_without_slr_empty",
"owner": null,
"cost": 50,
"status": "ready",
"segments": [
{
"uuid": "f492158b-0910-4ced-bc51-26e78b9b8b81",
"name": "19700101000000_20220101000000",
"status": "ready",
"dictionaries": {
"default.test_kylin_fact/lstg_site_id": "/dict/edw.test_sites/site_id/a9f93c23-9eca-4e2e-a814-17b81344a816.dict",
"default.test_category_groupings/categ_lvl2_name": "/dict/default.
test_category_groupings/categ_lvl2_name/58372aa5-6d42-4045-a32f-e6ae41c219a8.dict",
"default.test_kylin_fact/lstg_format_name": "/dict/default.test_kylin_fact/lstg_format_name/2e2e8137-5600-4c63-ba3f-3f382f452227.dict",
"default.test_kylin_fact/leaf_categ_id": "/dict/default.test_
category_groupings/leaf_categ_id/ee675200-8c5c-4112-99fa-763bb0aa689a.dict",
"default.test_category_groupings/meta_categ_name": "/dict/default.
test_category_groupings/meta_categ_name/8bc37a42-5577-4c18-b6a5-bd1c7eb55c73.dict",
"default.test_kylin_fact/slr_segment_cd": "/dict/edw.test_seller_
type_dim/seller_type_cd/0c356b8c-74fa-4e58-b8b8-bbbd5095a6be.dict",
"default.test_kylin_fact/cal_dt": "/dict/edw.test_cal_dt/cal_
dt/5e4b4f35-0fc8-4940-b123-b18c9f77da19.dict",
"default.test_kylin_fact/price": "/dict/default.test_kylin_fact/
price/94d429fc-60ef-4635-af1e-2b47679bb494.dict",
"default.test_category_groupings/categ_lvl3_name": "/dict/default.
test_category_groupings/categ_lvl3_name/759e5fd6-9c7e-47ed-9293-e7c8695b6bb4.dict"
},
"snapshots": {
"edw.test_sites": "/table_snapshot/test_sites/1c3d3b91-8afa-
4d12-8743-5376133185eb.snapshot",
"edw.test_cal_dt": "/table_snapshot/test_cal_dt/96a2ad25-4279-
4c7f-9c0a-7e1f0132ae77.snapshot",
"default.test_category_groupings": "/table_snapshot/test_category
_groupings/3ed9f146-2a8b-4bdb-8899-45f2d765c25a.snapshot",
"edw.test_seller_type_dim": "/table_snapshot/test_seller_type_
dim/f7f7b3c8-cfe8-49ea-8230-8c296d0e03ef.snapshot"
"storage_location_identifier": "kylin_kzo9npawgc",
"date_range_start": 0,
"date_range_end": 1640995200000,
"source_offset_start": 0,
"source_offset_end": 0,
"size_kb": 1589,
"input_records": 6000,
"input_records_size": 154637,
"last_build_time": 1467995504950,
"last_build_job_id": "f3f49487-e5bc-4fd0-a571-58c13c9311e9",
"create_time_utc": 1467995076271,
"cuboid_shard_nums": {},
"total_shards": 1,
"blackout_cuboids": [],
"binary_signature": null,
"index_path": "/kylin/kylin_metadata/kylin-f3f49487-e5bc-4fd0-a571-
58c13c9311e9/test_kylin_cube_without_slr_empty/secondary_index/",
"rowkey_stats": [
[
"leaf_categ_id",
134,
1
],
"meta_categ_name",
44,
"categ_lvl2_name",
94,
"categ_lvl3_name",
127,
"lstg_site_id",
262,
2
"slr_segment_cd",
8,
"cal_dt",
3652427,
3
"lstg_format_name",
5,
"price",
5999,
]
]
}
],
"last_modified": 1467995504950,
"descriptor": "test_kylin_cube_without_slr_desc",
"create_time_utc": 0,
"size_kb": 1589,
"input_records_count": 6000,
"input_records_size": 154637
}
]
盡管輸出比較複雜,但是我們仍然能夠迅速地觀察到目前的test_kylin_cube_without_slr_empty包含一個segment,該segment的分割時間為1970-01-01到2022-01-01。我們還能看到該segment的狀态(“status”)均為ready,表示這個segment背後的建構任務均已正常完成,并且這個segment已經可以正常使用。
2.?擷取建構任務詳情
如果segment的狀态顯示為“new”,則說明該segment背後的建構任務尚未完成,需要提取該建構任務的辨別符(job id),即segment中的last_build_job_id字段的值,然後以此為參數向kylin送出如下的rest請求以擷取該建構任務的詳情:
get http://hostname:port/kylin/api/jobs/{job_uuid}
job_uuid – 必需的,建構任務辨別符
該請求的傳回會帶上相應的任務步驟清單,步驟中可能包含mapreduce作業或其他作業。每一個步驟都有相應的狀态資訊“step_status”。
pending:表示該步驟處于等待被執行的狀态。
running:表示該步驟處于執行狀态。
error:表示該步驟的執行已經結束,并且該步驟執行失敗。
discarded:表示該步驟由于這個建構任務被取消而處于取消狀态。
finished:表示該步驟的執行已經結束,并且該步驟執行成功。
test_kylin_cube_without_slr_empty的第一個segment的last_build_job_id為f3f49487-e5bc-4fd0-a571-58c13c9311e9,通過以上的rest接口可以得到如下的結果:
{
"uuid": "f3f49487-e5bc-4fd0-a571-58c13c9311e9",
"version": "1.5.3",
"name": "test_kylin_cube_without_slr_empty - 19700101000000_20220101000000 - build - gmt-08:00 2016-07-08 08:24:36",
"type": "build",
"duration": 393,
"steps": [
{
"id": "f3f49487-e5bc-4fd0-a571-58c13c9311e9-00",
"name": "count source table",
"info": {
"endtime": "1467995164094",
"source_records_size": "571743",
"mr_job_id": "job_1466095360365_0611",
"hdfs_bytes_written": "6",
"yarn_application_tracking_url": "http://sandbox.hortonworks.com:
8088/proxy/application_1466095360365_0611/",
"starttime": "1467995122900"
},
"interruptcmd": null,
"sequence_id": 0,
"exec_cmd": "hive -e \"set dfs.replication=2;\nset hive.exec.compress.
output=true;\nset hive.auto.convert.join.noconditionaltask=true;\nset hive.auto.convert.join.noconditionaltask.size=300000000;\nset hive.merge.size.per.task=32000000;\n\nset hive.exec.compress.output=false;\n\ndfs -mkdir -p /kylin/kylin_metadata/kylin-f3f49487-e5bc-4fd0-a571-58c13c9311e9/row_count;insert overwrite directory '/kylin/kylin_metadata/kylin-f3f49487-e5bc-4fd0-a571-58c13c9311e9/row_count' select count(*) from default.test_kylin_fact test_kylin_fact\nwhere (test_kylin_fact.cal_dt < '2022-01-01')\n\n\"",
"interrupt_cmd": null,
"exec_start_time": 1467995122900,
"exec_end_time": 1467995164094,
"exec_wait_time": 0,
"step_status": "finished",
"cmd_type": "shell_cmd_hadoop",
"run_async": false
},
"id": "f3f49487-e5bc-4fd0-a571-58c13c9311e9-01",
"name": "create intermediate flat hive table",
"endtime": "1467995223284",
"starttime": "1467995164168"
"sequence_id": 1,
"exec_cmd": null,
"exec_start_time": 1467995164168,
"exec_end_time": 1467995223284,
…
"id": "f3f49487-e5bc-4fd0-a571-58c13c9311e9-16",
"name": "garbage collection",
"endtime": "1467995516662",
"starttime": "1467995505050"
"sequence_id": 16,
"exec_start_time": 1467995505050,
"exec_end_time": 1467995516662,
}
],
"submitter": "test",
"progress": 100,
"last_modified": 1467995516721,
"related_cube": "test_kylin_cube_without_slr_empty",
"related_segment": "f492158b-0910-4ced-bc51-26e78b9b8b81",
"exec_start_time": 0,
"exec_end_time": 0,
"mr_waiting": 94,
"job_status": "finished"
}
由于篇幅的限制,此處省略了中間14個子步驟的資訊,但是仍然可以觀察到每個子步驟的資訊都描述了步驟的參數等元資訊,另外每個子步驟還有一個唯一的字元串辨別符“id”。這些資訊可以幫助快速定位問題的所在。
3.?擷取建構步驟的輸出
一般情況下,建構觸發的用戶端會首先擷取cube的segment清單,如果所有segment的狀态都是ready,那麼用戶端就可以開始建構新的segment。反之,如果存在狀态不是ready的segment,那麼用戶端需要擷取建構任務詳情來觀察各個子步驟的狀态:如果某個子步驟的狀态為error,或者長時間pending,或者運作了非常長的時間,那麼用戶端有必要檢查一下該步驟中究竟正在發生什麼。kylin提供了另外一個rest接口允許使用者擷取建構任務中某個特定子步驟的輸出,接口的請求如下:
get http://hostname:port/kylin/api/jobs/{job_uuid}/steps/{step_id}/output
step_id – 必需的,建構任務子步驟辨別符
該接口的輸出為該步驟的日志,根據輸出的結果,使用者可以在觸發建構的用戶端中找到問題并修複問題,并且可調用以下的resume rest接口重新執行該次建構任務。resume接口會跳過之前所有已經成功了的子步驟,直接從第一個失敗的子步驟開始重新執行:
put http://hostname:port/kylin/api/jobs/{job_uuid}/resume
由于自動修複的複雜性,觸發建構的用戶端也可以選擇隻向管理者發送郵件通知該次失敗。kylin伺服器中自帶的web gui用戶端中暫時沒有自動修複的邏輯,在遇到建構失敗的情況時,web gui會根據cube層面的配置向不同的人員發送建構失敗的消息,并且将整個建構任務置于error狀态,并等待管理人員重新登入web gui檢視詳情。關于出錯時通知方式的配置可以參考第10章。
4.?觸發建構
首先介紹一下具體的api規範,代碼如下:
put http://hostname:port/kylin/api/cubes/{cubename}/rebuild
cubename – 必需的,cube名字
request body
starttime – 必需的,長整數類型的起始時間,例如使用1388563200000代表起始時間為2014-01-01
endtime – 必需的,長整數類型的結束時間
buildtype – 必需的,建構類型,可能的值為‘build’‘merge’和‘refresh’,分别對應于建立segment、合并多個segment,以及重新整理某個segment
舉例而言,假設在本地的7070端口啟動了kylin server,那麼可以通過如下的rest請求申請名為test_kylin_cube_without_slr_empty的cube,用于增量地建構[2022-01-01, 2023-01-01)這個時間段的新segment:
curl -x put -h "authorization: basic qurnsu46s1lmsu4=" -h "content-type: application/json" -d '{"starttime": 1640995200000, "endtime": 1672560000000, "buildtype": "build"}' http://localhost:7070/kylin/api/cubes/test_kylin_cube_without_slr_empty/rebuild
如果目前cube不存在任何segment,那麼可以将starttime設定為0,這樣kylin就會自動選擇cube的partition start date(見3.2.2節)作為starttime。如果目前cube不為空,那麼對于build類型的建構任務,請求中的starttime必須等于最後一個segment的endtime,否則請求會傳回500錯誤。