无情 @ 2015-12-18 14:14:53 阅读(2328)
hive Hadoop



前言:hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行




我在结合hadoop和hive遇到各种千奇百怪的问题,现在终于解决了,成功执行。hadoop安装详见 http://www.ccblog.cn/62.htm (本文结合之hadoop安装基础上还需要进行一些配置修改)



下面正式开始吧


1:修改之前hadoop安装好的配置文件

  a):yarn-site.xml


   

 <property>
        <name>yarn.nodemanager.resource.memory-mb</name>
        <value>2048</value>
    </property>


    参数修改2048 ,如果节点的内存小了执行hive的时候会报错:

    Caused by: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.yarn.exceptions.InvalidResourceRequestException):

    Invalid resource request, requested memory < 0, or requested memory > max configured, requestedMemory=1536, maxMemory=1024


   b): hdfs-site.xml 新增:

   

  <property>
     <name>dfs.permission</name>
     <value>false</value>
    </property>




    c): mapred-site.xml 新增(如果端口被占用清使用其他端口 或者把占用9001的端口修改掉)

      <property>      
        <name>mapred.job.tracker</name>    
        <value>XXXXXX:9001</value>  (ip是hadoop的地址)  
    </property>



    把以上3个文件分别复杂到另外两天slave上

    

    d):重启进程

      ./sbin/start-all.sh

      这个时候并没有启动yarn进程,通过jps看不到NodeManager的存在 所以需要再单独启动 命令:./yarn-daemons.sh stop|start(开启|关闭) nodemanager



      以上是对之前(http://www.ccblog.cn/62.htm )的基础上做了配置修改


2:hive安装

 先设置环境变量

export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91.x86_64

export HADOOP_HOME=/usr/local/hadoop-2.7.1

export HADOOP_PREFIX=/usr/local/hadoop-2.7.1

export PATH=$PATH:$HADOOP_PREFIX/bin

export PATH=$PATH:$HADOOP_PREFIX/sbin



  a):下载hive: wget http://mirror.bit.edu.cn/apache/hive/hive-1.2.1/apache-hive-1.2.1-bin.tar.gz (本人只在hadoop的master安装 salve没有安装hive)

       下载完成后解压 tar -vxf apache-hive-1.2.1-bin.tar.gz

  

  b):配置  apache-hive-1.2.1-bin/conf/hive-site.xml

       我在该目录下没有发现  hive-site.xml  只有  hive-default.xml.template ,只需:cp  hive-default.xml.template  hive-site.xml 就可以了 然后删除配置里面的内容修改如下:


 <configuration>
        <property>
                <name>javax.jdo.option.ConnectionURL</name>
                <value>jdbc:mysql://XXXX:3306/hive?characterEncoding=utf8</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionDriverName</name>
                <value>com.mysql.jdbc.Driver</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionUserName</name>
                <value>root</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionPassword</name>
                <value>root</value>
        </property>
        <property>
                <name>hive.metastore.local</name>
                <value>false</value>
        </property>
       
        <property>
                <name>hive.metastore.warehouse.dir</name>
                <value>hdfs://XXXXXX:9000/hive/</value> (这个是hadoop的安装ip)
        </property>
        <property>
                <name>hive.metastore.uris</name>
                <value>thrift://XXXXXXX:9083</value>(这个是hive的安装ip 如果是9083被占用请换其他端口)
        </property>
</configuration>


以上配置是:hive的远程模式配置法,连接了mysql数据库。需要先创建hive数据库在mysql上。注意编码格式是latin1 不能用utf-8否则会出现:

  Specified key was too long; max key length is 767 bytes 错误



c):启动服务

    启动前需要将mysql的mysql-connector-java-5.1.22.jar驱动包放到hive的lib下


    bin/hive --service metastore  ---- Starting Hive Metastore Server(这个是远程存储服务)

    ./bin/hive --service hiveserver2   (这个是hive服务启动,注意:hiveserver 已经被 hiveserver2 取代了,详见https://cwiki.apache.org/confluence/display/Hive/HiveServer)

    到此hive已经完成。



3:hive 使用

 

 a):创建表 

 create table testhive (key int, value string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'

 可以通过java api 或者直接在linux下创建


 说明:\t 是读取文件时候的分隔符


创建一个文件 1.txt内容如下 (注意:这里的空格是通过tab产生的)

1 zhp

2 hello

然后上传到hadoop上目录是之前的hdfs://XXXXXX:9000/hive/目录下


可以通过hivesql进行查询了

select * from testhive


select count(1) from testhive  (执行这个有点慢的)


java api操作

pom内容如下:

<dependency>
        <groupId>jdk.tools</groupId>
        <artifactId>jdk.tools</artifactId>
        <version>1.7</version>
        <scope>system</scope>
        <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
    </dependency>
 <dependency>  
            <groupId>org.apache.hive</groupId>  
            <artifactId>hive-jdbc</artifactId>  
            <version>1.2.1</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.hadoop</groupId>  
            <artifactId>hadoop-common</artifactId>  
            <version>2.7.1</version>  
</dependency>

 

  

代码

   


package com.demo.hive;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class CRUDhive {
    private static String    driverName = "org.apache.hive.jdbc.HiveDriver";
    private static String    url        = "jdbc:hive2://XXXXXXX:10000/default";//(默认端口是10000)
    private static String    user       = "hive";
    private static String    password   = "";
    private static String    sql        = "";
    private static ResultSet res;
    public static void main(String[] args) {
        System.out.print("2\t"+"HI");
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = getConn();
            stmt = conn.createStatement();
          selectData(stmt, "testhive");
          //  countData(stmt, "testhive");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static void countData(Statement stmt, String tableName) throws SQLException {
        sql = "select count(1) from " + tableName;
        System.out.println("Running:" + sql);
        res = stmt.executeQuery(sql);
        System.out.println("执行“regular hive query”运行结果:");
        while (res.next()) {
            System.out.println("count ------>" + res.getString(1));
        }
    }
    
    private static void selectData(Statement stmt, String tableName) throws SQLException {
        sql = "select * from " + tableName;
        System.out.println("Running:" + sql);
        res = stmt.executeQuery(sql);
        System.out.println("执行 select * query 运行结果:");
        while (res.next()) {
            System.out.println(res.getInt(1) + "\t" + res.getString(2));
        }
    }
    private static Connection getConn() throws ClassNotFoundException, SQLException {
        Class.forName(driverName);
        Connection conn = DriverManager.getConnection(url, user, password);
        return conn;
    }
}