數(shù)據(jù)遷移心得

  前幾天出差,去客戶現(xiàn)場幫忙遷移數(shù)據(jù),經(jīng)過幾天的奮戰(zhàn),終于將遷移數(shù)據(jù)自動化起來,并且可以日跑批操作,這里小編就跟大家分享下,這其中踩過的坑(也可能是實戰(zhàn)經(jīng)驗不豐富導(dǎo)致)。
  首先,榮小編我抱怨一下,不是自己熟悉的開發(fā)環(huán)境真的有些難過,給一臺電腦,咱不說沒有IDE,就連java都沒有安裝,連接數(shù)據(jù)庫的工具也沒有,唯一值得慶幸的是有xshell,但是完全不符合個人快捷鍵的喜好,沒辦法,想要開發(fā)高效,自己動手配置吧。單單是配置這些開發(fā)環(huán)境就整整犧牲了小編一上午的時間,還好后期開發(fā)有明顯的提速。中午吃個飯,下午進(jìn)入正題。
  下午拿到遷移任務(wù),發(fā)現(xiàn)一個庫中有很多表,其中表有大有小,當(dāng)時我沉默了幾秒鐘,感覺這個星期是交代在這里了。這里小編在那幾秒鐘的沉默中也把這個遷移流程想了一下,首先數(shù)據(jù)是存在關(guān)系型數(shù)據(jù)庫中的,然后我們要通過sqoop將數(shù)據(jù)上傳到HDFS中,然后用hive的外表去映射這些數(shù)據(jù),最終建立有索引的內(nèi)表來存儲一份完整的數(shù)據(jù)。內(nèi)表一般都是分區(qū),分桶,且有索引的orc表,查詢速度明顯比外表快很多。那么接下來小編就將這其中的步驟,一點點的分析下。

10年積累的做網(wǎng)站、網(wǎng)站設(shè)計經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有高昌免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

前期準(zhǔn)備:

   拿到一個庫的數(shù)據(jù)時,我們首先分析下這里有哪些表比較大,哪些表比較小,將大表和小表分開,使用不同的遷移方法,一般都是客戶提供每張表的數(shù)據(jù)條數(shù),如果沒有的話,只能selecct count(*) from table;將這些表的數(shù)據(jù)查出來,不僅便于區(qū)分大小表,而且對后期數(shù)據(jù)核對有較大的幫助。

1. 從關(guān)系型數(shù)據(jù)庫將數(shù)據(jù)遷移到HDFS中

  這里遷移數(shù)據(jù)小編是用的sqoop,雖然sqoop比較慢,但是學(xué)習(xí)成本相對較低,而且便于批量的生成語句,對開發(fā)要求沒那么高。首先先測試一個sqoop是否可以成功的遷移數(shù)據(jù),然后編寫腳本批量的生成sqoop語句,最后調(diào)用這些語句,后臺并行的遷移數(shù)據(jù)。這里小編先說說使用sqoop的幾個小竅門:

  • 如果集群的資源比較充分,一般新集群是沒有什么生產(chǎn)任務(wù)的,我們的sqoop語句中可以加入:
    -m 這個參數(shù)可以設(shè)置為>1 ,表示并行多個map去抽取數(shù)據(jù)。
    --split-by 當(dāng)然-m 參數(shù)設(shè)置大于后,要同時設(shè)置這個參數(shù),表示以表中的哪一個字段去分map并行。

    這里選取--split-by 盡量使用表中比較分散的字段,保證每一個map任務(wù)抽取的數(shù)據(jù)量都大致相同。

  • 如果表的數(shù)據(jù)量比較大,比如超過億條,我們這里就需要將這個表分成多個sqoop去抽?。?/p>

    --query : 指定where后的條件,抽取部分?jǐn)?shù)據(jù)
       這樣的好處是:如果只有一個sqoop任務(wù),抽取了90%的數(shù)據(jù)后,發(fā)現(xiàn)sqoop任務(wù)掛了,那么本次抽取失敗,不僅耗時,而且數(shù)據(jù)沒有抽取到。分多個sqoop任務(wù),不僅可并行,而且每個任務(wù)的數(shù)據(jù)量也不大,如果有任務(wù)掛了,只需要抽象抽取那個where條件下的數(shù)據(jù)即,并且對于找錯也有極大的幫助。
       分區(qū)字段的選取也同樣重要,這里一般都是使用日期作為where的后的條件,保證每個sqoop任務(wù)分的的數(shù)據(jù)量相差無幾。

    • sqoop抽取數(shù)據(jù)的目錄規(guī)劃
      #小表目錄規(guī)劃
      /tmp/庫名/表名
      #大表的目錄規(guī)劃
      /tmp/庫名/表名/分區(qū)名
  • query語句:在sqoop命令中,我們編寫查詢語句去抽取數(shù)據(jù)時,切記不要:

    -- ×
    select * from table;
    -- √
    select 字段1,字段2.... from table;
    不然可能會導(dǎo)致sqoop抽取速度變慢,甚至可能導(dǎo)致沒有抽取到數(shù)據(jù)。
       當(dāng)我們注意了以上的內(nèi)容后,就可以編寫腳本批量的生成每張表的sqoop語句了,根據(jù)庫名.表名,獲取關(guān)系型數(shù)據(jù)庫中表的元數(shù)據(jù),最后將sqoop組裝起來。最后在編寫任務(wù)腳本,定時執(zhí)行這些sqoop語句。
    實際數(shù)據(jù)分享:
       這里小編測試過,數(shù)據(jù)量比較大時,多sqoop和單sqoop的耗時:
    以600G數(shù)據(jù)為例:
       - 多sqoop 并行抽取數(shù)據(jù)耗時:3~4小時。
       - 單sqoop 抽取數(shù)據(jù)耗時:12小時以上。
       - 單sqoop && (-m 1)抽取5千萬條數(shù)據(jù),大概是27分鐘。

2. 建立外表映射

   說白了就是將抽取到的數(shù)據(jù),在hive中通過外表的方式映射出來,其實這里沒什么難的,主要是看客戶如果要求,可能是外表單獨一個庫,或者外表的名稱統(tǒng)一是:表名_ext。但是切記,不要手動的去編寫建表語句,如果表有百張以上,心態(tài)容易炸,這里可以使用關(guān)系型數(shù)據(jù)庫的元數(shù)據(jù) ,生成hive的建表語句的,這里我們與MySQL為例:

SELECT CONCAT('create table ', TABLE_NAME, '(', substring(column_info, 1, length(column_info) - 1), ')', ' comment ', '"', TABLE_COMMENT, '"', ';')
FROM (SELECT TABLE_NAME, TABLE_COMMENT, group_concat(CONCAT(COLUMN_NAME, ' ', DATA_TYPE, ' comment ', '"', COLUMN_COMMENT, '"')) AS column_info
FROM (SELECT t1.TABLE_NAME, CASE WHEN t2.TABLE_COMMENT = NULL THEN t1.TABLE_NAME ELSE t2.TABLE_COMMENT END AS TABLE_COMMENT, COLUMN_NAME, CASE WHEN DATA_TYPE = 'varchar' THEN 'string' WHEN DATA_TYPE = 'int' THEN 'int' WHEN DATA_TYPE = 'tinyint' THEN 'tinyint' WHEN DATA_TYPE = 'decimal' THEN 'double' WHEN DATA_TYPE = 'datetime' THEN 'string' WHEN DATA_TYPE = 'timestamp' THEN 'string' WHEN DATA_TYPE = 'float' THEN 'double' WHEN DATA_TYPE = 'double' THEN 'double' WHEN DATA_TYPE = 'bigint' THEN 'bigint' END AS DATA_TYPE, CASE WHEN COLUMN_COMMENT = NULL THEN COLUMN_NAME ELSE COLUMN_COMMENT END AS COLUMN_COMMENT
FROM COLUMNS t1 JOIN TABLES t2 ON t1.TABLE_NAME = t2.TABLE_NAME
WHERE t1.TABLE_NAME = 't_app_equipment_status'
) t3
GROUP BY TABLE_NAME, TABLE_COMMENT
) t4;

網(wǎng)上這樣的例子很多,這里小編就不在介紹。當(dāng)外表建立好之后,最好核對一下數(shù)據(jù)量的大小,對比下關(guān)系型數(shù)據(jù)庫中表的數(shù)據(jù)和hive中的數(shù)據(jù)是否相同,這樣驗證了sqoop這一環(huán)節(jié)是否有數(shù)據(jù)丟失的情況。
遇到的坑:
  當(dāng)大表我們在分區(qū)抽取時,是無法直接映射成為外表的,我們需要建立范圍分區(qū)表,將表的分區(qū)目錄映射到各個分區(qū)上。

3. 建立高效的內(nèi)表

   其實這一步就是將,外表的數(shù)據(jù),insert到一張和外表字段相同的經(jīng)過優(yōu)化的內(nèi)表中,這張內(nèi)表一般都是分區(qū)分桶,建立索引,或者基于閃存的表,反正就是查詢的速度大大提高的一張表,也叫做業(yè)務(wù)表。
   小編這里用的是一種基于閃存的高效查詢的,企業(yè)內(nèi)部開發(fā)的一種表結(jié)構(gòu)。小編這里介紹一下如何確定分桶字段:分桶的好處是
   (1)獲得更高的查詢處理效率。桶為表加上了額外的結(jié)構(gòu),Hive 在處理有些查詢時能利用這個結(jié)構(gòu)。具體而言,連接兩個在(包含連接列的)相同列上劃分了桶的表,可以使用 Map 端連接 (Map-side join)高效的實現(xiàn)。比如JOIN操作。對于JOIN操作兩個表有一個相同的列,如果對這兩個表都進(jìn)行了桶操作。那么將保存相同列值的桶進(jìn)行JOIN操作就可以,可以大大較少JOIN的數(shù)據(jù)量。
   (2)使取樣(sampling)更高效。在處理大規(guī)模數(shù)據(jù)集時,在開發(fā)和修改查詢的階段,如果能在數(shù)據(jù)集的一小部分?jǐn)?shù)據(jù)上試運行查詢,會帶來很多方便。
   那么如果確定分桶字段呢,一般的如果有主鍵的表就使用主鍵作為分桶字段,如果沒有主鍵的表,找?guī)讉€比較分散的字段使用:

 select count(distinct feild) from table;

找出數(shù)據(jù)最大的那個字段作為分桶字段。具體的分桶數(shù),這里建議是一個質(zhì)數(shù),因為如果是一個非質(zhì)數(shù),那么可能導(dǎo)致分桶不均勻,因為如果分桶數(shù)是9的話,那么字段值如果為18、27都會分到一個桶中,可能會導(dǎo)致桶“熱點”。

4. 外表insert 到 內(nèi)表中

   這個過程是耗時僅次于sqoop的過程,由于我們的內(nèi)表建立的分區(qū),那么在這個步驟中我們需要使用hive的動態(tài)分區(qū)插入,插入語句一般都是:

    insert into table_1 partition(par_field) select field1.field2...from table_2 ;

這里需要注意的是select 最后一個字段一定要是分區(qū)字段。
   當(dāng)我們insert 后,需要核對下是否所有的數(shù)據(jù)全部insert成功,此時:外表數(shù)據(jù)量=內(nèi)表數(shù)據(jù)量=關(guān)系型數(shù)據(jù)庫數(shù)據(jù)量。

5. 日增量數(shù)據(jù)的處理

   當(dāng)我們完成數(shù)據(jù)遷移后,其實外表相當(dāng)于一個中轉(zhuǎn)站,僅僅是將數(shù)據(jù)中轉(zhuǎn)到內(nèi)表中,如果我們確保了內(nèi)表中有一份完整的數(shù)據(jù),此時可以將外表的數(shù)據(jù)清空,這也是為什么我們將外表的location 設(shè)置為/tmp下 的原因,清空外表數(shù)據(jù)后,將日增數(shù)據(jù)抽取到外表的location地址上,然后全量的將外表數(shù)據(jù)insert到內(nèi)表中,就保證了日增量數(shù)據(jù)的成功導(dǎo)入到hive。

網(wǎng)站名稱:數(shù)據(jù)遷移心得
本文鏈接:http://bm7419.com/article6/jjejog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷虛擬主機、用戶體驗關(guān)鍵詞優(yōu)化、面包屑導(dǎo)航商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)