什麼是hive的靜態分區和動態分區,它們又有什麼區別呢?hive動態分區詳解

来源:https://www.cnblogs.com/lubians/archive/2022/08/07/16559562.html
-Advertisement-
Play Games

1.ETCD概述 1.1 ETCD概述 etcd是一個高可用的分散式的鍵值對存儲系統,常用做配置共用和服務發現。由CoreOS公司發起的一個開源項目,受到ZooKeeper與doozer啟發而催生的項目,名稱etcd源自兩個想法,即Linux的**/etc文件夾和d分散式系統。/etc**文件夾是用 ...


面試官問我,什麼是hive的靜態分區和動態分區,這題我會呀。

簡述

分區是hive存放數據的一種方式,將列值作為目錄來存放數據,就是一個分區,可以有多列。

這樣查詢時使用分區列進行過濾,只需根據列值直接掃描對應目錄下的數據,不掃描不關心的分區,快速定位,提高查詢效率。

hive的分區有兩種類型:

  • 靜態分區SP(Static Partitioning)
  • 動態分區DP(Dynamic Partitioning)

對於靜態分區,表的分區數量和分區值是固定的。新增分區或者是載入分區數據時,需要提前指定分區名。

對於動態分區,分區的值是不確定的,會根據數據自動的創建新的分區。

一、靜態分區

如上所述,靜態分區的使用場景主要是分區的數量是確定的。例如日誌流水數據中使用日期作為分區欄位,通常在寫入之前就已經確定了是哪個分區。

1.單分區建表

create table if not exists day_log(
  uid bigint,
  uname string,
  action string
) comment '用戶動作流水記錄'
partitioned by(ymd string comment '日期格式yyyyMMdd')
row format delimited fields terminated by '\t';

2.載入數據到指定分區

load data local inpath '/user/hive/data/day_log.txt' 
into table day_log paritition(ymd='20220803')

3.創建具有多個分區的表

create table if not exists day_log(
  uid bigint,
  uname string,
  action string
) comment '用戶動作流水記錄'
partitioned by(year string,month string,day string)
row format delimited fields terminated by '\t';

4.載入數據

load data local inpath '/user/hive/data/day_log.txt' 
into table day_log paritition(year='2022',month='08',day='02')

但通常我們寫入分區數據是通過計算SQL結果直接寫入,並不是從外部文件load進來的。示例如下:

insert overwrite table day_log partition (year='2022',month='08',day='02')
select uid,uname,action from (
	xxxxxx
)

二、動態分區

所謂動態分區,分區的值是不確定的,分區的數量是不確定,皆由載入數據確定。
生產環境中,動態分區一般常用於創建新表後,需要一次性載入歷史數據。

1.創建臨時表

-- 創建臨時表
create table if not exists tmp (
  uid int,
  commentid bigint,
  recommentid bigint,
  year int,
  month int,
  day int
)
row format delimited fields terminated by '\t';

-- 載入數據到臨時表
load data local inpath 'user/hive/data/tmp.txt' into table tmp;

2.創建動態分區表

-- 創建動態分區表
create table if not exists dp_tmp(
	uid int,
	commentid bigint,
	recommentid bigint
)
partitioned by (year string,month string,day string)
row format delimited fields terminated by '\t';

-- 寫入數據到分區表
-- 參數為開啟動態分區
set hive.exec.dynamic.partition=true;
insert overwrite table dp_tmp partition(year,month,day)
select uid,commentid,recommentid,year,month,day from tmp;

執行上述寫入語句會報錯:

FAILED: SemanticException [Error 10096]: Dynamic partition strict mode requires at least one static partition column. To turn this off set hive.exec.dynamic.partition.mode=nonstrict

看報錯信息:動態分區嚴格模式至少需要一個靜態分區列。關閉它,設置參數

set hive.exec.dynamic.partition.mode=nonstrict

下文介紹hive相關參數作用

3.嚴格模式

參數hive.exec.dynamic.partition.mode表示動態分區的模式。
預設是strict,也就是嚴格模式,表示必須指定至少一個分區為靜態分區

nonstrict模式,即非嚴格模式,表示允許所有的分區欄位都可以使用動態分區

嚴格模式

-- 至少需要指定一個靜態分區列
-- 開啟動態分區
set hive.exec.dynamic.partition=true;
insert overwrite table dp_tmp partition(year='2022',month,day)
select uid,commentid,recommentid,month,day from tmp;

4.非嚴格模式

set hive.exec.dynamic.partition=true;
-- 允許所有的分區欄位都可以使用動態分區,相容嚴格模式
-- 更改動態分區模式為非嚴格模式
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table dp_tmp partition(year,month,day)
select uid,commentid,recommentid,month,day from tmp;

通常情況下,我們使用動態分區,為非嚴格模式:

 set hive.exec.dynamic.partition=true;
 set hive.exec.dynamic.partition.mode=nonstrict;

三、靜態分區和動態分區的區別

兩種分區模式根據定義就可看出來明顯區別,這裡單列一下:

靜態分區(Static Partitioning) 動態分區(Dynamic Partitioning)
分區創建 數據插入分區之前,需要手動指定創建每個分區 根據表的輸入數據動態創建分區
適用場景 需要提前知道所有分區。適用於分區定義得早且數量少的用例,常見為插入某一個指定分區 有很多分區,無法提前預估新分區,動態分區是合適的

另外動態分區的值是MapReduce任務在reduce運行階段確定的,也就是所有的記錄都會distribute by,相同欄位(分區欄位)的map輸出會發到同一個reduce節點去處理,如果數據量大,這是一個很弱的運行性能。

而靜態分區在編譯階段就確定了,不需要reduce任務處理。所以如果實際業務場景靜態分區能解決的,儘量使用靜態分區即可。

四、分區使用註意事項

1.hive分區參數及作用

hive表中的分區作用主要是使數據按照分區目錄存儲在hdfs上,查詢只要針對指定的目錄集合進行查詢,避免全局查找,這樣提高了查詢性能。

hive的分區需要合理使用,過多的分區目錄和文件對於集群Namenode服務是有性能壓力的,Namenode需要將大量的元數據信息保存在記憶體中。如果報錯,會造成Namenode不可用。

一次查詢表裡有太多分區,會使得查詢文件過大,也會造成Metastore服務出現OOM報錯,報錯信息顯示Metastore不可用。

hive為了避免因為異常產生大量分區,導致上述問題,本身是預設動態分區關閉,同時對生成動態分區的數量也做了一定限制。

通過手動參數設置可以改變系統預設值,具體hive預設參數以及SQL執行配置參數(不同版本預設參數有一定差異)如下:

-- Hive預設配置值
-- 開啟或關閉動態分區
hive.exec.dynamic.partition=false;
-- 設置為nonstrict模式,讓所有分區都動態配置,否則至少需要指定一個分區值
hive.exec.dynamic.partition.mode=strict;
-- 能被mapper或reducer創建的最大動態分區數,超出而報錯
hive.exec.max.dynamic.partitions.pernode=100;
-- 一條帶有動態分區SQL語句所能創建的最大動態分區總數,超過則報錯
hive.exec.max.dynamic.partitions=1000;
-- 全局能被創建文件數目的最大值,通過Hadoop計數器跟蹤,若超過則報錯
hive.exec.max.created.files=100000;

-- 根據個人需要配置
-- 設置動態分區開啟
set hive.exec.dynamic.partition=true;  
-- 設置為非嚴格模式
set hive.exec.dynamic.partition.mode=nonstrict;
-- 設置每個節點創建最大分區數
set hive.exec.max.dynamic.partitions.pernode=1000;
-- 設置執行SQL創建最大分區數
set hive.exec.max.dynamic.partitions=10000;
-- 設置全局被創建文件最大值
set hive.exec.max.created.files=1000000;

在執行hiveSQL的時候如果動態分區數量或文件數任何一個超過集群預設就會產生報錯:

ERROR [LocalJobRunner Map Task Executor #0]:mr.ExecMapper (ExecMapper.java:map(171)) - org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row ....
 Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: [Error 20004]: Fatal error occurred when node tried to create too many dynamic partitions. The maximum number of dynamic partitions is controlled by hive.exec.max.dynamic.partitions and hive.exec.max.dynamic.partitions.pernode. Maximum was set to: 256... 10 more

集群會kill任務。為瞭解決報錯,我們通常將三個參數調大。但是也需要用戶對自己的Hive表的分區數量進行合理規劃,避免過多的分區

2.分區常見註意事項

a. 儘量不要使用動態分區,因為動態分區的時候,將會為每一個分區分配reducer數量,當分區數量多的時候,reducer數量將會增加,對伺服器是一種災難。

b. 動態分區和靜態分區的區別,靜態分區不管有沒有數據都會創建指定分區,動態分區是有結果集將創建,否則不創建。

c. hive動態分區的嚴格模式和hive嚴格模式是不同的。

hive提供的嚴格模式簡述:
hive提供的嚴格模式,為了組織用戶不小心提交惡意SQL
hive.mapred.mode=nostrict : strict
如果該模式值為strict,將會阻止一下三種查詢:
a.對分區表查詢,where條件中過濾欄位沒有分區欄位;
b.笛卡爾積join查詢,join查詢語句中不帶on條件或者where條件;
c.對order by查詢,有order by的查詢不太limit語句。

3.一些異常分區處理

a.預設分區

如果動態分區列輸入的值為NULL或空字元串,則hive將該行放入一個特殊分區,分區名稱由參數hive.exec.default.partition.name控制。

預設值為__HIVE_DEFAULT_PARTITION__。可以通過查看表分區命令進行查看:

show partitions 'table';
  
-- ymd=__HIVE_DEFAULT_PARTITION__

清理該分區使用正常刪除分區語句即可。對分區的操作命令詳見上篇文章。

b.亂碼分區

表分區欄位處理不當可能會造成亂碼分區,主要是由於轉譯編碼原因造成。例如:

sp_test=r_ready%3D91;r_load%3D351

原因是Hive會自動對一些UTF-8字元編碼成Unicode(類似網址中中文字元和一些特殊字元的編碼處理)。此處%3D解碼後是'='。可以使用線上轉換進行解碼:https://www.matools.com/code-convert-utf8。

最後使用解碼後的欄位即可(註意分號轉義):

alter table dpdw_traffic_base drop partition(sp_test='r_ready=91\;r_load=351');

上一篇:關於hive分區,你知道多少呢?

按例,我的個人公眾號:魯邊社,歡迎關註
魯邊社

後臺回覆關鍵字 hive,隨機贈送一本魯邊備註版珍藏大數據書籍。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 它是基於Django的,幫助我們快速開發符合RESTful規範的介面框架。 一 路由 可以通過路由as_view()傳參 根據請求方式的不同執行對應不同的方法 在routers模塊下 封裝了很多關於路由的方法 , 最基礎的BaseRouter類,給我提供自定製的介面。 下麵這個方法給我們提供了自動生 ...
  • 配置文件設置 set number (設置行號) set nocompatible (設置不相容vi模式,不設置會導致許多vim特性被禁用) set clipboard=unnamed (設置普通的複製粘貼的內容和vim複製的內容相互使用) 打開、編輯,查找文件 vim + 任意文件名,如vim f ...
  • “Linux,全稱GNU/Linux,是一種免費使用和自由傳播的類UNIX操作系統,其內核由林納斯·本納第克特·托瓦茲於1991年10月5日首次發佈,它主要受到Minix和Unix思想的啟發,是一個基於POSIX的多用戶、多任務、支持多線程和多CPU的操作系統。 ...
  • 想要將圖片中的文字提取出來嗎?小編今天為大家分享一款線上文字識別轉換工具—"Text Scanner"。Text Scanner for Mac是一款非常不錯的線上文字識別轉換工具,辨識速度快,操作流程也簡單直接,且會自動判斷各國語言,非常簡單! Text Scanner mac版基於AI領先的深度 ...
  • linux安裝光碟中的相關文件: [root@Centos8 cdrom]# ls BaseOS EFI images isolinux LICENSE media.repo Minimal TRANS.TBL #isolinux:存放和安裝相關的文件 [root@Centos8 isolinux] ...
  • Past for iChat 是一個Mac小應用程式,用於在macOS Big Sur、Monterey 及更高版本上打開和查看由 Apple 的 iChat 應用程式(.ichat 和 .chat 文件)創建的舊聊天日誌文件,iChat是新的和改進的消息應用程式的前身,使用非常方便。 詳情:Pas ...
  • NoSQL 1. 定義 NoSQL(Not Only SQL)即不僅僅是 SQL,泛指非關係型的資料庫 2. 為什麼使用 NoSQL? 傳統關係資料庫在應付動態網站、特別是超大規模和高併發的純動態網站已經顯得力不從心了,如商品網站中對商品數據的頻繁查詢、熱搜商品的排行統計、訂單超時問題。雖然能實現功 ...
  • 前幾天有個需求需要基於分類數據向上統計總數,一開始第一個想法是通過程式來計算,後再思考能不能通過SQL腳本直接來計算 基礎數據 | Id | ParentId | Category | Num | | | | | | | 1 | 0 | 分類1 | 0 | | 2 | 1 | 分類1-1 | 10 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...