2017-09-17Hive介绍与实践

Hive的系统架构部署
一.查看执行计划

explain select city_code,count(1) as cnt from user where access='WIFI' group by city_code order by cnt desc limit 5;

这里写图片描述

这里写图片描述

二.MR Job的基本过程

一个InputSplit输入到map,会运行我们实现的Mapper的处理逻辑,对数据进行映射操作。
map输出时,会首先将输出中间结果写入到map自带的buffer中(buffer默认大小为100M,可以通过io.sort.mb配置)。
map自带的buffer使用容量达到一定限制(默认0.80或80%,可以通过io.sort.spill.percent配置),一个后台线程会准备将buffer中的数据写入到磁盘。
这个后台线程在将buffer中数据写入磁盘之前,会首先将buffer中的数据进行partition(分区,partition数为Reducer的个数),对于每个的数据会基于Key进行一个in-memory排序。
排序后,会检查是否配置了Combiner,如果配置了则直接作用到已排序的每个partition的数据上,对map输出进行化简压缩(这样写入磁盘的数据量就会减少,降低I/O操作开销)。

过程图

过程图

现在可以将经过处理的buffer中的数据写入磁盘,生成一个文件(每次buffer容量达到设置的门限,都会对应着一个写入到磁盘的文件)。
map任务结束之前,会对输出的多个文件进行合并操作,合并成一个文件(若map输出至少3个文件,在多个文件合并后写入之前,如果配置了Combiner,则会运行来化简压缩输出的数据,文件个数可以通过min.num.splits.for.combine配置;如果指定了压缩map输出,这里会根据配置对数据进行压缩写入磁盘),这个文件仍然保持partition和排序的状态。
reduce阶段,每个reduce任务开始从多个map上拷贝属于自己partition(map阶段已经做好partition,而且每个reduce任务知道应该拷贝哪个partition;拷贝过程是在不同节点之间,Reducer上拷贝线程基于HTTP来通过网络传输数据)。
每个reduce任务拷贝的map任务结果的指定partition,也是先将数据放入到自带的一个buffer中(buffer默认大小为Heap内存的70%,可以通过mapred.job.shuffle.input.buffer.percent配置),如果配置了map结果进行压缩,则这时要先将数据解压缩后放入buffer中。。
reduce自带的buffer使用容量达到一定门限(默认0.66或66%,可以通过mapred.job.shuffle.merge.percent配置),或者buffer中存放的map的输出的数量达到一定门限(默认1000,可以通过mapred.inmem.merge.threshold配置),buffer中的数据将会被写入到磁盘中。
在将buffer中多个map输出合并写入磁盘之前,如果设置了Combiner,则会化简压缩合并的map输出。

当属于该reducer的map输出全部拷贝完成,则会在reducer上生成多个文件,这时开始执行合并操作,并保持每个map输出数据中Key的有序性,将多个文件合并成一个文件(在reduce端可能存在buffer和磁盘上都有数据的情况,这样在buffer中的数据可以减少一定量的I/O写入操作开销)。

最后,执行reduce阶段,运行我们实现的Reducer中化简逻辑,最终将结果直接输出到HDFS中(因为Reducer运行在DataNode上,输出结果的第一个replica直接在存储在本地节点上)。

三.进阶与分区

使用分区
分区(partition):hive里分区的概念是根据“分区列”的值对表的数据进行粗略划分的机制,在hive存储上就体现在表的主目录(hive的表实际显示就是一个文件夹)下的一个子目录,这个文件夹的名字就是我们定义的分区的名字,没有实际操作经验的人可能会认为分区列是表的某个字段,其实不是这样,分区列不是表里的某个字段,而是独立的列,我们根据这个列存储表的里的数据文件。使用分区是为了加快数据分区的查询速度而设计的,我们在查询某个具体分区列里的数据时候没必要进行全表扫描。
静态分区:静态分区在加载数据和使用时都需要在sql语句中指定

动态分区:使用动态分区需要设置hive.exec.dynamic.partition参数值为true,默认值为false,在默认情况下,hive会假设主分区时静态分区,副分区使用动态分区;如果想都使用动态分区,需要设置set hive.exec.dynamic.partition.mode=nostrick,默认为strick

静态分区使用
静态分区:静态分区在加载数据和使用时都需要在sql语句中指定

//1.建表
CREATE TABLE `user_daily`
(  
  `uid` int,  
  `city_code` int,  
  `model` string,  
  `access` string
)
partitioned by (p_date string);
//2.插入数据
INSERT OVERWRITE TABLE user_daily PARTITION (p_date='2017-09-13') SELECT * FROM user;

动态分区使用

//1.设置参数
set hive.exec.dynamic.partition.mode=nonstrict;

//2.插入数据
INSERT OVERWRITE TABLE user_daily PARTITION (p_date) 
SELECT *,'2017-09-02' FROM user
UNION ALL
SELECT *,'2017-09-03' FROM user;

基于Partition的操作

查看分区情况

show partitions user_daily;

一般 SELECT 查询会扫描整个表(除非是为了抽样查询)。但是如果一个表使用 PARTITIONED BY 子句建表,查询就可以利用分区剪枝(input pruning)的特性,只扫描一个表中它关心的那一部分。Hive 当前的实现是,只有分区断言出现在离 FROM 子句最近的那个WHERE 子句中,才会启用分区剪枝。例如,以下语句只会读取分区为‘2017-09-03’和‘2017-09-04’的数据:

select count(1) 
    from user_daily 
    where p_date>='2017-09-03' and p_date<='2017-09-04';
//修改分区
    ALTER TABLE user_daily PARTITION (p_date='2017-09-03') 
    RENAME TO PARTITION (p_date='20170903');
//删除分区
    alter table user_daily drop partition(p_date='2017-09-04');

进阶:条件判断、汇总

1、IF判断:统计WIFI用户占比

select sum(if(access='WIFI',1,0))/count(1) from user;

2、case when:统计uid尾数0-3、4-7、8-9用户数
……
3、集合collect_list(不去重)、collect_set去重)

 select collect_list(access) from user;  select collect_set(access) from user;

4、map:key/value对
统计user表city_code最多的4个城市的access分布情况,存储为map

进阶:hive 各种 join

1、左连接 left outer join
以左边表为准,逐条去右边表找相同字段,如果有多条会依次列出
2、右连接 left outer join
以左边表为准,逐条去右边表找相同字段,如果有多条会依次列出
3、内连接inner join
找出左右相同同的记录
4、全连接 full outer join
包括两个表的join结果,左边在右边中没找到的结果(NULL),
右边在左边没找到的结果(NULL)

进阶:窗口函数
1、分组topN:每个access下最大city_code的记录

row_number() over (partition by access order by city_code desc) as row_num
<think>好的,我现在要处理用户关于Android 12中RKNN开发配置和使用教程的问题。首先,我需要回顾用户提供的引用内容,看看是否有相关的信息。 用户提供了三个引用。引用1提到了RKNN Model Zoo和RKNN Toolkit2的环境配置,包括安装Miniconda3。引用2是关于系统镜像下载,特别是Ubuntu 22.04版本和导出ONNX模型。引用3讨论了RV1808/1126使用RKNN作为MediaPipe推理后端的步骤,包括配置参数如use_rga、use_mmap和data_type的设置,以及反量化的处理。 用户的问题集中在Android 12上,所以需要将引用中的信息与Android系统关联起来。引用3提到了MediaPipe和RKNN的集成,这可能适用于Android开发,但需要确认是否支持Android 12。此外,RKNN Toolkit2的环境配置可能在不同平台上有所不同,用户可能需要针对Android进行调整。 接下来,我需要考虑Android开发中RKNN的一般步骤,比如环境准备、模型转换、集成到Android应用、配置参数和性能优化。结合引用中的信息,模型转换部分可以参考引用2提到的导出ONNX模型,然后使用RKNN Toolkit转换为RKNN格式。引用3中的配置参数(如use_rga、use_mmap、data_type)可能在Android中同样适用,但需要查阅相关文档确认。 可能还需要指导用户如何将RKNN库集成到Android项目中,比如添加依赖项或NDK配置。此外,性能优化方面,引用3提到的反量化处理可能需要特别注意,尤其是在Android设备上的实现。 最后,确保回答结构清晰,分步骤说明,并引用提供的资料。需要验证引用中的信息是否适用于Android 12,例如系统镜像是否支持,或者是否有特定版本的要求。如果某些步骤在引用中没有明确说明,可能需要提示用户参考官方文档或社区资源。</think>### Android 12 RKNN 开发配置与使用教程 #### 1. **环境准备** - **系统镜像与工具链**: 根据引用[2],建议使用Ubuntu 22.04作为开发环境,并下载Orange Pi 5 Pro等支持RKNN的硬件镜像。对于Android 12开发,需确保RKNN Toolkit2适配Android NDK版本(推荐NDK 21+)[^2]。 - **安装RKNN Toolkit2**: 参考引用[1],通过Miniconda3配置Python环境(建议Python 3.8),并安装RKNN Toolkit2以支持模型转换与推理。命令示例: ```bash pip install rknn_toolkit2 ``` #### 2. **模型转换(ONNX转RKNN)** - **导出ONNX模型**: 使用PyTorch或TensorFlow等框架导出模型为ONNX格式(引用[2])。 - **转换为RKNN格式**: 编写RKNN配置文件(`config.yml`),指定输入尺寸、量化方式等参数。示例代码: ```python from rknn.api import RKNN rknn = RKNN() rknn.config(target_platform='rk3568', mean_values=[[127.5]], std_values=[[127.5]]) rknn.load_onnx(model="model.onnx") rknn.build(do_quantization=True, dataset="dataset.txt") rknn.export_rknn("model.rknn") ``` #### 3. **Android项目集成** - **添加RKNN库依赖**: 将编译好的RKNN动态库(`librknnrt.so`)和模型文件(`model.rknn`)放入Android项目的`jniLibs`目录。 - **JNI接口开发**: 通过JNI调用RKNN的C/C++ API实现推理。关键配置参考引用[3]: ```cpp #include <rknn/rknn_runtime.h> rknn_context ctx; int ret = rknn_init(&ctx, model_path, 0, 0, nullptr); ret = rknn_inputs_set(ctx, input_num, input_attrs); ret = rknn_run(ctx, nullptr); ret = rknn_outputs_get(ctx, output_num, output_attrs, nullptr); ``` #### 4. **关键配置参数** - **use_rga与use_mmap**: 根据引用[3],若Android设备不支持硬件加速(如RGA),需将`use_rga`和`use_mmap`设为`false`。 - **数据量化类型**: `data_type`可选`uint8`或`fp32`。若选`uint8`,需手动实现反量化;若选`fp32`,RKNN会自动处理[^3]。 #### 5. **性能优化** - **多线程推理**: 利用Android的`ThreadPoolExecutor`并行处理输入数据。 - **内存优化**: 启用`use_mmap`(若支持)减少内存拷贝开销,或通过零拷贝技术直接操作物理内存。 #### 6. **调试与验证** - **日志输出**: 启用RKNN的调试模式(`RKNN_LOG_LEVEL=DEBUG`)查看详细运行信息。 - **性能分析**: 使用`rknn.query(RKNN_QUERY_PERF_DETAIL)`获取各层耗时,针对性优化模型结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值