<b>2.3 設計cube</b>
<b></b>
如果資料已經在hive中準備好了,并且已經滿足了2.2節中介紹的條件,那麼就可以開始設計和建立cube了。本節将按通常的步驟介紹cube是如何進行建立的。
2.3.1 導入hive表定義
登入kylin的web界面,建立新的或選擇一個已有的項目之後,需要做的就是将hive表的定義導入到kylin中。
單擊web界面的model→data source下的“load hive table”圖示,然後輸入表的名稱(可以一次導入多張表,以逗号分隔表名,如圖2-1所示),單擊按鈕“sync”,kylin就會使用hive的api從hive中擷取表的屬性資訊。
導入成功後,表的結構資訊會以樹狀的形式顯示在頁面的左側,可以單擊展開或收縮,如圖2-2所示。
圖2-1 輸入hive表名 圖2-2 完成導入的hive表
同時,kylin會在背景觸發一個mapreduce任務,計算此表每個列的基數。通常稍過幾分鐘之後再重新整理頁面,就會看到顯示出來的基數資訊,如圖2-3所示。
圖2-3 計算後各列的基數
需要注意的是,這裡kylin對基數的計算方法采用的是hyperloglog的近似算法,與精确值略有誤差,但作為參考值已經足夠了。
2.3.2 建立資料模型
有了表資訊之後,就可以開始建立資料模型(data model)了。資料模型是cube的基礎,它主要用于描述一個星形模型。有了資料模型以後,定義cube的時候就可以直接從此模型定義的表和列中進行選擇了,省去重複指定連接配接(join)條件的步驟。基于一個資料模型還可以建立多個cube,以友善減少使用者的重複性工作。
在kylin界面的“models”頁面中,單擊“new”→“new model”,開始建立資料模型。給模型輸入名稱之後,選擇一個事實表(必需的),然後添加次元表(可選),如圖2-4所示。
圖2-4 選擇事實表
添加次元表的時候,需要選擇連接配接的類型:是inner還是left,然後選擇連接配接的主鍵和外鍵,這裡也支援多主鍵,如圖2-5所示。
圖2-5 選擇次元表
接下來選擇會用作次元和度量的列。這裡隻是選擇一個範圍,不代表這些列将來一定要用作cube的次元或度量,你可以把所有可能會用到的列都選進來,後續建立cube的時候,将隻能從這些列中進行選擇。
選擇次元列時,次元可以來自事實表或次元表,如圖2-6所示。
選擇度量列時,度量隻能來自事實表,如圖2-7所示。
最後一步,是為模型補充分割時間列資訊和過濾條件。如果此模型中的事實表記錄是按時間增長的,那麼可以指定一個日期/時間列作為模型的分割時間列,進而可以讓cube按此列做增量建構,關于增量建構的具體内容請參見第3章。
圖2-6 選擇次元列
圖2-7 選擇度量列
過濾(filter)條件是指,如果想把一些記錄忽略掉,那麼這裡可以設定一個過濾條件。kylin在向hive請求源資料的時候,會帶上此過濾條件。在圖2-8所示的示例中,會直接排除掉金額小于等于0的記錄。
圖2-8 選擇分區列和設定過濾器
最後,單擊“save”儲存此資料模型,随後它将出現在“models”的清單中。
2.3.3 建立cube
本節将快速介紹建立cube時的各種配置選項,但是由于篇幅的限制,這裡将不會對cube的配置和cube的優化進行深入的展開介紹。讀者可以在後續的章節(如第6章“cube優化”)中找到關于cube的更詳細的介紹。接下來開始cube的建立;單擊“new”,選擇“new cube”,會開啟一個包含若幹步驟的向導。
第一頁,選擇要使用的資料模型,并為此cube輸入一個唯一的名稱(必需的)和描述(可選的)(如圖2-9所示);這裡還可以輸入一個郵件通知清單,用于在建構完成或出錯時收到通知。如果不想接收處于某些狀态的通知,那麼可以從“notif?ication events”中将其去掉。
圖2-9 cube基本資訊
第二頁,選擇cube的次元。可以通過以下兩個按鈕來添加次元。
“add dimension”:逐個添加次元,可以是普通次元也可以是衍生(derived)次元。
“auto generator”:批量選擇并添加,讓kylin自動完成其他資訊。
使用第一種方法的時候,需要為每個次元起個名字,然後選擇表和列(如圖2-10所示)。
如果是衍生次元的話,則必須是來自于某個次元表,一次可以選擇多個列(如圖2-11所示);由于這些列值都可以從該次元表的主鍵值中衍生出來,是以實際上隻有主鍵列會被cube加入計算。而在kylin的具體實作中,往往采用事實表上的外鍵替代主鍵進行計算和存儲。但是在邏輯上可以認為衍生列來自于次元表的主鍵。
使用第二種方法的時候,kylin會用一個樹狀結構呈現出所有的列,使用者隻需要勾選所需要的列即可,kylin會自動補齊其他資訊,進而友善使用者的操作(如圖2-12所示)。請注意,在這裡kylin會把次元表上的列都建立成衍生次元,這也許不是最合适的,在這種情況下,請使用第一種方法。
圖2-11 添加衍生次元
第三頁,建立度量。kylin預設會建立一個count(1)的度量。可以單擊“+measure”按鈕來添加新的度量。kylin支援的度量有:sum、min、max、count、count distinct、top_n、raw等。請選擇需要的度量類型,然後再選擇适當的參數(通常為列名)。圖2-13是一個sum(price)的示例。
圖2-12 批量添加次元 圖2-13 添加度量
重複上面的步驟,建立所需要的度量。kylin可以支援在一個cube中添加多達上百個的度量;添加完所有度量之後,單擊“next”,如圖2-14所示。
圖2-14 度量清單
第四頁,是關于cube資料重新整理的設定。在這裡可以設定自動合并的門檻值、資料保留的最短時間,以及第一個segment的起點時間(如果cube有分割時間列的話),詳細内容請參考第3章。
第五頁,進階設定。在此頁面上可以設定聚合組和rowkey(如圖2-16所示)。
圖2-15 重新整理設定
kylin預設會把所有次元都放在同一個聚合組中;如果次元數較多(例如>10),那麼建議使用者根據查詢的習慣和模式,單擊“new aggregation group+”,将次元分為多個聚合組。通過使用多個聚合組,可以大大降低cube中的cuboid數量。下面來舉例說明,如果一個cube有(m+n)個次元,那麼預設它會有2m+n個cuboid;如果把這些次元分為兩個不相交的聚合組,那麼cuboid的數量将被減少為2m+2n。
在單個聚合組中,可以對次元設定進階屬性,如mandatory、hierarchy、joint等。這幾種屬性都是為優化cube的計算而設計的,了解這些屬性的含義對日後更好地使用cube至關重要。
mandatory次元指的是那些總是會出現在where條件或group by語句裡的次元;通過将某個次元指定為mandatory,kylin就可以不用預計算那些不包含此次元的cuboid,進而減少計算量。
hierarchy是一組有層級關系的次元,例如“國家”“省”“市”,這裡的“國家”是進階别的次元,“省”“市”依次是低級别的次元。使用者會按進階别次元進行查詢,也會按低級别次元進行查詢,但在查詢低級别次元時,往往都會帶上進階别次元的條件,而不會孤立地審視低級别次元的資料。例如,使用者會單擊“國家”作為次元來查詢彙總資料,也可能單擊“國家”+“省”,或者“國家”+“省”+“市”來查詢,但是不會跨越國家直接group by “省”或“市”。通過指定hierarchy,kylin可以省略不滿足此模式的cuboid。
joint是将多個次元組合成一個次元,其通常适用于如下兩種情形。
總是會在一起查詢的次元。
基數很低的次元。
kylin以key-value的方式将cube存儲到hbase中。hbase的key,也就是rowkey,是由各次元的值拼接而成的;為了更高效地存儲這些值,kylin會對它們進行編碼和壓縮;每個次元均可以選擇合适的編碼(encoding)方式,預設采用的是字典(dictionary)編碼技術;除了字典以外,還有整數(int)和固定長度(fixed length)的編碼。
字典編碼是将此次元下的所有值建構成一個從string到int的映射表;kylin會将字典序列化儲存,在cube中存儲int值,進而大大減小存儲的大小。另外,字典是保持順序的,即如果字元串a比字元串b大的話,那麼a編碼後的int值也會比b編碼後的值大;這樣可以使得在hbase中進行比較查詢的時候,依然使用編碼後的值,而無需解碼。
圖2-16 進階設定
字典非常适合于非固定長度的string類型值的次元,而且使用者無需指定編碼後的長度;但是由于使用字典需要維護一張映射表,是以如果此次元的基數很高,那麼字典的大小就非常可觀,進而不适合于加載到記憶體中,在這種情況下就要選擇其他的編碼方式了。kylin中字典編碼允許的基數上限預設是500萬(由參數“kylin.dictionary.max.cardinality”配置)。
整數(int)編碼适合于對int或bigint類型的值進行編碼,它無需額外存儲,同時還可以支援很大的基數。使用者需要根據值域選擇編碼的長度。例如有一個“手機号碼”的次元,它是一個11位的數字,如13800138000,我們知道它大于231,但是小于239-1,那麼使用int(5)即可滿足要求,每個值占用5位元組,比按字元存儲(11位元組)要少占用一半以上的空間。
當上面幾種編碼方式都不适合的時候,就需要使用固定長度的編碼了;此編碼方式其實隻是将原始值截斷或補齊成相同長度的一組位元組,沒有額外的轉換,是以空間效率較差,通常隻是作為一種權宜手段。
各次元在rowkeys中的順序,對于查詢的性能會産生較明顯的影響。在這裡使用者可以根據查詢的模式和習慣,通過拖曳的方式調整各個次元在rowkeys上的順序(如圖2-17所示)。通常的原則是,将過濾頻率較高的列放置在過濾頻率較低的列之前,将基數高的列放置在基數低的列之前。這樣做的好處是,充分利用過濾條件來縮小在hbase中掃描的範圍,進而提高查詢的效率。
第五頁,為cube配置參數。和其他hadoop工具一樣,kylin使用了很多配置參數以提高靈活性,使用者可以根據具體的環境、場景等配置不同的參數進行調優。kylin全局的參數值可在conf/kylin.properties檔案中進行配置;如果cube需要覆寫全局設定的話,則需要在此頁面中指定。單擊“+property”按鈕,然後輸入參數名和參數值,如圖2-18所示,指定“kylin.hbase.region.cut=1”,這樣此cube在存儲的時候,kylin将會為每個htable region配置設定1gb來建立一個htable region。
圖2-17 rowkey設定
圖2-18 覆寫預設參數
然後單擊next跳轉到最後一個确認頁面,如有修改,則單擊“prev”按鈕傳回以修改,最後再單擊“save”按鈕進行儲存,一個cube就建立完成了。建立好的cube會顯示在“cubes”清單中,如要對cube的定義進行修改,隻需單擊“edit”按鈕就可以進行修改。也可以展開此cube行以檢視更多的資訊,如json格式的中繼資料、通路權限、通知清單等。