本文为学习笔记,会随着学习深入持续更新,仅供参考
一、hive是干什么的
建立在hadoop上的数仓系统,可以将存储在hadoop中的结构化/半结构化数据映射成一张数据库表,提供基于sql的查询模型(HQL)。hive的核心是将HQL转化成mapReduce程序,然后将程序提交给hadoop集群去执行。
二、hive实现基本原理和基本组件
元数据:映射关系,包括:表的类型、存储位置、属性、字段顺序等。元数据可以存储在内置库中也可以存在第三方库中(如:mysql),外边服务想要访问元数据需要通过元数据服务(MetaStore)实现。生产环境常配置为远程模式
1、hive和mysql的区别
hive需要现有文件在映射出表
mysql是现有表结构在插入数据
2、hive的分区分桶应用场景
分区使用的是表外数据,比如按照时间进行分区,是一个大粒度划分,如果分区后数据还是太多,可以通过分桶,即根据表内字段进行进细粒度划分,类似于一个树形结构。
参考链接
3、HIVE数据的压缩与存储格式
使用压缩技术,减少数据大小,提高传输效率。
4、hive的多级分区是什么
通过将数据按多个维度进行分区,可以显著提高查询性能和数据管理的效率。举例:假设我们有一个电商网站的订单数据,需要按年、月、日进行分区存储。这样,我们可以方便地按时间范围查询订单数据,并且可以轻松地管理和清理历史数据。
#建表
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中实现
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的表是分内部表和外部表的。内部表就包含元数据和实际数据,外部表是只包含元数据,用于关联一些文件等。
内部表(Managed Table)适用场景:
a) 数据完全由Hive管理:如果数据的生命周期完全在Hive中管理,
b) 临时或中间数据:用于临时分析、实验或中间结果存储。
c) 全新的数据集:当你从其他数据源导入数据并希望Hive接管其管理时
外部表(External Table)适用场景:
a) 共享数据:数据需要被多个工具或框架共享,如Spark、Pig等。外部表允许你在Hive中定义表结构,而不改变数据的实际存储位置。
b) 现有数据集:数据已经存在于HDFS或其他存储系统中,你希望在Hive中对其进行查询和分析,但不希望Hive管理数据的生命周期。
d) 数据保留策略:当你希望保留数据,即使删除了表结构定义。删除外部表只会删除表的元数据信息,不会删除实际的数据文件。
e) 分区管理复杂:当你需要手动管理分区数据,或者分区数据由外部系统生成和管理时,外部表可以更灵活地处理这些情况。
下面以hive实现hdfs数据读取和写入全流程为例进行说明:
Default数据仓库的最原始位置是在hdfs上的:/user/hive/warehouse路径下。只有在这个路径下才能实现hive的表和文件自动关联。
1、配置mysql库存储元数据
即配置Hive的conf/hive-site.xml文件,添加MySQL的连接信息。
2、实现数据导入导出逻辑
-- 创建一个表
CREATE TABLE my_table (id INT, name STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LOCATION '/user/hive/warehouse/my_table';
-- 将数据放入HDFS的表位置
put my_data.csv /user/hive/warehouse/my_table;
-- 从HDFS读取数据
SELECT * FROM my_table;
-- 将查询结果写入到新的HDFS位置
INSERT OVERWRITE DIRECTORY '/user/hive/warehouse/new_table'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
SELECT * FROM my_table;
四、在springboot中实现hive从hadoop导入导出数据
1、hive中配置jdbc
2、hive中建表(见上边)
2、springboot中实现数据导入导出
1、pom添加依赖
复制代码<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应用中配置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执行SQL语句进行数据导入和导出:
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是一个分布式小文件存储器,支持主从模式,具有全局数据一致性特点,就是每个节点都有一份完整数据。主要用来解决分布式应用中数据管理问题,如:状态同步、集群选举管理、应用配置项管理等。
1、怎么保障全局数据一致性?
leader把所有事务性请求编号,然后依次执行。
2、怎么协调数据管理?
具有监听机制(客户端发起zk会启动监听),数据发布订阅(分布式环境配置统一配置中心,监听支持实时更新),选举(监听触发),分布式锁。以上上这几个主要功能都是以监听机制为基础进行的。
参考链接
1、Hive手册
2、Hive内部表、外部表区别是?分区表如何使用?为什么要分桶?
3、Hive-表数据的导出、导入(HDFS、本地)