hadoop15--MR调优, 虚拟列, mysql

表的优化

  1. 在表的优化中, 当数据量较大的时候常用的手段就是拆分表, 大表拆小表, 分区表, 临时表, 外部表
  2. 小表和大表的join, 要把数据量小的表放在join的左边, 先进行缓存, 这样会减少表join的时候内存的消耗量

数据倾斜

数据倾斜产生的原因为分区之后某一个reduce运算的数据量比较小, 而某一个reduce运行的数据量比较大, 造成两个reduce处理数据不平等

合理设置map数量
可以影响map的数量的因素

在input文件夹中, 每一个文件就是一个map. input文件的数量, input文件的大小都会影响map的数量, 在mapreduce任务中, 一个切片就是一个map任务, 在Driver中设置如下:

FileInputFormat.setMaxInputSplitSize(job, size);
FileInputFormat.setMinInputSplitSize(job, size);
合理设置reduce数量

设置reduce个数:

hive (default)> set mapreduce.job.reduces;
mapreduce.job.reduces=-1
//默认为-1, 就是不设置reduce的个数

根据业务自定分区规则

并行执行

并行执行与java多线程的异步和同步概念差不多, 在MR运行任务中, 存在很多的MR任务可以进行执行, 有些MR任务和下一个MR任务存在依赖关系, 但是有些MR任务没有依赖关系. 例如: 存在依赖关系的MR, 一个MR任务的输出就是下一个MR任务的输入. 对于没有依赖关系的MR任务可以使用并行执行, 在同一时间运行多个MR任务, 这样在运行的过程中效率就会得到提升.

可以通过以下参数来设置

  1. 开启并行任务
hive (default)> set hive.exec.parallel;
hive.exec.parallel=false
---------------------------------------
set hive.exec.parallel=true;
  1. 设置多少个任务可以同时运行
hive (default)> set hive.exec.parallel.thread.number;
hive.exec.parallel.thread.number=8
//默认值为8个任务可以同时执行

严格模式

hive中提供有严格模式, 为了防止一些查询出现不好的影响, 例如笛卡尔积, 在严格模式下是不能运行的.

默认的严格模式设置:

<property>
    <name>hive.mapred.mode</name>
    <value>nonstrict</value>
    <description>
      The mode in which the Hive operations are being performed. 
      In strict mode, some risky queries are not allowed to run. They include:
        Cartesian Product.
        No partition being picked up for a query.
        Comparing bigints and strings.
        Comparing bigints and doubles.
        Orderby without limit.
    </description>
  </property>
  //默认值为非严格模式 : nonstrict

开启严格模式 : strict

开启了严格模式会对查询语句进行一些限制:

  1. 对于分区表: 必须存在where语句对分区表中的分区字段进行条件过滤, 否则不允许执行该查询.
  2. 对于使用order by: 当使用orderby语句时, 必须使用limit进行限定, 由于orderby之后所有的数据都会被分到一个reduce中, 这样reduce操作的数据量太大, 可能时间过长, 导致卡死, 所以为了防止出现这种情况, 在orderby的时候必须给定limit限制, 减少reduce处理的数据量
  3. 笛卡尔积查询: 在多表join中会出现笛卡尔积, 笛卡尔积灰造成内存的加大消耗, 为了防止这种情况, 禁止使用笛卡尔积查询, 同时防止误操作

JVM重用

在hive执行计算任务的时候, 会把执行计划上传到YARN集群中进行提交, 运行MR任务, 每次进行任务的运行的时候都会开启一个JVM进程运行MR任务, 如果提交任务频繁过多, 就会造成JVM频繁的开启和关闭, 在JVM的开启和关闭的过程中会造成大量的资源浪费.

在处理小文件的时候, 由于map任务较多, 所以JVM或频繁的开启和关闭, 所以对于小文件的处理优化, 主要减少JVM开启的次数

在mapred-default.xml配置文件中有如下参数:

<property>
  <name>mapreduce.job.jvm.numtasks</name>
  <value>10</value>
  <description>How many tasks to run per jvm. If set to -1, there is
  no limit. 
  </description>
</property>

在hive中临时设置JVM重用任务的数量

hive (default)> set mapreduce.job.jvm.numtasks;
mapreduce.job.jvm.numtasks=1

推测执行

由于集群中的资源分配不均等, 或者说每个集群中节点硬件性能会导致某个任务运行的时间快, 或者某个任务运行时间慢, 或者某个任务运行时直接卡死.

为了防止某些任务在运行过程中拖慢了整个MR任务的进度, 在运行慢的任务节点上, 开启相同的任务, 如果时间比原来的任务运行的快, 则直接输出推测的任务.

注意 : 推测执行分为map端的推测执行以及reduce端的推测执行

map端

设置开启map端推测执行的参数:

<property>
  <name>mapreduce.map.speculative</name>
  <value>true</value>
  <description>If true, then multiple instances of some map tasks
               may be executed in parallel.</description>
</property>

在hadoop中默认开启推测执行, 推测执行不是说一卡死就开启推测任务, 而是必须要运行到5%以上才开启推测执行

在hive中通过set设置

hive (default)> set mapreduce.map.speculative;
mapreduce.map.speculative=true
reduce端

设置开启reduce端推测执行的参数:

<property>
  <name>mapreduce.reduce.speculative</name>
  <value>true</value>
  <description>If true, then multiple instances of some reduce tasks
               may be executed in parallel.</description>
</property>

在hive中通过set设置

hive (default)> set mapreduce.reduce.speculative;
mapreduce.reduce.speculative=true

执行计划—查看SQL语句的执行过程

hive中提供可以查看hql语句的执行计划 , 在执行计划中会生成抽象语法树, 在语法树中会显示hql语句之间的以来关系以及执行过程. 通过这些执行的过程和以来关系可以对hql语句进行优化

explain + 执行语句
------------------------------------------------
hive (default)> explain select * from emp;
OK
Explain
STAGE DEPENDENCIES:
  Stage-0 is a root stage

STAGE PLANS:
  Stage: Stage-0
    Fetch Operator
      limit: -1
      Processor Tree:
        TableScan
          alias: emp
          Statistics: Num rows: 2 Data size: 653 Basic stats: COMPLETE Column stats: NONE
          Select Operator
            expressions: empno (type: int), ename (type: string), job (type: string), mgr (type: int), edate (type: string), sal (type: double), deptno (type: int)
            outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6
            Statistics: Num rows: 2 Data size: 653 Basic stats: COMPLETE Column stats: NONE
            ListSink

Time taken: 0.127 seconds, Fetched: 17 row(s)

一般来说都会把复杂语句简单化处理, 例如多表的join

虚拟列

虚拟列本身是一个不存在的列, 在数据查询的时候, 可以通过虚拟列查询数据的路径, 以及数据的偏移量, 这两个都是hive中为用户提供的虚拟列进行的查询

INPUT__FILE__NAME : 数据文件的保存路径

通过查询得到文件的保存路径

select ename, INPUT__FILE__NAME  from emp;
SMITH   hdfs://ns1/user/hive/warehouse/emp/emp.txt
ALLEN   hdfs://ns1/user/hive/warehouse/emp/emp.txt
WARD    hdfs://ns1/user/hive/warehouse/emp/emp.txt
JONES   hdfs://ns1/user/hive/warehouse/emp/emp.txt
MARTIN  hdfs://ns1/user/hive/warehouse/emp/emp.txt
BLAKE   hdfs://ns1/user/hive/warehouse/emp/emp.txt
CLARK   hdfs://ns1/user/hive/warehouse/emp/emp.txt
SCOTT   hdfs://ns1/user/hive/warehouse/emp/emp.txt
KING    hdfs://ns1/user/hive/warehouse/emp/emp.txt
TURNER  hdfs://ns1/user/hive/warehouse/emp/emp.txt
ADAMS   hdfs://ns1/user/hive/warehouse/emp/emp.txt
JAMES   hdfs://ns1/user/hive/warehouse/emp/emp.txt
FORD    hdfs://ns1/user/hive/warehouse/emp/emp.txt
MILLER  hdfs://ns1/user/hive/warehouse/emp/emp.txt

BLOCK__OFFSET__INSIDE__FILE : 得到数据文件的偏移量信息

通过虚拟里得到数据的偏移量

select ename ,BLOCK__OFFSET__INSIDE__FILE  from emp;
ename   block__offset__inside__file
SMITH   0
ALLEN   44
WARD    97
JONES   149
MARTIN  194
BLAKE   249
CLARK   294
SCOTT   339
KING    385
TURNER  429
ADAMS   480
JAMES   524
FORD    567
MILLER  612

安装配置mysql

由于hive中默认的元数据保存在derby中只能单用户访问hive , 则另一用户无法访问, 会出现以下错误信息:

Caused by: ERROR XSDB6: Another instance of Derby may have already booted the database /opt/app/apache-hive-1.2.1-bin/metastore_db.

为了解决以上的问题, 可以把hive的元数据保存在mysql中.

mysql的安装步骤
  1. 在Linux系统中,可能存在mysql的安装包, 所以第一步先检查是否安装过mysql
[hadoop@hadoop apache-hive-1.2.1-bin]$ rpm -qa | grep -i mysql
mysql-libs-5.1.73-5.el6_6.x86_64

执行该命令可以查看是否安装mysql

  1. 卸载已有的mysql安装包
[hadoop@hadoop apache-hive-1.2.1-bin]$ sudo rpm -e --nodeps mysql-libs-5.1.73-5.el6_6.x86_64
[sudo] password for hadoop:  
  1. 查看是否卸载成功
[hadoop@hadoop apache-hive-1.2.1-bin]$ rpm -qa | grep -i mysql  
[hadoop@hadoop apache-hive-1.2.1-bin]$ 
  1. mysql分为server端和client端
 MySQL-client-5.5.47-1.linux2.6.x86_64.rpm
 MySQL-server-5.5.47-1.linux2.6.x86_64.rpm
  1. 安装mysql软件

    通过rpm安装server

sudo rpm -ivh MySQL-server-5.5.47-1.linux2.6.x86_64.rpm 

​ 通过rpm安装client

sudo rpm -ivh MySQL-client-5.5.47-1.linux2.6.x86_64.rpm
  1. 查看mysql的运行状态
sudo service mysql status
  1. 启动mysql服务
[root@hadoop mysql]# service mysql start
Starting MySQL.. SUCCESS!
  1. 再次查看mysql运行状态
 SUCCESS! MySQL running (5094)
设置密码,远程授权
设置密码
  1. mysql安装好之后进入mysql
mysql -uroot
  1. 查询数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.01 sec)
  1. 切换mysql数据库
mysql> use mysql;
Database changed
  1. 查看user, host, passWord信息
mysql> select user,host,password from user;
+------+-----------+----------+
| user | host      | password |
+------+-----------+----------+
| root | localhost |          |
| root | hadoop    |          |
| root | 127.0.0.1 |          |
| root | ::1       |          |
|      | localhost |          |
|      | hadoop    |          |
+------+-----------+----------+
6 rows in set (0.00 sec)
  1. 设置mysql密码
mysql> update user set password=PASSWORD('root') where user='root';
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4  Changed: 4  Warnings: 0
  1. 修改密码之后, 查询user表内容如下,说明在本地已经成功设置好了密码
mysql> select user,host,password from user;
+------+-----------+-------------------------------------------+
| user | host      | password                                  |
+------+-----------+-------------------------------------------+
| root | localhost | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| root | hadoop    | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| root | 127.0.0.1 | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| root | ::1       | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
|      | localhost |                                           |
|      | hadoop    |                                           |
+------+-----------+-------------------------------------------+
6 rows in set (0.00 sec)
设置远程授权
  1. 通过新设置的密码登录mysql, 发现遇到如下问题, 说明用户名或密码不正确
[root@hadoop mysql]# mysql -uroot -proot
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

​ 在user表中存在字段host , 该字段表示可以访问mysql的路径地址, 从哪个节点可以访问, 有这个字段来决定

  1. 所以要授权远程登录, 则需要修改host字段, 增加一条信息, 表示任意节点都可以访问mysql, 用%来表示任意
mysql> update user set host='%' where user='root' and host='127.0.0.1';
  1. 完成以上语句后, 需要对修改的user进行刷新来生效语句操作
mysql> flush privileges;

  1. 完成以上操作之后验证mysql用户登录,可以登录成功
[root@hadoop mysql]# mysql -uroot -proot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.5.47 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

配置hive元数据保存在mysql

需要在hive-site.xml配置文件总进行配置

  1. 设置hive链接mysql
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://192.168.91.100:3306/metastore?createDatabaseIfNotExist=true</value>
    <description>JDBC connect string for a JDBC metastore</description>
  </property>

​ metastore: 默认保存hive中的元数据, 是一个数据库的名字

  1. 设置jdbc的驱动类
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
    <description>Driver class name for a JDBC metastore</description>
  </property>
  1. 设置mysql的用户名
  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>root</value>
    <description>Username to use against metastore database</description>
  </property>
  1. 设置mysql的密码
  <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>root</value>
    <description>password to use against metastore database</description>
  </property>
  1. 完成以上的配置之后, 需要在hive/lib下边存放jdbc的驱动包, 上传好驱动包之后最好修改权限
 sudo chown -R hadoop:hadoop mysql-connector-java-5.1.31.jar 
  1. 将驱动包拷贝到hive目录下的lib文件夹
cp mysql-connector-java-5.1.31.jar /opt/app/apache-hive-1.2.1-bin/lib/
  1. 到hive的lib下检查是否拷贝成功

  2. 配置完成, 退出hive重新进入, 检查mysql中是否创建了metastore数据库, 如果创建成功, 则说明配置成功

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| metastore          |
| mysql              |
| performance_schema |
| test               |
+--------------------+

hiveserver2

1. beeline方式的连接

相当于在hive中启动一个服务器端, 客户端可以远程连接该hive, hiveserver2不用安装, 直接在hive/bin目录下启动

bin/hiveserver2

hiveserver2的服务启动之后, 可以通过bin/beeline客户端进行连接

官方实例:

!connect jdbc:hive2://localhost:10000 scott tiger

按照官方提供实例, 连接hiveserver2 测试能否连接成功

!connect jdbc:hive2://hadoop:10000 hadoop 123456
2. jdbc的方式连接
package org.hive.server;

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;

public class HiveJdbcClient {

	 private static String driverName = ""org.apache.hive.jdbc.HiveDriver"";
	 
	  /**
	   * @param args
	   * @throws SQLException
	   */
	  public static void main(String[] args) throws SQLException {
	      try {
	      Class.forName(driverName);
	    } catch (ClassNotFoundException e) {
	      // TODO Auto-generated catch block
	      e.printStackTrace();
	      System.exit(1);
	    }
	    //replace ""hive"" here with the name of the user the queries should run as
	    Connection con = DriverManager.getConnection(""jdbc:hive2://10.0.152.235:10000/default"", ""hive"", """");
	    Statement stmt = con.createStatement();
	    
	    String sql = ""show tables"";
	    System.out.println(""Running: "" + sql);
	    ResultSet res = stmt.executeQuery(sql);
	    if (res.next()) {
	      System.out.println(res.getString(1));
	    }
	 }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值