一、上次课回顾
二、Hive元数据之数据库相关表介绍
三、集群规模评估
四、写两个UDF函数
五、
一、上次课回顾
https://blog.csdn.net/zhikanjiani/article/details/98660561
二、Hive元数据之数据库相关表介绍
详细已经写在这篇博客上了:
https://blog.csdn.net/zhikanjiani/article/details/97237992
再来回顾一下吧
2.1、DBS(数据库表)
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/ruoze_g6?createDatabaseIfNotExist=true&characterEncoding=UTF-8</value>
</property>
ruoze_g6就是在mysql中创建的元数据库:
mysql> select * from DBS \G;
DB_ID: 6
DESC: NULL
DB_LOCATION_URI: hdfs://hadoop004:9000/user/hive/warehouse/ruozeg6.db
NAME: ruozeg6
OWNER_NAME: hadoop
OWNER_TYPE: USER
DBS库小结:主要关注两行:
1)DB_LOCATION_URI:ruozeg6数据库对应hdfs的存储目录
2)Name:ruozeg6:数据库名字
2.2、TBLS
mysql> select * from TBLS \G;
TBL_ID: 23
CREATE_TIME: 1561973475
DB_ID: 6
LAST_ACCESS_TIME: 0
OWNER: hadoop
RETENTION: 0
SD_ID: 23
TBL_NAME: dept
TBL_TYPE: MANAGED_TABLE
VIEW_EXPANDED_TEXT: NULL
VIEW_ORIGINAL_TEXT: NULL
TBLS表小结:
1)TBL_ID:表的id
2)DB_ID:Hive中的每一个表归属于一个数据库,相当于一个外键关联
3)SD_ID:关联SDS
2.3、SDS表
SD_ID: 33
CD_ID: 28
INPUT_FORMAT: org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat
IS_COMPRESSED:
IS_STOREDASSUBDIRECTORIES:
LOCATION: hdfs://hadoop004:9000/user/hive/warehouse/customers
NUM_BUCKETS: -1
OUTPUT_FORMAT: org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat
SERDE_ID: 33
SDS表小结:可以看出这个表的压缩形式.
CD_ID:关联到columns_v2表.
2.4、columns_v2表
mysql> select * from columns_v2 limit 20;
+-------+---------+-------------+-----------+-------------+
| CD_ID | COMMENT | COLUMN_NAME | TYPE_NAME | INTEGER_IDX |
+-------+---------+-------------+-----------+-------------+
| 1 | NULL | comm | double | 6 |
| 1 | NULL | deptno | int | 7 |
| 1 | NULL | empno | int | 0 |
| 1 | NULL | ename | string | 1 |
| 1 | NULL | hiredate | string | 4 |
| 1 | NULL | job | string | 2 |
| 1 | NULL | mgr | int | 3 |
| 1 | NULL | sal | double | 5 |
| 23 | NULL | deptno | string | 0 |
| 23 | NULL | dname | string | 1 |
| 23 | NULL | location | string | 2 |
| 24 | NULL | event_time | string | 1 |
| 24 | NULL | order_no | string | 0 |
| 25 | NULL | event_time | string | 1 |
| 25 | NULL | order_no | string | 0 |
| 26 | NULL | code | string | 0 |
| 26 | NULL | description | string | 1 |
| 26 | NULL | salary | int | 3 |
| 26 | NULL | total_emp | int | 2 |
| 27 | NULL | code | string | 0 |
+-------+---------+-------------+-----------+-------------+
20 rows in set (0.00 sec)
columns_v2表小结:存表中列的信息;
CD_ID:
COMMENT:描述
COLUMN_NAME:列名
TYPE_NAME:数据类型
INTEGER_IDX:信息作用上schema,插入数据的时候能知道插入那列是什么
eg: a,b,c,d,e,f 插入到Hive表中,它知道对应的列
2.4、Partitions表
2.5、partition_keys和partition_key_vals
问题:这些表的关联关系得知道?是通过哪些外键关联起来的?
业务场景:PK哥公司CDH版本比较低,Spark版本高;两个版本整合后基本功能没问题,有一个服务性能很高;把hadoop中hdfs的一个功能升级;Spark访问到的hdfs和Hadoop版本中的hdfs是不一样?
这样使用出现的问题:底层通信协议也对应不上,导致我们只能创建表,使用drop删除表都删除不了,无法删除Hive表中的数据;
解决方案:通过表的存放在mysql中表的关联关系去删除,还不能删错。
从监控、数据丢失、重跑;生产上业务需求是非常复杂的。
关联关系梳理清楚:
Spark对应的HDFS版本和YARN的版本不一致。
解决:编译的时候hadoop版本调高;info日志等级还不够,要打debug日志。
Spark ==> HDFS版本升级 ==> drop删除表删除不了 ==> meta
==>YARN
SQL ON Hadoop (优化策略基本上都是一样的)
Hive
Spark SQL
Impala
Presto
Phoenix
面试题:内部表和外部表区别?
三、集群规模评估
集群规模:
一条记录的大小(record size):300-500 byte字节
B=Byte(字节) b=bit(比特) 1B=8b
要计算访问量:一条业务线一天访问量1000W,每个人访问5次,一次看5个页面:
产生了流量1000W * 5 * 5 * (300~500)/ (102410241024) = 70M - 116M
访问量是100G,数据存放两年,副本数是3。计算所需要的存储空间?
==> 100 * 365 * 2 * 3
219T内存需要多少机器,一般服务器机器磁盘是30T,需要8台机器;
==>219 / 30
比如说有30条业务线,8 * 30 = 240台机器??
还要为这240台机器至少留30%的空间进行平摊;这时候存放的数据不可能一直都不动,肯定会有一些增量数据。我们差不多要留50%的空间。
从机器的角度看:NN/RM 可以放在一个机器上,NN至少要2个;
DN
ZK/JN 3~5台就够了 //PK公司1 2W台集群,也就十几台ZK/JN
Spark gateway 提交权限
如果有资源,ZK也建议独立。
从资源的角度看:
- CPU (32Core、64Core)影响application速度、物理core和虚拟core:1比1.5;云主机虚拟core没用,决定并行度
- Memory:主流100~200G,spark、flink 影响gc、oom
- Disk:100~200T
- network:万兆网
这还只是一个离线架构,RAW(源端) ⇒ ETL ==> sql table
面试题:你们一天的作业有多少???
一天跑几个mr、hive、spark?
一开始使用mr和hive,后来升级了才是用的spark。
通过一个例子来掌握一类例子:
StringBuilder builder = new StringBuilder("");
builder.append(cdn).append("\t")
.append(region).append("\t")
.append(level).append("\t")
.append(time).append("\t")
.append(ip).append("\t")
.append(domain).append("\t")
.append(url).append("\t")
.append(traffic);
业务需求1:每天每个域名访问产生的流量.
select day, domain, sum(traffic) from XXXX
group by day,domain
业务需求2:统计分析包含五个部分:
PV和UV、
地区和运营商、(日志清洗过程中解析IP,精准肯定是收费的)
域名排名:域名的访问量从高到低
热门Refer:从哪里来的意思
热门URL:
求每天每个地区每个运营商的流量
增量求全量:
离线任务:今天跑昨天的任务,2019-08-07跑的是2019-08-06的数据;
etl > table < sql > mysql/nosql < api ==> ui
etl过后的数据存放在mysql表中,我们使用sql访问,通过api的方式获取展示在ui上。
day=2019-08-06肯定是一个分区;要求近90天的,把所有分区累起来。
根据热门URL,流量,流量占比、访问次数、访问占比去计算mr的作业数??
需要使用IP解析成省、市;这个域名解析是收费的。
根据ip使用代码解析成省、市。
四、编写UDF函数
作业1:编写UDF函数:
输入:abc
输出:10以内的随机数_abc
新建AddPrefixUDF.java
package com.ruozedata.hadoop.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
import java.util.Random;
public class AddPrefixUDF extends UDF {
public String evluate(String input){
Random random = new Random();
int number = random.nextInt(10);
return number + ":" + input;
}
public static void main(String[] args) {
AddPrefixUDF udf = new AddPrefixUDF();
for (int i = 0;i < 10;i++){
System.out.println(udf.evluate("a") + i);
}
}
}
作业2:编写UDF函数
输入:10以内的随机数_abc
输出:abc
package com.ruozedata.hadoop.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
public class RemovePrefixUDF extends UDF {
public String evluate(String input){
return input.split("_")[1];
}
public static void main(String[] args) {
RemovePrefixUDF udf = new RemovePrefixUDF();
System.out.println(udf.evluate("10_abc" ));
}
}
打包到Hive中执行:
1、hive (ruozeg6)> ADD jar /home/hadoop/lib/g6-hadoop-1.0.jar;
Added [/home/hadoop/lib/g6-hadoop-1.0.jar] to class path
Added resources: [/home/hadoop/lib/g6-hadoop-1.0.jar]
2、hive (ruozeg6)> create temporary function add_Prefix AS 'com.ruozedata.hadoop.udf.AddPrefixUDF';
OK
Time taken: 0.096 seconds
3、hive (ruozeg6)> create temporary function remove_Prefix AS 'com.ruozedata.hadoop.udf.RemovePrefixUDF';
OK
Time taken: 0.005 seconds
hive (ruozeg6)> show functions;
OK
add_prefix
remove_prefix
4、测试
select add_prefix("a") from dual;
select remove_prefix("2_a") from dual;
select "b",add_prefix("b"), remove_prefix("3_a"),remove_prefix("b") from dual;