##[有贊]Kylin, Mondrian, Saiku系統(tǒng)的整合 - chenhao - 有贊技術(shù)團(tuán)隊(duì)

Kylin, Mondrian, Saiku系統(tǒng)的整合 - chenhao - 有贊技術(shù)團(tuán)隊(duì) http://tech.youzan.com/kylin-mondrian-saiku/

參考了--明略數(shù)據(jù)的解決方案

Kylin + Mondrian + Saiku是一個(gè)簡(jiǎn)單的三層架構(gòu)荣倾。git上開(kāi)源的Saiku的項(xiàng)目已經(jīng)整合了mondrian的jar包许蓖。所以構(gòu)建這樣一個(gè)三層架構(gòu)主要的工作是將Mondrian的schema和Kylin的schema對(duì)應(yīng)起來(lái),同時(shí)需要針對(duì)Kylin的語(yǔ)法對(duì)Mondrian做一些Kylin dialect的定制開(kāi)發(fā)谭梗。
Git上已經(jīng)有一個(gè)整合Kylin,Mondrian以及Saiku的項(xiàng)目卡骂。照著這個(gè)項(xiàng)目的指引崔慧,可以很輕松的搭建這么一個(gè)三層的系統(tǒng)狠半。在此宰翅,致謝開(kāi)源項(xiàng)目作者mustangore弃甥。

架構(gòu)圖.png

本文主要介紹有贊數(shù)據(jù)團(tuán)隊(duì)為了滿足在不同維度查看、分析重點(diǎn)指標(biāo)的需求而搭建的OLAP分析工具汁讼。這個(gè)工具對(duì)Kylin淆攻、Mondrian以及Saiku做了一個(gè)整合,主要工作包括一些定制化的修改以及環(huán)境的配置嘿架。 目前這個(gè)系統(tǒng)還處于一個(gè)需要優(yōu)化瓶珊、完善的過(guò)程,這篇博文也會(huì)相應(yīng)地更新耸彪。

背景
在有贊發(fā)展的初期艰毒,數(shù)據(jù)團(tuán)隊(duì)主要的工作之一就是根據(jù)運(yùn)營(yíng)人員的報(bào)表需求,編寫(xiě)sql搜囱,從hive中獲得數(shù)據(jù)并寫(xiě)入mysql中存儲(chǔ)。最后柑土,前端人員寫(xiě)相應(yīng)的代碼展現(xiàn)mysql中存儲(chǔ)的報(bào)表數(shù)據(jù)蜀肘。 隨著公司業(yè)務(wù)的快速發(fā)展,如此長(zhǎng)周期的報(bào)表開(kāi)發(fā)流程已經(jīng)很難跟上運(yùn)營(yíng)人員的分析需求了稽屏。為了避免深陷報(bào)表開(kāi)發(fā)扮宠、維護(hù)的泥潭,數(shù)據(jù)組決定調(diào)研大數(shù)據(jù)場(chǎng)景下的OLAP分析工具狐榔。參考了明略數(shù)據(jù)的解決方案之后坛增,我們選擇整合Kylin,Mondrian薄腻,Saiku來(lái)實(shí)現(xiàn)這樣一個(gè)OLAP系統(tǒng)收捣。

三巨頭
Kylin
kylin是apache軟件基金會(huì)的頂級(jí)項(xiàng)目,一個(gè)開(kāi)源的分布式多維分析工具庵楷。下面是摘自Kylin官網(wǎng)的介紹:

Apache Kylin? is an open source Distributed Analytics Engine designed to provide SQL interface and multi-dimensional analysis (OLAP) on Hadoop supporting extremely large datasets, original contributed from eBay Inc.

個(gè)人的理解是:Kylin通過(guò)預(yù)計(jì)算所有合理的維度組合下各個(gè)指標(biāo)的值并把計(jì)算結(jié)果存儲(chǔ)到HBASE中的方式罢艾,大大提高分布式多維分析的查詢效率楣颠。Kylin接收sql查詢語(yǔ)句作為輸入,以查詢結(jié)果作為輸出咐蚯。通過(guò)預(yù)計(jì)算的方式童漩,將在hive中可能需要幾分鐘的查詢響應(yīng)時(shí)間下降到毫秒級(jí)。更細(xì)致的關(guān)于Kylin的介紹春锋,可以參考我的另一片博客Kylin初體驗(yàn)矫膨。

Mondrian
Mondrian is an Open Source Business Analytics engine that enables organizations of any size to give business users access to their data for interactive analysis. You can build powerful Business Intelligence solutions with Mondrian as your Online Analytical Processing (OLAP) engine, enabling multidimensional queries against your business data, using the powerful MDX query language.

Mondrian是一個(gè)OLAP分析的引擎,主要工作是根據(jù)事先配置好的schema期奔,將輸入的多維分析語(yǔ)句MDX(Multidimensional Expressions )翻譯成目標(biāo)數(shù)據(jù)庫(kù)/數(shù)據(jù)引擎的執(zhí)行語(yǔ)言(比如SQL)侧馅。

Saiku
Saiku allows business users to explore complex data sources, using a familiar drag and drop interface and easy to understand business terminology, all within a browser. Select the data you are interested in, look at it from different perspectives, drill into the detail. Once you have your answer, save your results, share them, export them to Excel or PDF, all straight from the browser.

Saiku提供了一個(gè)多維分析的用戶操作界面,可以通過(guò)簡(jiǎn)單拖拉拽的方式迅速生成報(bào)表能庆。Saiku的主要工作是根據(jù)事先配置好的schema施禾,將用戶的操作轉(zhuǎn)化成MDX語(yǔ)句提供給Mondrian引擎執(zhí)行。

技術(shù)架構(gòu)
架構(gòu)圖

Paste_Image.png

Kylin + Mondrian + Saiku是一個(gè)簡(jiǎn)單的三層架構(gòu)搁胆。git上開(kāi)源的Saiku的項(xiàng)目已經(jīng)整合了mondrian的jar包弥搞。所以構(gòu)建這樣一個(gè)三層架構(gòu)主要的工作是將Mondrian的schema和Kylin的schema對(duì)應(yīng)起來(lái),同時(shí)需要針對(duì)Kylin的語(yǔ)法對(duì)Mondrian做一些Kylin dialect的定制開(kāi)發(fā)渠旁。
Git上已經(jīng)有一個(gè)整合Kylin攀例,Mondrian以及Saiku的項(xiàng)目。照著這個(gè)項(xiàng)目的指引顾腊,可以很輕松的搭建這么一個(gè)三層的系統(tǒng)粤铭。在此,致謝開(kāi)源項(xiàng)目作者mustangore杂靶。

一些細(xì)節(jié)
介紹完整體的結(jié)構(gòu)梆惯,下面講一些構(gòu)建過(guò)程中遇到的坑。有些可能是我們的理解還不夠深入吗垮,有些可能隨著開(kāi)源軟件版本的升級(jí)已經(jīng)不再是一個(gè)坑了垛吗。希望能給大家?guī)?lái)一些幫助,如果是由于我們理解的偏差導(dǎo)致踩到的坑烁登,也希望大家留言給出指正:) 本套系統(tǒng)構(gòu)建基于kylin1.5怯屉, Mondrian4.4以及Saiku3.7.4。底層是Hive0.14以及Hbase0.98饵沧。

關(guān)于schema
前面提到锨络,要讓系統(tǒng)運(yùn)轉(zhuǎn),Kylin的schema必須和mondrian的schema能夠?qū)由侠俏ylin是根據(jù)自身cube配置的schema來(lái)進(jìn)行預(yù)計(jì)算的羡儿,schema決定Kylin能夠接收的sql查詢的范圍。Mondrian又根據(jù)自身的shema翻譯MDX到sql锁右, Mondrian的schema決定它生成的sql的范圍失受。如果兩者有不一致的情況讶泰,就可能導(dǎo)致Mondrian生成的sql無(wú)法被Kylin執(zhí)行。 kylin的schema配置比較簡(jiǎn)單拂到,管理頁(yè)面上有一套圖形界面指引你一步步地構(gòu)建一個(gè)星型模型痪署,配置di mension、measure兄旬。不過(guò)要把cube設(shè)計(jì)得高效狼犯,Kylin還是有不少高級(jí)地設(shè)置的,比如選擇 attribute group领铐, derived dimension等悯森。官網(wǎng)上有詳細(xì)的介紹。
Mondrian的schema沒(méi)有比較好的圖形配置工具绪撵,需要手寫(xiě)Mondrian schema的XML文檔瓢姻,文檔格式參考官方文檔,通過(guò)Saiku上傳音诈。
需要注意的坑:

不要用view作為lookup table 在設(shè)計(jì)Kylin cube時(shí)幻碱,用hive view作為fact table是一個(gè)比較好的實(shí)踐方式,可以屏蔽一些底層數(shù)據(jù)結(jié)構(gòu)變化對(duì)Kylin cube的影響细溅。但是不要用view作look up table褥傍,在build cube計(jì)算維度表容量時(shí)會(huì)出問(wèn)題。
Kylin無(wú)法在預(yù)計(jì)算指標(biāo)時(shí)制定條件 比如有兩個(gè)字段:orderpay, ispayed喇聊。我們可以配置sum(orderpay)作為訂單金額, sum(ispayed)作為付款訂單數(shù)恍风。但是沒(méi)法配置sum(orderpay) where ispayed = 1來(lái)表示付款訂單金額。我們需要在fact view中添加字段payedorderpay表示付款的訂單金額誓篱。
盡量在Kylin中用int類型 比如is_payed字段朋贬,就0/1兩個(gè)值,通常我們?cè)趆ive里可以設(shè)置為tiny int類型的字段窜骄。但是在Kylin中兄世,針對(duì)tiny int 和 int類型的字段配置出來(lái)的measure類型是不一樣的,tiny int 類型的字段得到的measure在和Saiku結(jié)合時(shí)可能會(huì)出現(xiàn)問(wèn)題啊研。
把hive表放在default庫(kù)中 Kylin添加hive table的時(shí)候是可以指定hive table所在庫(kù)的,但是建議將fact table鸥拧、lookup table都放在default庫(kù)中党远。因?yàn)樵贛ondrian的schema中,physical table是默認(rèn)去default庫(kù)查找的富弦,目前還沒(méi)有發(fā)現(xiàn)很好的在Mondrian schema中指定數(shù)據(jù)庫(kù)的方式沟娱。
關(guān)于count distinct
Kylin配置cube的時(shí)候可以指定某個(gè)measure的聚合方式為count distinct,有精準(zhǔn)計(jì)算的方式也有基于hyperloglog算法的近似計(jì)算方式腕柜。同樣济似,在Mondrian的schema里也可以配置count distinct的指標(biāo)聚合方式矫废。
看上去一切都OK,然而問(wèn)題來(lái)了: Kylin的count distinct語(yǔ)法只針用count distinct聚合的指標(biāo)字段砰蠢,在計(jì)算維度表大小的時(shí)候蓖扑,kylin無(wú)法計(jì)算類似 select count(distinct date) from lu_date這樣的sql語(yǔ)句。在mustangore的項(xiàng)目中台舱,對(duì)Mondrian打了Kylin-dialect的補(bǔ)丁律杠。其中添加了一個(gè)JdbcDialect的實(shí)現(xiàn):

public class KylinDialect extends JdbcDialectImpl {

public static final JdbcDialectFactory FACTORY =
        new JdbcDialectFactory(KylinDialect.class, DatabaseProduct.KYLIN) {
            protected boolean acceptsConnection(Connection connection) {
                return super.acceptsConnection(connection);
            }
        };

/**
 * Creates a KylinDialect.
 *
 * @param connection Connection
 * @throws SQLException on error
 */
public KylinDialect(Connection connection) throws SQLException {
    super(connection);
}

@Override
public boolean allowsCountDistinct() {
    return false;
}

@Override
public boolean allowsJoinOn() {
    return true;
}

}
注意到:allowsCountDistinct()函數(shù)被設(shè)置成了return false; mustangore 通過(guò)這種方式避免了Mondrian計(jì)算維度大小的時(shí)候count disctinct竞惋,然而這種一桿子打死的方式也使得Mondrian計(jì)算count distinct的指標(biāo)的時(shí)候出現(xiàn)問(wèn)題:select count(distinct XXX) from tableA這樣的語(yǔ)句會(huì)被翻譯成select count YYY from (select distinct XXX as YYY from tableA)柜去,而Kylin又不能很好的執(zhí)行后者。為了解決這個(gè)兩難的問(wèn)題拆宛,我們深入到Mondrian的源碼中去嗓奢,找到了計(jì)算維度表大小的代碼:

private static String generateColumnCardinalitySql(
Dialect dialect,
String schema,
String table,
String column)
{
final StringBuilder buf = new StringBuilder();
String exprString = dialect.quoteIdentifier(column);
if (dialect.allowsCountDistinct()) {
// e.g. "select count(distinct product_id) from product"
buf.append("select count(distinct ")
.append(exprString)
.append(") from ");
dialect.quoteIdentifier(buf, schema, table);
return buf.toString();
}
else if (dialect.allowsFromQuery()) {
// Some databases (e.g. Access) don't like 'count(distinct)',
// so use, e.g., "select count() from (select distinct
// product_id from product)"
buf.append("select count(
) from (select distinct ")
.append(exprString)
.append(" from ");
dialect.quoteIdentifier(buf, schema, table);
buf.append(")");
...
注意到只有dialect.allowsCountDistinct()為true時(shí)才會(huì)用count distinct來(lái)計(jì)算維度表大小。 我們只要將Kylin dialect的allowsCountDistinct()設(shè)置為true浑厚,同時(shí)在generateColumnCardinalitySql添加一個(gè)判斷條件:

if (dialect.allowsCountDistinct()
&& !dialect.getDatabaseProduct().name().equalsIgnoreCase("KYLIN")) {
...
就可以實(shí)現(xiàn)和kylin的count distcint measure的正常對(duì)接了股耽。

關(guān)于Kylin sql
有了處理count distinct的問(wèn)題的經(jīng)驗(yàn),我們發(fā)現(xiàn)瞻颂,只要了解Kylin sql的特點(diǎn)豺谈,針對(duì)Kylin sql定制Mondrian 的Kylin—diect就能將Mondrian和kylin較好的對(duì)接。經(jīng)過(guò)在Kylin1.5的交互界面中的測(cè)試贡这,我們列出如下的區(qū)別:

不能limit beg, end 只能limit length
不支持 union, union all
不支持 where exists 子句
結(jié)束語(yǔ)
以上是有贊數(shù)據(jù)團(tuán)隊(duì)實(shí)現(xiàn)多維分析工具的探索過(guò)程茬末。總的來(lái)說(shuō)盖矫,Kylin + Saiku + Mondrian的一套流程是能走通的丽惭,中途遇到一些零碎的問(wèn)題沒(méi)有完全列出來(lái)。通常是因?yàn)镵ylin只支持cube范圍內(nèi)的查詢辈双,如果Mondrian翻譯出的sql超出這個(gè)范圍就會(huì)引起系統(tǒng)的錯(cuò)誤责掏。通常有三種解決方案: - 重新構(gòu)建Kylin cube,讓它能覆蓋更廣范圍的查詢 - 修改Mondrian schema湃望,讓它的cube描述和Kylin cube吻合 - 定制化開(kāi)發(fā)Mondrian的Kylin dialect换衬,讓Mondrian生成符合Kylin特點(diǎn)的sql

目前我們還在對(duì)這套三層框架做一些定制化的功能開(kāi)發(fā)以及性能的調(diào)優(yōu)工作。希望這篇文章能給大家?guī)?lái)些幫助证芭,也希望有獨(dú)特見(jiàn)解或者發(fā)現(xiàn)我們的理解不對(duì)的朋友們留言交流瞳浦。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市废士,隨后出現(xiàn)的幾起案子叫潦,更是在濱河造成了極大的恐慌,老刑警劉巖官硝,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矗蕊,死亡現(xiàn)場(chǎng)離奇詭異短蜕,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)傻咖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)朋魔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人没龙,你說(shuō)我怎么就攤上這事铺厨。” “怎么了硬纤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵解滓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我筝家,道長(zhǎng)洼裤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任溪王,我火速辦了婚禮腮鞍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘莹菱。我一直安慰自己移国,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布道伟。 她就那樣靜靜地躺著迹缀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蜜徽。 梳的紋絲不亂的頭發(fā)上祝懂,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音拘鞋,去河邊找鬼砚蓬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛盆色,可吹牛的內(nèi)容都是我干的灰蛙。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼隔躲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缕允!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蹭越,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎教届,沒(méi)想到半個(gè)月后响鹃,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體驾霜,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年买置,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了粪糙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡忿项,死狀恐怖蓉冈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情轩触,我是刑警寧澤寞酿,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站脱柱,受9級(jí)特大地震影響伐弹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜榨为,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一惨好、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧随闺,春花似錦日川、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至绰精,卻和暖如春撒璧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笨使。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工卿樱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人硫椰。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓繁调,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親靶草。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蹄胰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容