Hive进阶之路
目录
一、Hive 基础回顾
二、数据定义语言(DDL)进阶
2.1 复杂表创建
2.2 分区与分桶优化
三、数据操作语言(DML)深入
3.1 高效的数据加载
3.2 灵活的数据更新与删除
四、Hive 函数高级应用
4.1 内置函数的巧用
4.2 自定义函数(UDF)开发
五、查询优化技巧
5.1 查询语句优化
5.1.1 全表扫描问题
5.1.2 笛卡尔积问题
5.2 执行计划分析
六、Hive 高级特性
6.1 ACID 与事务支持
6.2 Hive on Tez/Spark
6.2.1 Hive 与 Tez 集成
6.2.2 Hive 与 Spark 集成
七、实战案例分析
7.1 电商数据分析案例
7.2 日志分析案例
八、总结与展望
一、Hive 基础回顾
Hive 是基于 Hadoop 的数据仓库工具,能将结构化数据文件映射为数据库表,并提供类 SQL 查询功能,它将 SQL 语句转变成 MapReduce 任务执行,大大降低了大数据处理的门槛,让熟悉 SQL 的开发者能轻松进行数据分析。
Hive 的架构主要包含用户接口、元数据存储、解释器、编译器、优化器和执行器等组件。用户接口常见的有 CLI(命令行接口)、JDBC/ODBC 和 WebGUI,方便用户与 Hive 交互,提交查询语句。元数据存储通常使用关系数据库(如 MySQL),用于保存表结构、列信息、分区、表属性及数据存储目录等元数据,这些元数据对 Hive 理解和处理数据至关重要。当用户提交 Hive SQL 语句后,解释器会将其转换为语法树,编译器把语法树编译成逻辑执行计划,优化器对逻辑执行计划进行优化,以提高执行效率,最后执行器调用底层的运行框架(通常是 MapReduce,也可以是 Tez、Spark 等)执行优化后的逻辑执行计划,并将结果返回给用户。
Hive 与 Hadoop 紧密相关,是 Hadoop 生态系统的重要组成部分。Hadoop 提供了分布式存储(HDFS)和计算(MapReduce)的基础架构,Hive 则构建在 Hadoop 之上。Hive 的数据都存储在 HDFS 中,利用 Hadoop 的分布式存储能力,实现海量数据的存储。在查询执行时,Hive 将 SQL 查询转化为 MapReduce 任务,借助 Hadoop 的 MapReduce 框架进行分布式计算,充分发挥 Hadoop 并行处理大数据的优势。不过,并非所有 Hive 查询都会生成 MapReduce 任务,例如简单的全表扫描(如select * from table)可能无需 MapReduce 即可完成。
在大数据处理领域,Hive 扮演着举足轻重的角色。它为数据仓库的构建和分析提供了强大支持,使企业能方便地对大规模数据进行存储、查询和分析。通过 Hive,数据分析师和开发人员可以利用熟悉的 SQL 语法,完成复杂的数据处理任务,无需深入了解底层复杂的分布式计算和存储细节,大大提高了开发效率和数据分析的灵活性,成为大数据处理不可或缺的工具之一。
二、数据定义语言(DDL)进阶
2.1 复杂表创建
在 Hive 中,除了常见的基本数据类型(如 INT、STRING、DOUBLE 等),还支持复杂数据类型,这使得数据存储和处理更加灵活,能适应多样化的数据格式。
Array 类型:Array 是一种有序的数组类型,用于存储一组相同类型的数据。例如,若要记录每个学生的选修课程列表,就可以使用 Array 类型。建表语句如下:
CREATE TABLE students ( id INT, name STRING, courses ARRAY<STRING> ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY ','; |
在这个例子中,courses列的数据类型为ARRAY<STRING>,表示它是一个字符串数组,用于存储学生选修的课程名称。数据文件中,不同课程之间用逗号(由COLLECTION ITEMS TERMINATED BY ','指定)分隔,如下所示:
1 Alice Math,English,Physics 2 Bob Chemistry,Biology |
Map 类型:Map 是一种键值对的数据结构,用于存储一组键值对,其中键和值的数据类型可以不同。比如,记录每个学生的课程成绩,就可以使用 Map 类型,以课程名称为键,成绩为值。建表语句如下:
CREATE TABLE student_scores ( id INT, name STRING, scores MAP<STRING, INT> ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY ',' MAP KEYS TERMINATED BY ':'; |
这里,scores列的数据类型为MAP<STRING, INT>,表示它是一个键为字符串(课程名称),值为整数(成绩)的键值对集合。数据文件中,不同键值对之间用逗号分隔,键和值之间用冒号(由MAP KEYS TERMINATED BY ':'指定)分隔,数据如下:
1 Alice Math:90,English:85,Physics:88 2 Bob Chemistry:75,Biology:80 |
Struct 类型:Struct 用于将多个不同类型的数据组合成一个结构体。比如,记录学生的基本信息,包括姓名、年龄和地址,就可以使用 Struct 类型。建表语句如下:
CREATE TABLE student_info ( id INT, info STRUCT<name:STRING, age:INT, address:STRING> ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY ','; |
在这个例子中,info列的数据类型为STRUCT<name:STRING, age:INT, address:STRING>,表示它是一个包含name(字符串类型)、age(整数类型)和address(字符串类型)三个字段的结构体。数据文件中,结构体内部字段之间用逗号分隔,数据如下:
1 Alice,20,New York 2 Bob,22,Los Angeles |
这些复杂数据类型在实际应用中非常广泛。在电商领域,记录用户的订单信息时,Array类型可用于存储订单中的商品列表,Map类型可用于存储商品的属性(如颜色、尺码等)及其对应值,Struct类型可用于存储用户的详细地址信息(包括省、市、区等)。在日志分析中,Array类型可用于存储一条日志中的多个操作步骤,Map类型可用于存储日志的各种属性(如时间、来源等)及其对应值,Struct类型可用于存储日志的结构化信息(如用户 ID、设备信息等)。通过合理使用这些复杂数据类型,可以更有效地存储和处理复杂的数据,提高数据分析的效率和灵活性。
2.2 分区与分桶优化
在 Hive 中,分区(Partitioning)和分桶(Bucketing)是两种重要的数据组织和查询优化技术,能显著提升大数据处理的效率。
分区表原理与优势:分区表是根据表的某一列(或多列)的值将数据划分为不同的逻辑分区,每个分区对应 HDFS 上的一个目录,其中存储着符合该分区条件的数据。例如,有一个销售记录表sales,包含order_id(订单 ID)、order_date(订单日期)、customer_id(客户 ID)和amount(订单金额)等字段。如果经常按日期查询销售数据,就可以按order_date列对sales表进行分区,建表语句如下:
CREATE TABLE sales ( order_id INT, customer_id INT, amount DECIMAL(10, 2) ) PARTITIONED BY (order_date STRING); |
分区表的优势在于查询时,Hive 只需扫描与查询条件匹配的分区,而无需扫描整个表,大大减少了数据扫描量,从而提高查询效率。比如查询 2023 年 10 月 1 日的销售数据,Hive 只会扫描order_date为2023-10-01的分区目录下的数据,而不会扫描其他日期的分区,极大提升了查询速度。此外,分区表在数据管理方面也很方便,如可以方便地删除某个分区的数据,实现数据的快速清理和维护。
分桶表原理与优势:分桶表是使用哈希函数将数据行分配到固定数量的桶(buckets)中,每个桶对应一个数据文件。分桶依据的列称为分桶列,Hive 会对分桶列的值计算哈希值,并根据哈希值将数据分配到相应的桶中。继续以上述sales表为例,如果经常需要按照customer_id进行连接操作,为了提高连接效率,可以按customer_id列对sales表进行分桶,建表语句如下:
CREATE TABLE sales ( order_id INT, order_date STRING, customer_id INT, amount DECIMAL(10, 2) ) CLUSTERED BY (customer_id) INTO 16 BUCKETS; |
这里将sales表按customer_id列分桶,分为 16 个桶。分桶表在处理连接操作时优势明显。当连接两个分桶表,且它们的分桶列和桶数量相同时,Hive 可以直接根据桶的编号进行连接,而无需扫描整个表,大大减少了数据传输和处理的开销,提高了连接操作的效率。分桶表还能使数据分布更加均匀,避免数据倾斜问题,提升查询性能。
分区与分桶结合使用:在实际应用中,常常将分区和分桶结合起来,以充分发挥两者的优势。比如,对于sales表,可以先按order_date分区,再在每个分区内按customer_id分桶,建表语句如下:
CREATE TABLE sales ( order_id INT, customer_id INT, amount DECIMAL(10, 2) ) PARTITIONED BY (order_date STRING) CLUSTERED BY (customer_id) INTO 16 BUCKETS; |
这样,查询时既能利用分区快速定位到相关日期的数据,又能利用分桶提高连接等操作的效率,进一步提升了查询性能和数据处理的灵活性。例如,在分析不同日期不同客户的销售数据时,这种方式能快速准确地获取所需数据,满足复杂的数据分析需求。通过合理使用分区和分桶技术,可以有效优化 Hive 的数据存储和查询性能,提高大数据处理的效率。
三、数据操作语言(DML)深入
3.1 高效的数据加载
在 Hive 中,数据加载是将数据导入到 Hive 表的重要操作,不同的数据加载方式适用于不同的场景,了解它们的差异和适用场景,能帮助我们更高效地处理数据。
LOAD DATA:这是最常用的数据加载方式,语法为LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]。LOCAL关键字表示从本地文件系统导入数据,若不指定,则从 HDFS 文件系统导入,此时是文件的移动操作,类似剪切。OVERWRITE关键字表示执行数据覆盖操作,原有数据会被全部覆盖(若是分区表,则覆盖指定分区);若不指定,则执行数据追加操作,原有数据不会被覆盖。比如,有一个本地的 CSV 文件employees.csv,内容如下:
1,Alice,30,HR 2,Bob,25,Engineering 3,Charlie,35,Sales |
创建一个 Hive 表并加载该文件的语句如下:
CREATE TABLE employees ( id INT, name STRING, age INT, department STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE; LOAD DATA LOCAL INPATH '/path/to/employees.csv' INTO TABLE employees; |
LOAD DATA方式适合将大量的本地文件或 HDFS 文件快速加载到 Hive 表中,因为它直接移动或复制文件,不进行数据解析和转换,效率较高。但使用时需注意,它不会检查表的字段,若文件中的字段多了,会自动舍去,少了则会使用 NULL 填充,所以在使用前需确保对表结构和文件数据非常熟悉。
INSERT INTO:用于将查询结果插入到 Hive 表中,语法为INSERT INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] SELECT ...。例如,有两个表source_table和target_table,将source_table中的数据插入到target_table中的语句如下:
CREATE TABLE source_table ( id INT, name STRING, age INT, department STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE; CREATE TABLE target_table ( id INT, name STRING, age INT, department STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE; INSERT INTO TABLE target_table SELECT * FROM source_table; |
INSERT INTO适用于将一个表的查询结果插入到另一个表中,或者将复杂查询的结果保存到表中。与LOAD DATA不同,它允许从一个表动态地导入数据,并且可以在插入过程中对数据进行处理和转换,比如进行字段计算、过滤等操作。但由于它会对查询结果进行处理,所以在处理大规模数据时,性能可能不如LOAD DATA。
CREATE TABLE AS SELECT (CTAS):通过查询结果创建新表并插入数据,语法为CREATE TABLE new_table AS SELECT ...。假设已有source_table,希望根据查询结果创建一个新表new_table,包含source_table中年龄大于 30 的记录,语句如下:
CREATE TABLE source_table ( id INT, name STRING, age INT, department STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE; CREATE TABLE new_table AS SELECT id, name, age FROM source_table WHERE age > 30; |
CTAS适用于根据特定的查询结果创建新表,并将结果数据存储到新表中。它在创建新表时,会根据查询结果自动推断表的结构,无需手动指定列的数据类型等信息,使用起来非常方便。不过,由于它会创建新表,所以在数据量较大时,会占用较多的存储空间。
在实际应用中,选择合适的数据加载方式至关重要。若要加载大量的本地文件或 HDFS 文件,且对数据处理要求不高,可优先使用LOAD DATA;若需要将查询结果保存到表中,或对数据进行处理和转换后再插入,可使用INSERT INTO;若要根据查询结果创建新表并存储数据,则CREATE TABLE AS SELECT是较好的选择。同时,为了提高数据加载的效率,还可以采取一些优化措施,如在加载数据前对数据文件进行预处理,确保数据格式正确、字段匹配,避免数据加载过程中的错误和性能损耗。合理使用这些数据加载方式,能有效提升 Hive 数据处理的效率和灵活性。
3.2 灵活的数据更新与删除
在传统数据库中,数据更新(UPDATE)和删除(DELETE)操作是非常常见且方便的,可直接使用UPDATE和DELETE语句对数据进行修改和删除。但 Hive 在默认情况下,由于其基于 Hadoop 的架构和 HDFS 的特性(一次写入,多次读取),对数据更新和删除操作的支持相对有限,实现方式与传统数据库有所不同。
Hive 的数据更新操作:Hive 从 0.14 版本开始支持事务和行级更新,但默认是不支持的,需要进行一些附加配置。要使 Hive 支持行级insert、update、delete,需配置 Hive 支持事务。具体配置如下:
<property> <name>hive.support.concurrency</name> <value>true</value> </property> <property> <name>hive.exec.dynamic.partition.mode</name> <value>nonstrict</value> </property> <property> <name>hive.txn.manager</name> <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value> </property> <property> <name>hive.compactor.initiator.on</name> <value>true</value> </property> <property> <name>hive.compactor.worker.threads</name> <value>1</value> </property> |
并且,要执行Update的表需满足特定语法要求:建表时必须带有buckets(分桶)属性;需指定格式,目前只支持ORCFileformat和AcidOutputFormat;建表时必须指定参数('transactional' = true)。例如,创建一个支持更新操作的表:
CREATE TABLE t2 ( id INT, name STRING ) PARTITIONED BY (country STRING, state STRING) CLUSTERED BY (id) INTO 8 BUCKETS STORED AS ORC TBLPROPERTIES ('transactional' = 'true'); |
然后可以进行更新操作,如UPDATE t2 SET name='张' WHERE id=1;。不过,Hive 的更新机制速度相对较慢,在小数据集上更新也可能需要分钟级别,在大数据量场景下,性能问题更为突出,基本上处于不太可用的状态。在实际应用中,若要更新数据,一种常用的替代方法是将要更新的数据导出到一个新表,然后将更新后的数据再导入原表。例如:
-- 创建一个新表来存放更新后的数据 CREATE TABLE new_table ( id INT, name STRING, age INT ); -- 更新数据,假设更新id为1的数据 INSERT OVERWRITE TABLE new_table SELECT id, 'new_name', age FROM original_table WHERE id = 1; -- 将更新后的数据导入原表 INSERT OVERWRITE TABLE original_table SELECT nt.id, nt.name, nt.age FROM new_table nt LEFT JOIN original_table ot ON nt.id = ot.id; |
Hive 的数据删除操作:同样,在配置好事务支持后,可以使用DELETE语句进行删除操作,如DELETE FROM t2 WHERE name='李四';。但与更新操作类似,直接使用DELETE语句在大数据量下性能不佳。通常也采用类似的间接方法来实现删除功能,即创建一个新表,将要保留的数据插入新表,然后用新表数据覆盖原表数据。例如:
-- 创建一个新表来存放要保留的数据 CREATE TABLE new_table ( id INT, name STRING, age INT ); -- 删除数据,假设删除id为1的数据 INSERT OVERWRITE TABLE new_table SELECT id, name, age FROM original_table WHERE id <> 1; -- 将新表数据导入原表 INSERT OVERWRITE TABLE original_table SELECT nt.id, nt.name, nt.age FROM new_table nt; |
适用场景:尽管 Hive 原生的更新和删除操作存在性能上的不足,但在一些特定场景下仍有应用价值。在流式接收数据场景中,事务支持可获得数据的一致性视图,避免产生过多小文件给 NameNode 造成压力;在缓慢变化维场景中,如维度表随时间缓慢变化,可使用行级更新操作;在数据重述场景中,当发现数据集合有错误需要更正,或业务规则需要根据后续事务重述特定事务时,也可使用更新和删除操作。而在大数据量的常规数据处理中,通过导出数据到新表再导入的间接方式,虽然操作繁琐,但能在一定程度上满足数据更新和删除的需求,也是目前较为可行的解决方案。
四、Hive 函数高级应用
4.1 内置函数的巧用
Hive 提供了丰富的内置函数,涵盖日期、字符串、数学等多个领域,熟练掌握这些函数的高级用法,能在复杂业务场景中高效处理数据。
日期函数:在处理时间序列数据时,日期函数非常实用。current_date()用于获取当前日期,格式为yyyy-MM-dd;current_timestamp()则返回当前系统时间,精确到毫秒,格式为yyyy-MM-dd HH:mm:ss。例如,在电商业务中,要统计每天的订单数量,可结合current_date()和group by语句实现:
SELECT current_date() AS today, COUNT(*) AS order_count FROM orders GROUP BY current_date(); |
unix_timestamp([STRING timestamp [, STRING pattern]])函数返回时间对应的 Unix 时间戳(即距离1970-01-01 00:00:00的秒数),若不传入参数则返回当前时间的 Unix 时间戳。与之对应的from_unixtime(BIGINT unixtime [, STRING format])函数将 Unix 时间戳转换为指定格式的时间。比如,将时间戳1609459200转换为yyyy-MM-dd格式的日期:
SELECT from_unixtime(1609459200, 'yyyy-MM-dd'); |
date_add(DATE startdate, INT days)和date_sub(DATE startdate, INT days)分别用于对时间按天做加减,datediff(STRING enddate, STRING startdate)用于计算两个时间相差的天数。在分析用户活跃周期时,可能会用到这些函数,如计算用户首次登录和最近一次登录的时间间隔:
SELECT user_id, datediff(max(last_login_time), min(first_login_time)) AS active_days FROM user_login_log GROUP BY user_id; |
字符串函数:字符串函数在处理文本数据时不可或缺。concat(string A, string B…)用于拼接字符串,concat_ws(string SEP, string A, string B…)则在拼接时可指定分隔符。例如,将用户的姓和名拼接成完整姓名,并以空格分隔:
SELECT concat_ws(' ', first_name, last_name) AS full_name FROM users; |
substr(string A, int start, int len)用于截取字符串,从指定位置start开始,截取长度为len的子串。在处理 URL 时,可能需要截取特定部分,如从https://www.example.com/path/to/page中截取路径部分:
SELECT substr('https://www.example.com/path/to/page', 20); |
regexp_replace(string x, string y, string z)用于替换字符串中的指定字段,将字符串x中的y替换为z。比如,将文本中的敏感词替换为***:
SELECT regexp_replace('This is a secret message', 'secret', '***') AS censored_message; |
数学函数:数学函数在数值计算和统计分析中发挥重要作用。round(double a, int d)用于对数字进行四舍五入,保留d位小数。在计算商品平均价格时,可使用该函数保留两位小数:
SELECT round(AVG(price), 2) AS average_price FROM products; |
ceil(double a)和floor(double a)分别用于向上取整和向下取整。例如,在计算订单数量时,若要确保订单数量为整数,可使用ceil函数:
SELECT ceil(SUM(quantity)) AS total_quantity FROM order_items; |
power(double a, int n)用于求指定a的n次方。在计算复利时,会用到该函数,假设年利率为r,存款年限为n,初始本金为P,计算最终本息和:
SELECT P * power((1 + r), n) AS final_amount FROM investment; |
4.2 自定义函数(UDF)开发
当 Hive 内置函数无法满足业务需求时,就需要开发自定义函数(UDF)。下面以 Java 语言为例,讲解 UDF 的开发步骤。
创建 Java 类:首先,创建一个 Maven 项目,并在pom.xml文件中添加 Hive 和 Hadoop 相关依赖,以便在项目中使用 Hive 的 API。例如:
<dependencies> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>3.1.2</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>3.3.1</version> </dependency> </dependencies> |
然后,创建一个继承自org.apache.hadoop.hive.ql.exec.UDF的 Java 类,并重写evaluate方法。例如,开发一个将字符串转为大写的 UDF:
package com.example.udf; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; public class StringToUpper extends UDF { public Text evaluate(Text input) { if (input == null) { return null; } return new Text(input.toString().toUpperCase()); } } |
打包部署:在项目根目录下执行mvn clean package命令,将项目打包成 JAR 文件。将生成的 JAR 文件上传到 Hive 服务器上。可以使用hdfs dfs -put命令将 JAR 文件上传到 HDFS 上,如:
hdfs dfs -put /local/path/to/your-udf.jar /hive/udf/ |
在 Hive 中使用:在 Hive 客户端中,使用add jar命令将上传的 JAR 文件添加到 Hive 的类路径中,如:
add jar hdfs:///hive/udf/your-udf.jar; |
接着,使用CREATE TEMPORARY FUNCTION语句创建临时函数,将 Java 类与 Hive 函数关联起来,如:
CREATE TEMPORARY FUNCTION string_to_upper AS 'com.example.udf.StringToUpper'; |
现在就可以在 Hive 查询中使用自定义函数了,例如:
SELECT string_to_upper('hello world') AS upper_string; |
若要创建永久函数,可使用CREATE FUNCTION语句,并指定 JAR 文件的 HDFS 路径,如:
CREATE FUNCTION my_db.string_to_upper AS 'com.example.udf.StringToUpper' USING JAR 'hdfs:///hive/udf/your-udf.jar'; |
解决特定业务问题:以解析 JSON 数据为例,假设 Hive 表中存储的是 JSON 格式的用户信息,需要提取其中的某个字段。Hive 内置的get_json_object函数每次只能返回一个数据项,若要提取多个字段,使用起来不太方便。此时,可以开发一个自定义 UDF 来解析 JSON 数据。例如:
package com.example.udf; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; import org.json.JSONObject; public class JsonExtractor extends UDF { public Text evaluate(Text jsonText, Text field) { if (jsonText == null || field == null) { return null; } try { JSONObject jsonObject = new JSONObject(jsonText.toString()); return new Text(jsonObject.getString(field.toString())); } catch (Exception e) { return null; } } } |
按照上述步骤打包部署并在 Hive 中创建函数后,就可以使用该 UDF 提取 JSON 数据中的字段了,如:
SELECT json_extractor(json_data, 'name') AS user_name FROM user_info_table; |
通过开发和使用自定义函数,能够根据具体业务需求,灵活扩展 Hive 的功能,解决复杂的数据处理问题。
五、查询优化技巧
5.1 查询语句优化
在 Hive 查询中,全表扫描和笛卡尔积是常见的导致查询性能低下的问题,深入理解它们并掌握优化策略至关重要。
5.1.1 全表扫描问题
全表扫描是指在查询时对整个表的数据进行遍历读取,这在数据量较大时会消耗大量的时间和资源。例如,有一个包含数十亿条记录的销售记录表sales,表结构如下:
CREATE TABLE sales ( id INT, order_date STRING, customer_id INT, product_id INT, amount DECIMAL(10, 2) ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE; |
若执行简单的查询语句SELECT * FROM sales;,Hive 会对sales表进行全表扫描,读取每一条记录,这在大数据量下效率极低。
优化策略:
a. 添加过滤条件:在WHERE子句中添加过滤条件,可显著减少扫描的数据量。比如查询 2023 年 10 月的销售记录,可使用SELECT * FROM sales WHERE order_date BETWEEN '2023-10-01' AND '2023-10-31';,这样 Hive 只会扫描符合日期条件的记录,大大提高查询效率。
b. 使用分区表:如前文所述,按order_date对sales表进行分区,查询时 Hive 只需扫描指定日期分区的数据。例如:
CREATE TABLE sales ( id INT, customer_id INT, product_id INT, amount DECIMAL(10, 2) ) PARTITIONED BY (order_date STRING); |
查询时SELECT * FROM sales WHERE order_date = '2023-10-01';,Hive 仅扫描order_date为2023-10-01的分区,避免了全表扫描。
c. 利用索引:虽然 Hive 的索引机制不像传统关系数据库那样强大,但在特定场景下仍可提高查询性能。在频繁查询的列上创建索引,如对customer_id列创建索引:
CREATE INDEX idx_customer_id ON TABLE sales (customer_id); |
这样在查询特定customer_id的销售记录时,可利用索引快速定位数据,减少扫描范围。
5.1.2 笛卡尔积问题
笛卡尔积是指在查询时,将两个或多个表的每一行进行组合,产生的结果集行数是各个表行数的乘积,这会导致数据量急剧膨胀,查询效率极低。例如,有两个表customers和orders,表结构如下:
CREATE TABLE customers ( customer_id INT, customer_name STRING, address STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE; CREATE TABLE orders ( order_id INT, customer_id INT, order_date STRING, amount DECIMAL(10, 2) ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE; |
若执行错误的查询语句SELECT * FROM customers, orders;,Hive 会生成笛卡尔积,假设customers表有 1000 条记录,orders表有 500 条记录,那么结果集将有 500,000 条记录,处理如此庞大的结果集将耗费大量资源。
优化策略:
a. 添加关联条件:在JOIN操作中,确保添加正确的关联条件,避免生成笛卡尔积。正确的查询应该是SELECT * FROM customers JOIN orders ON customers.customer_id = orders.customer_id;,这样 Hive 会根据关联条件进行连接操作,而不是生成笛卡尔积。
b. 小表驱动大表:当一个小表和一个大表进行JOIN时,使用小表驱动大表的方式,可减少数据传输和处理的开销。例如:
SELECT /*+ MAPJOIN(customers) */ * FROM orders JOIN customers ON orders.customer_id = customers.customer_id; |
这里使用MAPJOIN提示,将customers小表加载到内存中,在Map阶段就完成连接操作,避免在Reduce阶段进行大规模的数据传输和处理,提高查询效率。
c. 避免不必要的JOIN:仔细检查查询需求,避免进行不必要的表连接操作,减少数据处理量。若只需要orders表的部分数据,就无需与customers表进行连接,直接查询orders表即可,如SELECT order_id, order_date, amount FROM orders;。
5.2 执行计划分析
在 Hive 中,使用EXPLAIN命令可以查看查询执行计划,这对于理解查询的执行过程和优化查询性能非常有帮助。
使用EXPLAIN命令:EXPLAIN命令的基本语法为EXPLAIN [EXTENDED|CBO|AST|DEPENDENCY|AUTHORIZATION|LOCKS|VECTORIZATION|ANALYZE] query,其中query是要分析的 Hive 查询语句,EXTENDED等参数是可选的,用于显示不同类型的详细信息。例如,对于查询语句SELECT * FROM sales WHERE order_date = '2023-10-01';,使用EXPLAIN命令查看执行计划:
EXPLAIN SELECT * FROM sales WHERE order_date = '2023-10-01'; |
执行上述命令后,会输出查询的执行计划信息,主要包括以下几个部分:
抽象语法树(部分版本已移除,可使用单独命令查看):展示查询语句的语法结构,帮助理解查询的逻辑组成。
Stage Dependencies:各个阶段之间的依赖关系,显示查询执行过程中不同阶段的先后顺序和依赖情况。例如,可能存在多个Stage,Stage-1可能依赖Stage-2,表示Stage-2必须先执行完成,Stage-1才能开始执行。
Stage Plan:各个阶段的执行计划,详细描述每个阶段的具体操作,如Map Operator Tree和Reduce Operator Tree中的操作。Map Operator Tree描述Map阶段的操作,Reduce Operator Tree描述Reduce阶段的操作。
解读执行计划各部分含义:
TableScan:表扫描操作,通常是Map端的第一个操作,用于读取表中的数据。alias表示表的别名,Statistics包含表的统计信息,如数据行数、数据大小等。
Select Operator:选取操作,用于选择查询结果中的列。expressions表示选取的列及其数据类型,outputColumnNames表示输出的列名称。
Filter Operator:过滤操作,根据predicate中的条件对数据进行过滤。例如,predicate: (order_date = '2023-10-01')表示根据order_date等于2023-10-01的条件进行过滤。
Group By Operator:分组聚合操作,aggregations显示聚合函数信息,如sum、count等,keys表示分组的列。
Join Operator:连接操作,condition map表示连接方式(如InnerJoin、LeftJoin等),keys表示连接条件字段,outputColumnNames表示连接后输出的字段。
根据执行计划优化查询:通过分析执行计划,可以发现查询中的性能瓶颈,并针对性地进行优化。如果执行计划中显示存在全表扫描,可通过添加过滤条件、使用分区表或索引等方式进行优化。若执行计划中Join操作的Map和Reduce阶段数据量过大,可考虑使用MapJoin优化,将小表加载到内存中进行连接。例如,对于一个包含多个表连接的复杂查询,执行计划显示在Reduce阶段出现数据倾斜,导致查询性能低下。进一步分析发现,是由于连接键分布不均匀造成的。此时,可以通过调整连接顺序,将数据分布较均匀的表放在前面进行连接,或者对连接键进行预处理,如对空值赋予随机值,使其分布更均匀,从而优化查询性能。通过深入分析执行计划,能更好地理解 Hive 查询的执行过程,找到性能瓶颈,采取有效的优化措施,提高查询效率。
六、Hive 高级特性
6.1 ACID 与事务支持
在大数据处理领域,随着应用场景的不断拓展,对数据一致性和事务处理的需求日益增长。Hive 从 0.13 版本之后开始支持 ACID 事务特性,并在后续版本中逐步完善,这使得 Hive 在处理数据时能够更好地满足复杂业务场景的要求。
ACID 是数据库事务正确执行的四个基本要素的缩写,分别代表原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。在 Hive 中,这些特性的实现对于保证数据的可靠性和一致性至关重要。
原子性:确保每个事务都是一个原子操作,要么完全执行,要么完全不执行。Hive 通过使用事务日志(如 HDFS 的事务文件和合并文件)来支持原子性,确保所有变更要么全部成功,要么全部失败。例如,在一个包含多条插入语句的事务中,如果其中一条插入语句失败,整个事务将回滚,不会有部分数据被插入到表中。
一致性:保证事务执行前后,数据库的状态始终是有效的,并且符合定义的约束条件。Hive 通过事务日志、数据的校验以及约束条件(如 PRIMARY KEY 等)来实现一致性。事务操作必须在数据表中定义合适的字段来进行完整性检查。比如,在一个订单表中,订单金额必须大于 0,当执行更新订单金额的事务时,Hive 会检查新的金额是否符合这个约束条件,若不符合则事务不会提交,从而保证数据的一致性。
隔离性:确保在多个并发事务的情况下,每个事务的执行结果对其他事务不可见,直到事务提交。Hive 通过在底层使用行级锁和分布式锁(如 HBase 或其他支持事务的存储系统)来确保隔离性。Hive 事务的隔离级别默认为 READ COMMITTED,这意味着一个事务只能看到已提交事务的结果。例如,当多个用户同时对一个用户信息表进行更新操作时,每个用户的事务在提交前,其他用户无法看到其修改的内容,避免了数据的不一致和干扰。
持久性:确保一旦事务提交,其结果就永久保存,即使系统发生崩溃,数据也不会丢失。Hive 的持久性是通过将事务日志记录到 HDFS 中来实现的。即便发生硬件故障,日志文件可以帮助恢复数据。比如,当一个事务成功提交后,相关的事务日志会被写入 HDFS,即使此时服务器突然断电,在恢复后也可以根据日志文件将数据恢复到事务提交后的状态。
Hive 事务支持适用于多种场景。在流式接收数据场景中,许多用户使用如 Apache Flume、Apache Storm 或 Apache Kafka 等工具将流数据灌入 Hadoop 集群。当这些工具以每秒数百行的频率写入时,Hive 也许只能每 15 分钟到 1 小时添加一个分区,因为过于频繁地添加分区很快就会使一个表中的分区数量难以维护。而且这些工具还可能向已存在的分区中写数据,但是这样将会产生脏读(可能读到查询开始时间点以后写入的数据),还在这些分区的所在目录中遗留大量小文件,进而给 NameNode 造成压力。在这个使用场景下,事务支持可以获得数据的一致性视图同时避免产生过多的文件。在缓慢变化维场景中,在一个典型的星型模式数据仓库中,维度表随时间的变化很缓慢。例如,一个零售商开了一家新商店,需要将新店数据加到商店表,或者一个已有商店的营业面积或其它需要跟踪的特性改变了。这些改变会导致插入或修改个别记录,从 0.14 版本开始,Hive 支持行级更新,能够很好地满足这种需求。
要启用 Hive 的事务支持,需要进行一系列配置。在 hive-site.xml 中添加以下配置,启用事务支持:
<property> <name>hive.support.concurrency</name> <value>true</value> <description>Enable support for ACID transactions in Hive.</description> </property> <property> <name>hive.enforce.bucketing</name> <value>true</value> <description>Enforce bucketing for ACID tables.</description> </property> <property> <name>hive.exec.dynamic.partition.mode</name> <value>nonstrict</value> <description>Allow dynamic partitioning in transactions.</description> </property> <property> <name>hive.txn.manager</name> <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value> <description>Specify the transaction manager for Hive (DbTxnManager supports transactions).</description> </property> <property> <name>hive.compactor.initiator.on</name> <value>true</value> <description>Enable the compaction process for ACID tables.</description> </property> <property> <name>hive.compactor.worker.threads</name> <value>1</value> <description>Number of threads used for compaction of tables.</description> </property> <property> <name>hive.acid.output.format</name> <value>org.apache.hadoop.hive.ql.io.AcidOutputFormat</value> <description>Enable acid output format for transactional tables.</description> </property> |
Hive 的 ACID 事务只支持 ORC(Optimized Row Columnar)格式的表。因此,创建支持 ACID 事务的表时,需要指定 STORED AS ORC,例如:
CREATE TABLE transaction_table ( id INT, name STRING, amount DOUBLE ) CLUSTERED BY (id) INTO 4 BUCKETS STORED AS ORC TBLPROPERTIES ('transactional' = 'true'); |
Hive 的事务支持与传统数据库事务存在一些异同。相同点在于,两者都遵循 ACID 原则,致力于保证数据的一致性、完整性和可靠性。不同点则较为明显,传统数据库通常基于单机或小型集群架构,其事务处理能力强大,能高效处理大量并发事务,并且支持复杂的事务嵌套和回滚操作。而 Hive 构建于 Hadoop 分布式架构之上,主要面向大数据批处理,虽然引入了 ACID 特性,但事务处理性能相对较弱,不太适合高并发的实时事务处理场景。在处理复杂事务时,传统数据库有着成熟的并发控制机制和高效的存储引擎支持,而 Hive 在事务处理过程中,由于涉及分布式存储和计算,会产生较高的网络开销和延迟。不过,Hive 的优势在于其能够处理海量数据,通过分布式计算框架实现数据的并行处理,在大数据分析领域有着广泛的应用。
6.2 Hive on Tez/Spark
在 Hive 的生态系统中,执行引擎的选择对查询性能和资源利用有着至关重要的影响。Tez 和 Spark 作为两种高效的执行引擎,与 Hive 的集成能够显著提升 Hive 的性能和功能。
6.2.1 Hive 与 Tez 集成
Tez 是一个基于 Hadoop YARN 的分布式计算框架,它对 MapReduce 进行了优化,旨在提供更高效、更灵活的计算模型。Hive 与 Tez 集成后,能够充分利用 Tez 的优势,提升查询执行效率。
优势:Tez 允许更细粒度的任务划分和更灵活的任务依赖关系,能够优化复杂查询的执行计划。在一个包含多个 JOIN 和聚合操作的复杂查询中,Tez 可以根据数据的特点和查询逻辑,将任务进行合理拆分和调度,避免不必要的中间数据传输和计算,从而大大提高查询性能。Tez 在处理复杂 SQL 时,内部翻译 SQL 能实现任意的 Map、Reduce、Reduce 组合,而 MapReduce 只能 Map-Reduce-Map-Reduce,因此 Tez 在执行复杂 SQL 时优势明显。Tez 在执行查询时,还能提供动态的进度指示,让用户更直观地了解查询的执行状态。
配置和使用方法:要将 Hive 配置为使用 Tez 作为执行引擎,需要在 hive-site.xml 中进行相应配置。添加以下配置:
<property> <name>hive.execution.engine</name> <value>tez</value> </property> |
如果需要指定 Tez 库的位置,还可以添加:
<property> <name>tez.lib.uris</name> <value>hdfs:///path/to/tez.tar.gz</value> </property> |
配置完成后,在 Hive 会话中即可使用 Tez 执行查询。可以通过 SET 语句临时设置执行引擎为 Tez:
SET hive.execution.engine=tez; |
然后执行查询,如:
SELECT * FROM sales WHERE order_date = '2023-10-01'; |
6.2.2 Hive 与 Spark 集成
Spark 是一个快速、通用的数据处理引擎,具有内存计算的特性,能够显著提升数据处理的速度。Hive 与 Spark 集成后,用户可以利用 Spark 的高性能计算能力来执行 Hive 查询。
优势:Spark 的内存计算特性使得数据可以在内存中进行处理,避免了频繁的磁盘 I/O 操作,大大提高了查询的响应速度。在进行实时数据分析时,Spark 能够快速处理大量数据,并及时返回结果,满足实时性要求。Spark 还支持多种编程语言,如 Scala、Java、Python 等,这使得开发者可以根据自己的需求选择合适的语言进行开发。
配置和使用方法:配置 Spark 以使用 Hive,首先要确保系统中安装了 Hadoop、Hive 和 Spark。然后设置 Hadoop 和 Hive 环境变量,例如:
export HADOOP_HOME=/path/to/hadoop export HIVE_HOME=/path/to/hive export SPARK_HOME=/path/to/spark |
在 Spark 的 conf/spark-defaults.conf 中添加 Hive 支持的配置,如:
spark.sql.hive.metastore.version=1.2.1 spark.sql.hive.metastore.jars=local spark.sql.hive.thriftServer=off |
如果使用 SparkSession,可以通过以下方式启用 Hive 支持:
from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("Spark Hive Example") \ .config("spark.sql.warehouse.dir", "/path/to/spark-warehouse") \ .enableHiveSupport() \ .getOrCreate() |
然后就可以使用 Spark 执行 Hive 查询,如:
df = spark.sql("SELECT * FROM employee") df.show() |
不同执行引擎性能对比:在实际应用中,Tez 和 Spark 在性能上各有优势。Tez 在处理复杂查询时,通过优化任务调度和执行计划,能够有效减少中间数据的传输和计算,提高查询效率。而 Spark 由于其内存计算的特性,在处理迭代计算和实时查询时表现出色。例如,在一个需要多次迭代计算的机器学习算法应用中,Spark 可以将中间结果保存在内存中,避免了重复读取磁盘数据,大大加快了计算速度。而在处理复杂的 ETL 任务,涉及多个表的复杂关联和聚合操作时,Tez 可能会因为其灵活的任务调度和执行计划优化,展现出更好的性能。在选择执行引擎时,需要根据具体的业务场景和数据特点进行评估和选择。如果业务以复杂的批处理查询为主,Tez 可能是更好的选择;如果需要进行实时数据分析或迭代计算,Spark 则更具优势。
七、实战案例分析
7.1 电商数据分析案例
在电商领域,海量的交易数据蕴含着丰富的商业价值,Hive 作为强大的数据处理工具,能够高效地对这些数据进行分析,为企业决策提供有力支持。以下以一个电商数据为例,展示 Hive 在实际业务中的应用,包括数据清洗、指标计算和报表生成。
假设我们有一份电商交易数据,存储在 HDFS 上的文件中,数据包含以下字段:order_id(订单 ID)、user_id(用户 ID)、product_id(产品 ID)、order_date(订单日期)、quantity(购买数量)、price(产品单价)、payment_amount(支付金额)。
数据清洗:原始数据中可能存在各种问题,如数据缺失、重复记录、异常值等,需要进行清洗。首先,检查数据完整性,删除包含空值的记录。在 Hive 中,可以使用如下语句:
-- 创建一个新表用于存储清洗后的数据 CREATE TABLE clean_orders AS SELECT * FROM raw_orders WHERE order_id IS NOT NULL AND user_id IS NOT NULL AND product_id IS NOT NULL AND order_date IS NOT NULL AND quantity IS NOT NULL AND price IS NOT NULL AND payment_amount IS NOT NULL; |
然后,检查并删除重复记录,可根据order_id判断记录是否重复 :
-- 创建临时表存储去重后的数据 CREATE TABLE temp_orders AS SELECT DISTINCT * FROM clean_orders; -- 用临时表覆盖原表,完成去重 DROP TABLE clean_orders; ALTER TABLE temp_orders RENAME TO clean_orders; |
还要处理异常值,如quantity和price不能为负数。对于quantity为负数的情况,可以将其设置为 0(假设是数据录入错误导致):
UPDATE clean_orders SET quantity = CASE WHEN quantity < 0 THEN 0 ELSE quantity END; |
对于price为负数的情况,同样可以将其设置为 0 :
UPDATE clean_orders SET price = CASE WHEN price < 0 THEN 0 ELSE price END; |
指标计算:清洗数据后,可计算各种业务指标。
计算每日订单总数:
SELECT order_date, COUNT(*) AS order_count FROM clean_orders GROUP BY order_date; |
计算每个用户的总购买金额:
SELECT user_id, SUM(payment_amount) AS total_payment FROM clean_orders GROUP BY user_id; |
计算每个产品的销售总量:
SELECT product_id, SUM(quantity) AS total_quantity FROM clean_orders GROUP BY product_id; |
报表生成:为了更直观地展示数据分析结果,可将指标数据生成报表。假设要生成每日订单统计报表,以 CSV 格式保存到 HDFS 上。首先,使用 Hive 查询获取每日订单统计数据:
SELECT order_date, COUNT(*) AS order_count FROM clean_orders GROUP BY order_date; |
然后,通过 Hive 的INSERT OVERWRITE DIRECTORY语句将查询结果导出为 CSV 文件 :
INSERT OVERWRITE DIRECTORY '/user/hive/warehouse/reports/daily_orders' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' SELECT order_date, COUNT(*) AS order_count FROM clean_orders GROUP BY order_date; |
可以使用一些工具(如 Sqoop)将 HDFS 上的报表文件导出到关系数据库(如 MySQL)中,以便在其他系统中进行展示和分析。例如,使用 Sqoop 将 Hive 报表数据导出到 MySQL 的daily_orders_report表中:
sqoop export \ --connect jdbc:mysql://your_mysql_host:3306/your_database \ --username your_username \ --password your_password \ --table daily_orders_report \ --export-dir /user/hive/warehouse/reports/daily_orders \ --fields-terminated-by ','; |
7.2 日志分析案例
网站日志记录了用户在网站上的各种行为,通过对这些日志数据的分析,可以深入了解用户行为,优化网站性能和用户体验。以下以网站日志分析为例,讲解如何使用 Hive 进行日志数据处理和用户行为分析。
假设网站日志数据存储在 HDFS 上,日志格式为每行记录包含timestamp(时间戳)、user_id(用户 ID)、ip_address(IP 地址)、page_url(页面 URL)、action(用户行为,如点击、浏览、购买等)。
数据清洗:原始日志数据可能存在格式不一致、非法字符等问题,需要清洗。使用 Hive 的正则表达式函数regexp_replace清洗page_url中的非法字符。假设page_url中可能包含特殊字符$,需要将其去除:
-- 创建清洗后的日志表 CREATE TABLE clean_logs AS SELECT timestamp, user_id, ip_address, regexp_replace(page_url, '\\$', '') AS page_url, action FROM raw_logs; |
还可以过滤掉无效的日志记录,如action字段为空的记录 :
-- 再次过滤,去除action为空的记录 CREATE TABLE final_clean_logs AS SELECT * FROM clean_logs WHERE action IS NOT NULL AND action != ''; |
用户行为分析:利用清洗后的数据进行用户行为分析。
分析用户在一天中不同时间段的访问量:
SELECT hour(from_unixtime(timestamp)) AS hour_of_day, COUNT(*) AS visit_count FROM final_clean_logs GROUP BY hour(from_unixtime(timestamp)) ORDER BY hour_of_day; |
统计每个用户的页面浏览路径:
SELECT user_id, collect_list(page_url) AS page_path FROM final_clean_logs GROUP BY user_id; |
分析用户的购买转化率:假设购买行为的action值为purchase,先统计每个用户的购买次数和总访问次数 :
SELECT user_id, SUM(CASE WHEN action = 'purchase' THEN 1 ELSE 0 END) AS purchase_count, COUNT(*) AS total_visits FROM final_clean_logs GROUP BY user_id; |
再计算购买转化率 :
SELECT user_id, purchase_count, total_visits, purchase_count / total_visits AS conversion_rate FROM ( SELECT user_id, SUM(CASE WHEN action = 'purchase' THEN 1 ELSE 0 END) AS purchase_count, COUNT(*) AS total_visits FROM final_clean_logs GROUP BY user_id ) subquery; |
通过以上电商数据分析案例和日志分析案例可以看出,Hive 在处理大规模数据时具有强大的能力,能够帮助企业从海量数据中提取有价值的信息,为业务决策提供有力支持。无论是数据清洗、指标计算还是复杂的用户行为分析,Hive 都能通过灵活的 SQL 语句实现,展现出其在大数据分析领域的重要性和实用性。
八、总结与展望
Hive 作为大数据生态系统中的关键数据仓库工具,通过本文对其进阶知识的探索,我们深入了解了从数据定义、操作到函数应用、查询优化以及高级特性和实战案例等多方面的内容。从复杂表创建、分区与分桶优化,到高效的数据加载、灵活的数据更新与删除;从内置函数的巧用、自定义函数开发,到查询语句优化、执行计划分析;再到 ACID 与事务支持、Hive on Tez/Spark 等高级特性,以及电商和日志分析的实战应用,Hive 展现出强大的数据处理和分析能力。
这些进阶知识是提升 Hive 应用能力的关键,在实际工作中,我们应不断实践,将这些知识运用到具体项目中。持续学习和关注 Hive 的发展趋势也至关重要,随着大数据技术的不断演进,Hive 在性能优化、与其他技术的集成等方面不断发展,如 Hive 与人工智能技术的结合,将为数据处理和分析带来更多可能性。希望读者通过本文的学习,能在 Hive 的世界中不断探索,提升自己的大数据处理技能,为大数据领域的发展贡献力量。
相关文章:
Hive进阶之路
目录 一、Hive 基础回顾 二、数据定义语言(DDL)进阶 2.1 复杂表创建 2.2 分区与分桶优化 三、数据操作语言(DML)深入 3.1 高效的数据加载 3.2 灵活的数据更新与删除 四、Hive 函数高级应用 4.1 内置函数的巧用 4.2 自定义…...
imx6uLL应用-v4l2
Linux V4L2 视频采集 JPEG 解码 LCD 显示实践 本文记录一个完整的嵌入式视频处理项目:使用 V4L2 接口从摄像头采集 MJPEG 图像,使用 libjpeg 解码为 RGB 格式,并通过 framebuffer 显示在 LCD 屏幕上。适用于使用 ARM Cortex-A 系列开发板进…...
以太坊智能合约开发框架:Hardhat v2 核心功能从入门到基础教程
一、设置项目 Hardhat 项目是安装了 hardhat 包并包含 hardhat.config.js 文件的 Node.js 项目。 操作步骤: ①初始化 npm npm init -y②安装 Hardhat npm install --save-dev hardhat③创建 Hardhat 项目 npx hardhat init如果选择 Create an empty hardhat.…...
【现代深度学习技术】现代循环神经网络06:编码器-解码器架构
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…...
Jasper and Stella: distillation of SOTA embedding models
摘要 Dense检索是许多深度学习应用系统中(例如常见问题 (FAQ) 和检索增强生成 (RAG))关键组成部分。在此过程中,Embedding模型将原始文本转换为向量。然而,目前在文本Embedding基准…...
程序的本质—API接口
API 是什么 官方定义:API 英文全称 Application Programming Interface,翻译过来为程序之间的接口。也是程序与外部世界的桥梁,实现了服务拆分与解藕的核心机制 大白话:按照规则提供输入,它帮你得到对应的输出 API可…...
Python函数完全指南:从零基础到灵活运用
Python函数是组织代码、实现代码复用的基本单元,也是Python编程中最重要的概念之一。本文将全面介绍Python函数的知识体系,帮助初学者系统掌握函数的使用方法。 一、函数基础概念 1. 什么是函数? 函数是一段可重复使用的代码块,…...
第十章.XML
文章目录 1.XMl简介2.解析XML技术2.1DOM解析XML 2.2DOM4j3.json 1.XMl简介 EXtensible Markup Language ,可扩充标记语言 特点: XML与操作系统,编程语言的开发平台无关实现不同系统之间的数据交换 作用: 数据交互配置应用程序和网站 XML标签 xml文档由一系列标签元素组成<…...
5个情感丰富GPT-4o图像提示词(不是吉卜力风格)
一场新的创意运动正在迅速兴起——人们不仅使用ChatGPT进行写作,还用它来构思富有想象力、情感丰富的视觉概念。 这一趋势正在改变我们讲故事、建立品牌和探索创意的方式。从异想天开的海报世界到基于物品的故事叙述,各行业的创作者正在将ChatGPT与视觉生成工具结合使用,赋…...
华为OD机试真题——求最多可以派出多少支队伍(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录…...
《七年一剑》速读笔记
文章目录 书籍信息概览知己知彼市场的本质认识自我了解他人人剑合一 技术分析精要K线分型均线节奏形态画线成交量周期级别指标之王——MACD波动理论 管窥基本面A股周期论实战角度看财报 构建交易系统打开交易之门交易基础之买卖依据风险控制与仓位管理系统评估及情绪管理 实战秘…...
VMware-centOS7安装redis分布式集群
1.部署redis包 1.1 在usr/local文件夹里创建文件夹 mkdir software 1.2 进入文件夹 cd /usr/local/software/ 下载redis wget http://download.redis.io/releases/redis-6.2.6.tar.gz解压 tar zxvf redis-6.2.6.tar.gz重命名文件夹 mv redis-6.2.6 redis安装gcc编译器 yum i…...
Kubernetes(k8s)学习笔记(六)--KubeSphere前置环境安装
1、安装 helm(master 节点执行) Helm 是 Kubernetes 的包管理器。包管理器类似于我们在 Ubuntu 中使用的apt、Centos 中使用的 yum 或者 Python 中的 pip 一样,能快速查找、下载和安装软件包。Helm由客户端组件 helm 和服务端组件 Tiller 组…...
黑马点评day01(基于Redis)
1.7 Redis代替session的业务流程 1.7.1、设计key的结构 首先我们要思考一下利用redis来存储数据,那么到底使用哪种结构呢?由于存入的数据比较简单,我们可以考虑使用String,或者是使用哈希,如下图,如果使用…...
14.Excel:排序和筛选
一 位置 两个位置。 二 排序:如何使用 1.常规使用 补充:不弹出排序提醒排序。 选中要排序列中的任意一个单元格,然后排序。 2.根据要求进行排序 1.根据姓名笔画进行降序排序 要勾选上数据包含标题,默认是勾选了。 2.根据运营部、…...
力扣-字符串-468 检查ip
思路 考察字符串的使用,还有对所有边界条件的检查 spilt(“\.”),toCharArray,Integer.parseInt() 代码 class Solution {boolean checkIpv4Segment(String str){if(str.length() 0 || str.length() > 4) retur…...
C++名称空间
名称空间 名称空间可以是全局的,也可以位于另一个名称空间中,但不能位于代码块中。因此,在默认情况下,在名称空间中声明的名称的链接性为外部的(除非它引用了常量) 名称空间是开放的,你可以在…...
Redis 过期与淘汰机制全解析
概述 Redis 作为一种高性能的内存数据库,提供了数据过期和淘汰策略以管理存储的数据。本文将详细探讨 Redis 中数据失效的基本原理、实现方式,并结合源码进行分析,帮助读者更深入地理解和优化 Redis 的使用。 数据过期机制 过期键的存储方…...
PMP-第四章 项目整合管理(一)
项目整合管理 项目整合管理包括对项目管理过程组内的各种过程和项目管理活动而进行识别、定义、组合、统一与协调的各种过程和活动项目整合管理必须由项目经理负责。其他知识领域可以由相关领域专家管理,但整合的责任不能被授权或转移项目与项目管理本质上具有整合…...
VSCode搭建STM32开发调试环境
闲言碎语: 好久没更,在忙着科研→校招→写毕业论文。 临近毕业,总结自己的大学生活:C\C、Java、Python、深度学习,学的乱七八糟。 秋招找了个嵌入式工作(涉及AI应用),大致确定了以后…...
【数据结构】稀疏矩阵的快速转置
稀疏矩阵的快速转置 如图给出一个稀疏矩阵,要求表示出它的转置矩阵 由这个矩阵我们能轻松得到它的三元组顺序表 6行(x坐标)7列(y坐标)8个元素121213931-3361443245218611564-7 接下来我们同样把转置后的矩阵的三元组…...
【Godot】使用 Shader 实现可调节的精确切角效果
今天我们要实现的是一个四角精确切割Shader,可以在UI元素或Sprite的四个角分别切割出不同大小的三角形区域。 文章目录 什么是Godot Shader?数学原理详解左上角切割右上角切割右下角切割左下角切割四角切割Shader完整代码使用方法在Godot编辑器中设置通过代码控制进阶技巧1. …...
在CentOS环境中安装MySQL数据库保姆级教程
一.确认当前系统版本 1.1登录系统,切换至root账户 如图所示: 1.2:在终端中执行如下命令查看系统版本 cat /etc/redhat-release 二.添加 MySQL Yum 源 2.1访问MySQL开发者专区 https://dev.mysql.com/downloads/repo/yum/ TIPS: 1.发布包命…...
分布式系统中的 ActiveMQ:异步解耦与流量削峰(二)
四、流量削峰 (一)流量削峰原理深入解析 在当今互联网应用中,高并发场景屡见不鲜 。例如,电商平台的促销活动、在线票务系统的抢票时刻以及社交平台的热点事件爆发期等,都会在短时间内迎来大量用户请求。这些瞬间涌入…...
JAVA设计模式——(十)抽象工厂模式(Abstract Factory Pattern)
JAVA设计模式——(十)抽象工厂模式(Abstract Factory Pattern) 介绍理解实现工厂接口工厂实现类应用类应用类实现测试改造工厂类 应用 介绍 抽象工厂模式在工厂模式的基础上,适配的对象变为一组相关的对象,…...
STM32的定时器
定时器的介绍 介绍:STM32F103C8T6微控制器内部集成了多种类型的定时器,这些定时器在嵌入式系统中扮演着重要角色,用于计时、延时、事件触发以及PWM波形生成、脉冲捕获等应用。 *几种定时器(STM32F103系列)࿱…...
ubuntu-PyQt5安装+PyCharm配置QtDesigner + QtUIC
个人环境 ubuntu22.04 pycharm 2024.3 python 3.10 1)先使用apt命令在线安装 1)sudo apt install pyqt5* 2)sudo apt install qttools5-dev-tools2)Pycharm配置Pycharm External Tool 在设置—工具——外部工具中 配置QtDesigner Name :QtDesigne…...
测试基础笔记第十九天
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、接口的概念二、接口的类型三、接口测试1.概念2.原理:3.特点:4.实现方式:5.什么是自动化接口测试? 二、HTTP协议1.HTTP协议简介2.URL格式…...
Ubuntu 系统上广受好评的浏览器推荐
日常使用与开发者首选 Firefox 特点:开源、隐私保护强大,支持丰富扩展(如开发者工具、广告拦截),默认预装且跨平台兼容368。 适用场景:日常浏览、开发者调试(支持实时 CSS/JS 编辑)、…...
第 13 届蓝桥杯 C++ 青少组省赛中 / 高级组真题解析
一、选择题 第 1 题 题目:下列关于类中声明的变量描述正确的是 ( )。 选项: A. 只属于该类 B. 属于全局变量 C. 任何情况下都可被该类所有实例共享 D. 属于该类,某些情况下也可被该类不同实例所共享 答案:D 解析&…...
Win10下安装Linux-Ubuntu24.04双系统
0 引言 Ubuntu 24.04 LTS(代号“Noble Numbat”)是 Canonical 于 2024 年 4 月 25 日发布的第 10 个长期支持版本,专注于性能优化、企业安全和开发者体验提升 Windows 10 是微软于 2015 年 7 月发布的跨平台操作系统,融合了传统桌…...
express 怎么搭建 WebSocket 服务器
一:使用 express-ws var express require(express); var app express(); var expressWs require(express-ws)(app);app.use(function (req, res, next) {console.log(middleware);req.testing testing;return next(); });app.get(/, function(req, res, next){…...
模型部署——cuda编程入门
CUDA中的线程与线程束 kernel是在device上线程中并行执行的函数,核函数用__global__符号声明,在调用时需要用<<<grid_size, block_size>>>来指定kernel要执行的线程数量。在CUDA中,每一个线程都要执行核函数,并…...
llfc项目TCP服务器笔记
ChatServer 一个TCP服务器必然会有连接的接收,维持,收发数据等逻辑。那我们就要基于asio完成这个服务的搭建。主服务是这个样子的 #include "LogicSystem.h"#include <csignal>#include <thread>#include <mutex>#include "AsioIOServiceP…...
NPP库中libnppi模块介绍
1. libnppi 模块简介 libnppi 是 NPP 库中专门用于 图像处理 的模块,提供高度优化的 GPU 加速函数,支持: 图像滤波(卷积、形态学操作) 几何变换(旋转、缩放、透视变换) 颜色空间转换…...
从头训练小模型: 3 传统RLHF与DPO的区别
这个步骤我其实是忽略了。如果我的目标是建立一个安全领域的模型,我个人理解这步骤并不太必要。关于人类偏好对齐:在前面的训练步骤中,模型已经具备了基本的对话能力。 此时模型还不知道什么是好的回答,什么是不好的回答。我们希…...
Python-Django系列—视图
一、通用显示视图 以下两个基于类的通用视图旨在显示数据。在许多项目中,它们通常是最常用的视图。 1、DetailView class django.views.generic.detail.DetailView 当该视图执行时,self.object 将包含该视图正在操作的对象。 祖先(MRO&a…...
el-input Vue 3 focus聚焦
https://andi.cn/page/622173.html...
动态规划(5)路径问题--剑指offer -珠宝的最大值
题目: 现有一个记作二维矩阵 frame 的珠宝架,其中 frame[i][j] 为该位置珠宝的价值。拿取珠宝的规则为: 只能从架子的左上角开始拿珠宝每次可以移动到右侧或下侧的相邻位置到达珠宝架子的右下角时,停止拿取 注意࿱…...
ZArchiver正版:高效文件管理,完美解压体验
在使用安卓设备的过程中,文件管理和压缩文件的处理是许多用户常见的需求。无论是解压下载的文件、管理手机存储中的文件,还是进行日常的文件操作,一款功能强大且操作简便的文件管理工具都能极大地提升用户体验。今天,我们要介绍的…...
Netlink在SONiC中的应用
Netlink在SONiC中的应用 Netlink介绍 Netlink 是 Linux 内核态程序与用户空间程序之间进行通信的机制之一,原本是用于传递网络协议栈中的各种控制消息。它采用和套接字(socket)编程接口相同的形式,常用于配置内核网络子系统&…...
ReentrantLock实现公平锁和非公平锁
在 Java 里,公平锁和非公平锁是多线程编程中用于同步的两种锁机制,它们的主要差异在于获取锁的顺序规则。下面是对二者的详细介绍: 公平锁 公平锁遵循 “先来先服务” 原则,也就是线程获取锁的顺序和请求锁的顺序一致。先请求锁…...
【C++】 —— 笔试刷题day_25
一、笨小猴 题目解析 这道题,给定一个字符str,让我们找到这个字符串中出现次数最多字母的出现次数maxn和出现次数最少字母的出现次数minn; 然后判断maxn - minn是否是一个质数,如果是就输出Lucky Word和maxn - minn;如…...
terraform resource创建了5台阿里云ecs,如要使用terraform删除其中一台主机,如何删除?
在 Terraform 中删除阿里云 5 台 ECS 实例中的某一台,具体操作取决于你创建资源时使用的 多实例管理方式(count 或 for_each)。以下是详细解决方案: 方法一:使用 for_each(推荐) 如果创建时使…...
Office 三大组件Excel、Word、Access 里 VBA 区别对比
以下是Excel、Word和Access在VBA中的主要区别对比及详细说明: 核心对象模型 Excel Workbook(工作簿)→ Worksheet(工作表)→ Range(单元格区域) 核心围绕单元格数据处理,如 Cells(1,1).Value = "数据" Word Document(文档)→ Range(文本范围)→ Paragrap…...
Linux 进程基础(二):操作系统
目录 一、什么是操作系统:用户和电脑之间的「翻译官」🌐 OS 的层状结构🧩 案例解析:双击鼠标的「跨层之旅」 二、操作系统的必要性探究:缺乏操作系统的环境面临的挑战剖析🔑 OS 的「管理者」属性࿱…...
Java高并发处理核心技术详解:从理论到实战
高并发处理能力是衡量系统性能的重要指标。Java作为企业级开发的主力语言,提供了丰富的并发编程工具和框架。 一、Java并发基础 1.1 Java内存模型(JMM) 主内存与工作内存:每个线程拥有独立的工作内存,通过JMM协议与主…...
单细胞测序数据分析试验设计赏析(二)
单细胞测序数据分析试验设计赏析(二) 这次的单细胞测序数据分析的试验设计是单细胞测序分析机器学习(with SHAP分析),也是常见的试验设计之一,重点是可以用于筛选鉴定基因调控网络,也可以是构建…...
Docker 服务搭建
💢欢迎来到张翊尘的开源技术站 💥开源如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 Docker 服务搭建在 Ubuntu 上安装 Docker更新软件…...
4电池_基于开关电容的均衡
基于开关电容的均衡系统(Switched-Capacitor Equalization System) 开关电容均衡(Switched-Capacitor Equalization, SCE)是一种广泛应用于 电池组(如锂电池、超级电容组) 的主动均衡技术,通过电…...