本文為學(xué)習(xí)筆記灾部,會隨著學(xué)習(xí)深入持續(xù)更新绷蹲,僅供參考
一、hive是干什么的
????????建立在hadoop上的數(shù)倉系統(tǒng)修档,可以將存儲在hadoop中的結(jié)構(gòu)化/半結(jié)構(gòu)化數(shù)據(jù)映射成一張數(shù)據(jù)庫表碧绞,提供基于sql的查詢模型(HQL)。hive的核心是將HQL轉(zhuǎn)化成mapReduce程序吱窝,然后將程序提交給hadoop集群去執(zhí)行讥邻。
二、hive實現(xiàn)基本原理和基本組件
元數(shù)據(jù):映射關(guān)系院峡,包括:表的類型计维、存儲位置、屬性撕予、字段順序等。元數(shù)據(jù)可以存儲在內(nèi)置庫中也可以存在第三方庫中(如:mysql)蜈首,外邊服務(wù)想要訪問元數(shù)據(jù)需要通過元數(shù)據(jù)服務(wù)(MetaStore)實現(xiàn)实抡。生產(chǎn)環(huán)境常配置為遠程模式
1、hive和mysql的區(qū)別
hive需要現(xiàn)有文件在映射出表
mysql是現(xiàn)有表結(jié)構(gòu)在插入數(shù)據(jù)
2欢策、hive的分區(qū)分桶應(yīng)用場景
????????分區(qū)使用的是表外數(shù)據(jù)吆寨,比如按照時間進行分區(qū),是一個大粒度劃分踩寇,如果分區(qū)后數(shù)據(jù)還是太多啄清,可以通過分桶,即根據(jù)表內(nèi)字段進行進細粒度劃分俺孙,類似于一個樹形結(jié)構(gòu)辣卒。
參考鏈接
3掷贾、HIVE數(shù)據(jù)的壓縮與存儲格式
????????使用壓縮技術(shù),減少數(shù)據(jù)大小荣茫,提高傳輸效率想帅。
4、hive的多級分區(qū)是什么
????????通過將數(shù)據(jù)按多個維度進行分區(qū)啡莉,可以顯著提高查詢性能和數(shù)據(jù)管理的效率港准。舉例:假設(shè)我們有一個電商網(wǎng)站的訂單數(shù)據(jù),需要按年咧欣、月浅缸、日進行分區(qū)存儲。這樣魄咕,我們可以方便地按時間范圍查詢訂單數(shù)據(jù)衩椒,并且可以輕松地管理和清理歷史數(shù)據(jù)。
#建表
CREATE TABLE IF NOT EXISTS orders (
order_id STRING,
customer_id STRING,
amount DOUBLE
)
PARTITIONED BY (year STRING, month STRING, day STRING)
STORED AS ORC;
#在sprignboot中實現(xiàn)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void createPartitionedTable() {
String createTableQuery = "CREATE TABLE IF NOT EXISTS orders (" +
"order_id STRING, " +
"customer_id STRING, " +
"amount DOUBLE" +
") PARTITIONED BY (year STRING, month STRING, day STRING) " +
"STORED AS ORC";
jdbcTemplate.execute(createTableQuery);
}
public void insertOrder(String orderId, String customerId, double amount, String year, String month, String day) {
String insertQuery = String.format(
"INSERT INTO TABLE orders PARTITION (year='%s', month='%s', day='%s') VALUES ('%s', '%s', %f)",
year, month, day, orderId, customerId, amount
);
jdbcTemplate.execute(insertQuery);
}
public List<Map<String, Object>> queryOrders(String year, String month, String day) {
String query = String.format("SELECT * FROM orders WHERE year='%s' AND month='%s' AND day='%s'", year, month, day);
return jdbcTemplate.queryForList(query);
}
}
三蚕礼、常用API
1烟具、基本操作語句
????????hive的表是分內(nèi)部表和外部表的。內(nèi)部表就包含元數(shù)據(jù)和實際數(shù)據(jù)奠蹬,外部表是只包含元數(shù)據(jù)朝聋,用于關(guān)聯(lián)一些文件等。
內(nèi)部表(Managed Table)適用場景:
a) 數(shù)據(jù)完全由Hive管理:如果數(shù)據(jù)的生命周期完全在Hive中管理囤躁,
b) 臨時或中間數(shù)據(jù):用于臨時分析冀痕、實驗或中間結(jié)果存儲。
c) 全新的數(shù)據(jù)集:當(dāng)你從其他數(shù)據(jù)源導(dǎo)入數(shù)據(jù)并希望Hive接管其管理時
外部表(External Table)適用場景:
a) 共享數(shù)據(jù):數(shù)據(jù)需要被多個工具或框架共享狸演,如Spark言蛇、Pig等。外部表允許你在Hive中定義表結(jié)構(gòu)宵距,而不改變數(shù)據(jù)的實際存儲位置腊尚。
b) 現(xiàn)有數(shù)據(jù)集:數(shù)據(jù)已經(jīng)存在于HDFS或其他存儲系統(tǒng)中,你希望在Hive中對其進行查詢和分析满哪,但不希望Hive管理數(shù)據(jù)的生命周期婿斥。
d) 數(shù)據(jù)保留策略:當(dāng)你希望保留數(shù)據(jù),即使刪除了表結(jié)構(gòu)定義哨鸭。刪除外部表只會刪除表的元數(shù)據(jù)信息民宿,不會刪除實際的數(shù)據(jù)文件。
e) 分區(qū)管理復(fù)雜:當(dāng)你需要手動管理分區(qū)數(shù)據(jù)像鸡,或者分區(qū)數(shù)據(jù)由外部系統(tǒng)生成和管理時活鹰,外部表可以更靈活地處理這些情況。
????????下面以hive實現(xiàn)hdfs數(shù)據(jù)讀取和寫入全流程為例進行說明:
????????Default數(shù)據(jù)倉庫的最原始位置是在hdfs上的:/user/hive/warehouse路徑下。只有在這個路徑下才能實現(xiàn)hive的表和文件自動關(guān)聯(lián)志群。
1着绷、配置mysql庫存儲元數(shù)據(jù)
????????即配置Hive的conf/hive-site.xml文件,添加MySQL的連接信息赖舟。
2蓬戚、實現(xiàn)數(shù)據(jù)導(dǎo)入導(dǎo)出邏輯
-- 創(chuàng)建一個表
CREATE TABLE my_table (id INT, name STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LOCATION '/user/hive/warehouse/my_table';
-- 將數(shù)據(jù)放入HDFS的表位置
put my_data.csv /user/hive/warehouse/my_table;
-- 從HDFS讀取數(shù)據(jù)
SELECT * FROM my_table;
-- 將查詢結(jié)果寫入到新的HDFS位置
INSERT OVERWRITE DIRECTORY '/user/hive/warehouse/new_table'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
SELECT * FROM my_table;
四、在springboot中實現(xiàn)hive從hadoop導(dǎo)入導(dǎo)出數(shù)據(jù)
1宾抓、hive中配置jdbc
2子漩、hive中建表(見上邊)
2、springboot中實現(xiàn)數(shù)據(jù)導(dǎo)入導(dǎo)出
1石洗、pom添加依賴
復(fù)制代碼<dependencies>
<!-- Hive JDBC Driver -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>3.1.2</version>
</dependency>
<!-- Hadoop Common -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.2.1</version>
</dependency>
<!-- Hadoop Client -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
2幢泼、在Spring Boot應(yīng)用中配置Hive連接:
# application.properties
spring.datasource.url=jdbc:hive2://your_hive_server:10000/default
spring.datasource.username=hive_user
spring.datasource.password=hive_password
spring.datasource.driver-class-name=org.apache.hive.jdbc.HiveDriver
3、使用JdbcTemplate執(zhí)行SQL語句進行數(shù)據(jù)導(dǎo)入和導(dǎo)出:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class HiveService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void executeQuery(String query) {
jdbcTemplate.execute(query);
}
public void loadDataFromHDFS(String hdfsFilePath, String hiveTableName) {
String query = String.format("LOAD DATA INPATH '%s' INTO TABLE %s", hdfsFilePath, hiveTableName);
executeQuery(query);
}
public void exportDataToHDFS(String hiveTableName, String hdfsDirPath) {
String query = String.format("INSERT OVERWRITE DIRECTORY '%s' SELECT * FROM %s", hdfsDirPath, hiveTableName);
executeQuery(query);
}
}
補充介紹下zookeeper
zk是一個分布式小文件存儲器讲衫,支持主從模式缕棵,具有全局數(shù)據(jù)一致性特點,就是每個節(jié)點都有一份完整數(shù)據(jù)涉兽。主要用來解決分布式應(yīng)用中數(shù)據(jù)管理問題招驴,如:狀態(tài)同步、集群選舉管理枷畏、應(yīng)用配置項管理等别厘。
1、怎么保障全局數(shù)據(jù)一致性拥诡?
leader把所有事務(wù)性請求編號触趴,然后依次執(zhí)行。
2渴肉、怎么協(xié)調(diào)數(shù)據(jù)管理冗懦?
具有監(jiān)聽機制(客戶端發(fā)起zk會啟動監(jiān)聽),數(shù)據(jù)發(fā)布訂閱(分布式環(huán)境配置統(tǒng)一配置中心仇祭,監(jiān)聽支持實時更新)披蕉,選舉(監(jiān)聽觸發(fā)),分布式鎖乌奇。以上上這幾個主要功能都是以監(jiān)聽機制為基礎(chǔ)進行的嚣艇。
參考鏈接
1、Hive手冊
2华弓、Hive內(nèi)部表、外部表區(qū)別是困乒?分區(qū)表如何使用寂屏?為什么要分桶?
3、Hive-表數(shù)據(jù)的導(dǎo)出迁霎、導(dǎo)入(HDFS吱抚、本地)