Hive元數(shù)據(jù)升級工具源碼剖析——HiveSchemaTool

1 背景

隨著公司業(yè)務(wù)的井噴式發(fā)展,數(shù)倉元數(shù)據(jù)也日益龐大恕刘,尤其是存在很多設(shè)計不合理的大分區(qū)表市殷,導(dǎo)致一些元數(shù)據(jù)表(如PARTITIONS,PARTITION_PARAMS等表)高達(dá)數(shù)億記錄勘畔,這不得不讓我們考慮做HMS的federation方案,另外丽惶,Mysql的穩(wěn)定性也提出了更高的要求炫七。本文正是在Mysql交由更專業(yè)的DBA團隊運維的背景下產(chǎn)生的。

在Hive版本升級中, 需要考慮的是版本間的語法兼容性, 這應(yīng)該是升級中最大的困難钾唬。
而元數(shù)據(jù)Hive MetaStore(HMS)的升級相對而言就簡單很多万哪,本文主要關(guān)注HMS的升級侠驯。

本文適用于想進行Hive元數(shù)據(jù)升級,尤其是想對Hive元數(shù)據(jù)Mysql做遷移改造的同學(xué)借鑒奕巍,也適于對Hive源碼感興趣的同學(xué)參考吟策。

2 HiveSchemaTool源碼分析

如果你親手搭建過Hive,想必肯定對命令schematool -dbType mysql -initSchema有印象的止,因為在搭建完Hive之后檩坚,執(zhí)行該命令后,你會驚奇地發(fā)現(xiàn)Mysql中會創(chuàng)建好相應(yīng)的元數(shù)據(jù)表信息冲杀。schematool主要完成元數(shù)據(jù)庫中表結(jié)構(gòu)(如DBS效床,TBLS等)的更新創(chuàng)建睹酌。那它的背后是如何完成的呢权谁?

2.1 schematool 的用法

你應(yīng)該善于使用help:

schematool -help
usage: schemaTool
 -dbOpts <databaseOpts>             Backend DB specific options
 -dbType <databaseType>             Metastore database type
 -dryRun                            list SQL scripts (no execute)
 -help                              print this message
 -info                              Show config and schema details
 -initSchema                        Schema initialization
 -initSchemaTo <initTo>             Schema initialization to a version
 -passWord <password>               Override config file password
 -upgradeSchema                     Schema upgrade
 -upgradeSchemaFrom <upgradeFrom>   Schema upgrade from a version
 -userName <user>                   Override config file user name
 -verbose                           only print SQL statements

dryRun是升級演習(xí)模式。可以打印出將要執(zhí)行的SQL腳本信息憋沿。從而提醒我們該去哪個文件查看此次變更內(nèi)容旺芽,讓我們更清楚將要發(fā)生什么;
verbose參數(shù)可以打印出每個執(zhí)行的SQL內(nèi)容辐啄。 方便在失敗時采章,我們知道是哪個環(huán)節(jié)出現(xiàn)了問題。

其他選項比較簡單壶辜,不再一一介紹悯舟。

2.2 schematool 的功能

schematool主要有如下功能:

  • 元數(shù)據(jù)版本升級
  • 元數(shù)據(jù)初始化
  • 元數(shù)據(jù)信息查看

2.3 核心代碼分析

2.3.1 main入口函數(shù)

  • 第一步參數(shù)解析

  • 第二步參數(shù)校驗

  • 第三步強制開啟版本校驗

  • 第四步參數(shù)賦值

  • 第五步開始版本升級/初始化

源碼流程比較清晰,不再多敘砸民,可參考源碼自行閱讀抵怎。

2.3.2 upgrade

關(guān)于版本升級主要有兩種方式: 不指定版本號和指定版本號

  • 1 不指定版本號升級
    upgradeSchema: schematool -upgradeSchema
    默認(rèn)不指定版本號升級, 這時是從mysql中讀取版本號.

  • 2 指定版本號升級
    upgradeSchemaFrom: schematool -upgradeSchemaFrom <upgradeFrom>
    指定版本號升級,我們可以指定升級的版本號.這里可以是我們內(nèi)部版本號
    (如果是內(nèi)部版本,可以使用指定內(nèi)部版本號實現(xiàn)升級)

不管是否指定版本號升級, 最終都會調(diào)用方法:
org.apache.hive.beeline.HiveSchemaTool#doUpgrade(java.lang.String)

doUpgrade分析

1 等價版本號

合法的可識別的版本號保存在兩個地方:

一是在硬代碼靜態(tài)變量中定義好的:
org.apache.hadoop.hive.metastore.MetaStoreSchemaInfo#EQUIVALENT_VERSIONS
這里定義的意思是說有些版本號之間的schema的變化是一致的,升級是等價的.

  // 這里注明了一些等價的版本岭参,也就是元數(shù)據(jù)沒有變化的版本反惕,如 1.2.1 和 1.2.0 版本的元數(shù)據(jù)是一致的。
  private static final Map<String, String> EQUIVALENT_VERSIONS =
      ImmutableMap.of("0.13.1", "0.13.0",
          "1.0.0", "0.14.0",
          "1.0.1", "1.0.0",
          "1.1.1", "1.1.0",
          "1.2.1", "1.2.0"
      );

二是從數(shù)據(jù)庫中獲取版本號(這里是從VERSION表中讀取版本號).

2 升級腳本注冊文件

命名規(guī)則:upgrade.order.<dbType>

以mysql庫為例:
upgrade.order.mysql:該文件中定義了mysql升級將要執(zhí)行的腳本名標(biāo)識演侯。

# upgrade.order.mysql 文件內(nèi)容:
0.5.0-to-0.6.0
0.6.0-to-0.7.0
0.7.0-to-0.8.0
0.8.0-to-0.9.0
0.9.0-to-0.10.0
0.10.0-to-0.11.0
0.11.0-to-0.12.0
0.12.0-to-0.13.0
0.13.0-to-0.14.0
0.14.0-to-1.1.0
1.1.0-to-1.2.0

upgrade.order.mysql文件中定義了升級腳本名標(biāo)識姿染,該標(biāo)識以升級的當(dāng)前版本號為前綴。這里也規(guī)定了升級的版本之間的依賴關(guān)系秒际。如0.6.0版本悬赏,無法跨版本升級至1.2.0,只能通過逐級升級至1.2.0娄徊。

如何跨版本升級赢笨?
沒錯,聰明的你肯定想到了:我們可以通過修改該文件來實現(xiàn)跨元數(shù)據(jù)的版本升級仇冯。

如何自定義內(nèi)部版本升級筛谚?
這里如果我們自定義內(nèi)部版本升級, 我們可以在該文件中增加想要升級的版本標(biāo)識,如:
1.2.1-to-1.2.1-stefan_r中鼠,假定是mysql庫可婶,我們需要在scripts/upgrade/mysql目錄下,定義內(nèi)部版本升級腳本文件:
upgrage-1.2.1-to-1.2.1-stefan_r.mysql.sql

為什么是這個文件名呢援雇?下面我們看升級腳本文件命名規(guī)則矛渴。

3 升級腳本文件命名規(guī)則

upgrage-<upgrade.order.mysql中定義的文件標(biāo)識>.<dbType>.sql

image.png
4 升級腳本文件的獲取

獲取升級腳本文件的方法是:
org.apache.hadoop.hive.metastore.MetaStoreSchemaInfo#getUpgradeScripts

比如我們當(dāng)前版本是1.1.0, 那執(zhí)行如下命令
schematool -dbType mysql -initSchemaTo 1.1.0
, 那么會根據(jù)指定的版本號1.1.0 在upgrade.order.mysql 中找該版本號前綴的標(biāo)識惫搏,將會升級到1.2.0版本(1.1.0-to-1.2.0)

當(dāng)然具温,如果我們執(zhí)行如下命令
schematool -dbType mysql -initSchema
該升級哪個版本呢?
此時的版本號是取<hive.version.shortname>1.2.0</hive.version.shortname>, 這里不多展開筐赔。

5 升級腳本的執(zhí)行

這里是利用beeline通過JDBC連接對應(yīng)的數(shù)據(jù)庫铣猩,完成升級腳本的執(zhí)行。

這里有幾個模式:
演習(xí)模式: 可以通過指定 -dryRun 開啟茴丰。該模式不會真正地升級达皿,會打印升級的文件。
verbose模式: 可以通過 -verbose 開啟贿肩。該模式會將升級中執(zhí)行的SQL打印出來峦椰。

通常不同issue對應(yīng)的升級腳本都是有序獨立提供,

image.png

主升級腳本中通常source他們汰规,來看看 upgrade-0.14.0-to-1.1.0.mysql.sql 升級腳本的內(nèi)容:

SELECT 'Upgrading MetaStore schema from 0.14.0 to 1.1.0' AS ' ';

SOURCE 020-HIVE-9296.mysql.sql;

UPDATE VERSION SET SCHEMA_VERSION='1.1.0', VERSION_COMMENT='Hive release version 1.1.0' where VER_ID=1;
SELECT 'Finished upgrading MetaStore schema from 0.14.0 to 1.1.0' AS ' ';


以上是升級upgrade中的一些細(xì)節(jié)汤功,理解了升級,下面的初始化init理解起來就容易地多了溜哮。

2.3.2 init

初始化同樣有兩種方式: 不指定版本號和指定版本號

  • 1 不指定版本號升級
    initSchema: schematool -dbType -initSchema
    默認(rèn)不指定版本號升級, 這時是從mysql中讀取版本號.

  • 2 指定版本號升級
    initSchemaTo: schematool -dbType -initSchemaTo <initVersion>

不管是否指定版本號升級, 最終都會調(diào)用方法:
org.apache.hive.beeline.HiveSchemaTool#doInit(java.lang.String)

doInit分析

1 初始化腳本文件命名規(guī)則

hive-schema-<toVersion>.<dbType>.sql

image.png

2 升級腳本文件的獲取

這個比較簡單滔金,根據(jù)初始化的目標(biāo)版本號,獲取茬射。

其他都與upgrade類似鹦蠕。

3 元數(shù)據(jù)升級的一些注意事項

如果是不停服的升級,這里有兩點需要注意:

一是要關(guān)閉版本嚴(yán)格校驗?zāi)J健?/strong>
如果在不停服的升級過程中可以做到對用戶透明在抛,避免客戶端請求失敗钟病。

    METASTORE_SCHEMA_VERIFICATION("hive.metastore.schema.verification", false,
        "Enforce metastore schema version consistency.\n" +
        "True: Verify that version information stored in metastore matches with one from Hive jars.  Also disable automatic\n" +
        "      schema migration attempt. Users are required to manually migrate schema after Hive upgrade which ensures\n" +
        "      proper metastore schema migration. (Default)\n" +
        "False: Warn if the version information stored in metastore doesn't match with one from in Hive jars."),

二是要關(guān)閉JDO框架自動更新元數(shù)據(jù)的功能(生產(chǎn)環(huán)境,不建議打開)刚梭。
因為元數(shù)據(jù)的更新由我們手工操作完成肠阱,這樣更可控,我們更清楚發(fā)生了什么朴读。如果打開該開關(guān)屹徘,JDO框架會默認(rèn)創(chuàng)建缺失的表等。

    METASTORE_AUTO_CREATE_ALL("datanucleus.schema.autoCreateAll", false,
        "creates necessary schema on a startup if one doesn't exist. set this to false, after creating it once"),

最后別忘了在升級完成后衅金,打開版本嚴(yán)格校驗?zāi)J剑ó?dāng)然也可以選擇關(guān)閉)噪伊。

為什么我初始化之后default庫沒有自動創(chuàng)建簿煌?

有時候在initSchema之后,發(fā)現(xiàn)default庫并沒有創(chuàng)建鉴吹,這是因為沒有打開開關(guān):

    METASTORE_DEFAULT_DBROLES_INIT("hive.metastore.default.dbroles.init", false,
        "If true, default db/roles are created and admin roles are added every time when metastore server starts"),

Thanks

54686973 20617274 69636C65 20697320 64656469 63617465 6420746F 20526F6E 67657220 77686F20 49206465 65706C79 206C6F76 65642E54 68697320 61727469 636C6520 69732064 65646963 61746564 20746F20 526F6E67 65722077 686F2049 20646565 706C7920 6C6F7665 642E5468 69732061 72746963 6C652069 73206465 64696361 74656420 746F2052 6F6E6765 72207768 6F204920 64656570 6C79206C 6F766564 2E

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姨伟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子豆励,更是在濱河造成了極大的恐慌夺荒,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件良蒸,死亡現(xiàn)場離奇詭異技扼,居然都是意外死亡,警方通過查閱死者的電腦和手機嫩痰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門剿吻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人始赎,你說我怎么就攤上這事和橙∽醒啵” “怎么了造垛?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長晰搀。 經(jīng)常有香客問我五辽,道長,這世上最難降的妖魔是什么外恕? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任杆逗,我火速辦了婚禮,結(jié)果婚禮上鳞疲,老公的妹妹穿的比我還像新娘罪郊。我一直安慰自己,他們只是感情好尚洽,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布悔橄。 她就那樣靜靜地躺著,像睡著了一般腺毫。 火紅的嫁衣襯著肌膚如雪癣疟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天潮酒,我揣著相機與錄音睛挚,去河邊找鬼。 笑死急黎,一個胖子當(dāng)著我的面吹牛扎狱,可吹牛的內(nèi)容都是我干的侧到。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼淤击,長吁一口氣:“原來是場噩夢啊……” “哼床牧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起遭贸,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤戈咳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后壕吹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體著蛙,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年耳贬,在試婚紗的時候發(fā)現(xiàn)自己被綠了踏堡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡咒劲,死狀恐怖顷蟆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腐魂,我是刑警寧澤帐偎,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蛔屹,受9級特大地震影響削樊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兔毒,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一漫贞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧育叁,春花似錦迅脐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至昵骤,卻和暖如春树碱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背变秦。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工成榜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹦玫。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓赎婚,卻偏偏與公主長得像刘绣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挣输,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

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

  • Hive是什么 我們知道傳統(tǒng)數(shù)據(jù)存儲都是存儲在關(guān)系型數(shù)據(jù)庫中纬凤,它們使用一種SQL(結(jié)構(gòu)化查詢語言)方言來查詢數(shù)據(jù)庫...
    零度沸騰_yjz閱讀 1,113評論 0 7
  • Zookeeper用于集群主備切換。 YARN讓集群具備更好的擴展性撩嚼。 Spark沒有存儲能力停士。 Spark的Ma...
    Yobhel閱讀 7,277評論 0 34
  • 本文是對Hive組件的學(xué)習(xí)的一個初步總結(jié),包括如下章節(jié)的內(nèi)容: Hive是什么 Hive安裝 快速上手 Hive元...
    我是老薛閱讀 1,924評論 1 23
  • hive.ddl.output.format:hive的ddl語句的輸出格式完丽,默認(rèn)是text恋技,純文本,還有json...
    博弈史密斯閱讀 1,947評論 0 6
  • 不知道從哪一天起逻族,我開始厭倦了上班蜻底。也不是上班不好,也不是和同事相處的不好聘鳞,而是對以后的擔(dān)憂薄辅,和對大環(huán)境的...
    追逐夢的自由閱讀 141評論 0 0