zoukankan      html  css  js  c++  java
  • 浅谈hive

    hive
    支持sql标准的数据仓库,可以将sql语句转化成mr程序执行。基础分析一般用hive来做,比较复杂的用mr来做
    数据仓库和数据库的区别
        数据仓库:历史数据,面向分析,保证数据的完整性可以允许数据冗余。
        数据库:存储结构化,在线数据,面向业务,使用范式来减少冗余。
    hive中有解析器,编译器,优化器。hive最终会将sql语句转成mr程序(select * from 表 除外,消耗时间过长所以不转mr)
    hive中也是有表的结构,来处理结构化数据,hive的元数据存储在关系型数据库(默认derby)中,元数据指表的名字、表的列和分区及其属性(是否为外部表)、表的数据所在目录等
    架构
    Driver:解析器,编译器(将hql转成很多操作符(树状结构),操作符是hive的最小单元,每个操作符表示对hdfs操作或者mr任务),优化器
        常用操作符:select operator(查找),tablescan operator(扫描),limit(限制输出),file output operator(文件输出)。
        hive的解析是通过antlr进行解析的,生成一个语法树生成上面的策略
            将HQL转成一个抽象的语法树,然后再转成一个查询块,接着转成逻辑计划并重写逻辑计划,再将逻辑计划转成物理计划(mr任务,可能有多个),最终从多种物理计划中选择最佳策略
    元数据库:存放元数据,需要用到元数据信息执行从这里拿
    Thrift:跨语言跨平台的socket通讯组件,可以进行跨语言跨平台的数据交互,支持多种序列化和反序列化,MetaStoreServer模式中hive客户端和MetaStoreServer通讯就是用Thrift组件
    Hadoop:hive解析成mr程序后提交给Hadoop进行执行
    三种模式(根据元数据存储的位置来划分)
    本地模式(测试)
        元数据存放在derby数据库(hive自带)中,在同一台中
    单用户模式
        元数据存放在自己选的数据库中,笔者这里用mysql,hive直接从MySQL中获取元数据。
        只允许一个hive客户端来访问MySQL,如果两个hive元数据都放在MySQL中,没有组件对元数据进行管理,两个hive同时操作会出问题
    多用户模式
        元数据存放在MySQL中,hive客户端通过MetaStoreServer来从MySQL中获取元数据(多个hive客户端操作一份元数据),采用Thrift协议。
        由MetaStoreServer来管理元数据信息,多个hive通过MetaStoreServer来拿元数据,MetaStoreServer会通过访问的顺序来返回
    安装(依赖Hadoop的环境变量,启动Hadoop)
        安装之前需要查看和Hadoop版本:http://hive.apache.org/downloads.html,笔者这里采用的是2.3.4版本
    1.本地模式
        cp conf/hive-env.sh.template conf/hive-env.sh
        添加HADOOP_HOME=/opt/hadoop-2.7.5
        cp conf/hive-default.xml.template conf/hive-site.xml
        <configuration>
            <property>
                <!--连接数据库的地址:数据库derby,数据库名称metastore_db,是否需要创建数据库-->
                <name>javax.jdo.option.ConnectionURL</name>
                <value>jdbc:derby:;databaseName=metastore_db;create=true</value>
            </property>
            <property>
                <!--驱动包-->
                <name>javax.jdo.option.ConnectionDriverName</name>
                <value>org.apache.derby.jdbc.EmbeddedDriver</value>
            </property>
            <property>
                <!--是否使用hive本地来管理元数据,一定是true-->
                <name>hive.metastore.local</name>
                <value>true</value>
            </property>
            <property>
                <!--hive对应HDFS的数据目录-->
                <name>hive.metastore.warehouse.dir</name>
                <value>/user/hive/warehouse</value>
            </property>
        </configuration>
        初始化derby数据库
            bin/schematool -dbType derby -initSchema
        进入hive
            bin/hive
    2.单用户模式(依赖MySQL)
        cp conf/hive-env.sh.template conf/hive-env.sh
        添加HADOOP_HOME=/opt/hadoop-2.7.5
        cp conf/hive-default.xml.template conf/hive-site.xml
        <configuration>
            <property>
                <!--HDFS中真实数据目录,空目录或不存在-->
                <name>hive.metastore.warehouse.dir</name>
                <value>/user/hive_remote/warehouse</value>
            </property>
            <property>
                <!--hive本地管理元数据-->
                <name>hive.metastore.local</name>
                <value>true</value>
            </property>
            <property>
                <name>hive.metastore.schema.verification</name>
                <value>false</value>
            </property>
            <property>
                <!--指定文件数据库url,用于存放元数据。格式jdbc:mysql://地址/库?库不存在自动创建-->
                <name>javax.jdo.option.ConnectionURL</name>
                <value>jdbc:mysql://node3:3306/hive_remote?createDatabaseIfNotExist=true</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>123456</value>
            </property>
        </configuration>
        添加mysql启动jar包,mysql-connector-java-5.1.32-bin.jar到hive的lib中
        启动Hadoop
        初始化MySQL数据库
            bin/schematool -dbType mysql -initSchema
        进入hive
            bin/hive
        可以在MySQL中看到TBLS表就是来存放hive表的元数据信息,COLUMNS_V2是列的元数据
    3.多用户模式
        1)remote一体
            配置MetaStoreServer和hive客户端放在一起
            cp conf/hive-env.sh.template conf/hive-env.sh
            添加HADOOP_HOME=/opt/hadoop-2.7.5
            cp conf/hive-default.xml.template conf/hive-site.xml
            <configuration>
                <property>
                    <!--HDFS真实存放数据的目录,空目录或不存在-->
                    <name>hive.metastore.warehouse.dir</name>
                    <value>/user/hive/warehouse</value>
                </property>
                <property>
                    <!--存放元数据地址,hive_remote库为空或者不存在-->
                    <name>javax.jdo.option.ConnectionURL</name>
                    <value>jdbc:mysql://node3:3306/hive_remote?createDatabaseIfNotExist=true</value>
                </property>
                <property>
                    <!--驱动包-->
                    <name>javax.jdo.option.ConnectionDriverName</name>
                    <value>com.mysql.jdbc.Driver</value>
                </property>
                <property>
                    <!--MySQL用户名-->
                    <name>javax.jdo.option.ConnectionUserName</name>
                    <value>root</value>
                </property>
                <property>
                    <!--MySQL密码-->
                    <name>javax.jdo.option.ConnectionPassword</name>
                    <value>123456</value>
                </property>
                <property>
                    <!--不启动本地hive管理元数据功能-->
                    <name>hive.metastore.local</name>
                    <value>false</value>
                </property>
                <property>
                    <!--MetaStoreServer的地址端口-->
                    <name>hive.metastore.uris</name>
                    <value>thrift://node1:9083</value>
                </property>
            </configuration>
            添加mysql启动jar包,mysql-connector-java-5.1.32-bin.jar到hive的lib中
            启动Hadoop
            初始化MySQL数据库
                bin/schematool -dbType mysql -initSchema
            启动MetaStoreServer
                bin/hive --service metastore
            启动hive
                bin/hive
        2)remote分开
        1、配置MetaStoreServer
            cp conf/hive-env.sh.template conf/hive-env.sh
            添加HADOOP_HOME=/opt/hadoop-2.7.5
            cp conf/hive-default.xml.template conf/hive-site.xml
            <configuration>
                <property>
                    <!--HDFS真实存放数据的目录,空目录或不存在-->
                    <name>hive.metastore.warehouse.dir</name>
                    <value>/user/hive/warehouse</value>
                </property>
                <property>
                    <!--存放元数据地址,hive_remote数据库一定保证空或者不存在-->
                    <name>javax.jdo.option.ConnectionURL</name>
                    <value>jdbc:mysql://node3:3306/hive_remote?createDatabaseIfNotExist=true</value>
                </property>
                <property>
                    <!--驱动包-->
                    <name>javax.jdo.option.ConnectionDriverName</name>
                    <value>com.mysql.jdbc.Driver</value>
                </property>
                <property>
                    <!--mysql用户名-->
                    <name>javax.jdo.option.ConnectionUserName</name>
                    <value>root</value>
                </property>
                <property>
                    <!--mysql密码-->
                    <name>javax.jdo.option.ConnectionPassword</name>
                    <value>123456</value>
                </property>
            </configuration>
            MetaStoreServer节点添加mysql启动jar包,mysql-connector-java-5.1.32-bin.jar到hive的lib中
            启动Hadoop
            初始化MySQL数据库
                bin/schematool -dbType mysql -initSchema
            启动MetaStoreServer
                bin/hive --service metastore
        2、hive客户端配置
            cp conf/hive-env.sh.template conf/hive-env.sh
            添加HADOOP_HOME=/opt/hadoop-2.7.5
            cp conf/hive-default.xml.template conf/hive-site.xml
            <configuration>
                <property>
                    <!--HDFS真实存放数据的目录,空目录或不存在,和MetaStoreServer保持一致-->
                    <name>hive.metastore.warehouse.dir</name>
                    <value>/user/hive/warehouse</value>
                </property>
                <property>
                    <!--不启动本地hive管理元数据功能-->
                    <name>hive.metastore.local</name>
                    <value>false</value>
                </property>
                <property>
                    <!--MetaStoreServer的地址端口-->
                    <name>hive.metastore.uris</name>
                    <value>thrift://node2:9083</value>
                </property>
            </configuration>
            启动hive
                bin/hive
    Beeline
    hive2中提出,用来管理hive属性的设定,和之前使用方式一样的
    在Hadoop的hdfs-site.xml和core-site.xml文件中分布添加
    hdfs-site.xml
        <property>  
            <name>dfs.webhdfs.enabled</name>  
            <value>true</value>  
        </property>  
    core-site.xml
        <property>
            <name>hadoop.proxyuser.root.hosts</name>
            <value>*</value>
        </property>
        <property>
            <name>hadoop.proxyuser.root.groups</name>
            <value>*</value>
        </property>
    按照上述过程安装后在MetaStoreServer节点启动hiveServer2,如果有metastore则需要启动
        bin/hiveserver2
    hive客户端
        bin/beeline(这时只是打开了beeline窗口并没有连接到MetaStoreServer节点)
        连接上MetaStoreServer节点的hiveserver2
        beeline>!connect jdbc:hive2://MetaStoreServer_IP:10000
        然后填写用户,可以填root,因为之前Hadoop的数据是在root用户下创建的。密码为空可直接回车
        默认不启动验证,配置文件中hive.server2.authentication默认为NONE
        或者
        bin/beeline -u jdbc:hive2://MetaStoreServer_IP:10000/库 -n user -w password_file(没有密码去掉-w password_file)
    beeline提供jdbc方式访问
    例如:(导入commons-lang-2.62,guava-14.0.12,hive-common-2.3.42,hive-jdbc-2.3.42,hive-serde-2.3.42,hive-service-2.3.42,hive-service-rpc-2.3.42,httpclient-4.42,httpcore-4.42,libthrift-0.9.32,slf4j-api-1.7.102的jar包)
        private static String driverName = "org.apache.hive.jdbc.HiveDriver";
        public static void main(String[] args) throws SQLException {
            try {
                Class.forName(driverName);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                System.exit(1);
            }
            Connection con = DriverManager.getConnection("jdbc:hive2://node1:10000/default", "root", "");
            Statement stmt = con.createStatement();
            String sql = "select * from psn";
            ResultSet res = stmt.executeQuery(sql);
            while (res.next()) {
                System.out.println(res.getString(1));
            }
        }
    HQL(官网->Language Manual)
    数据类型
        复合类型array_type(定义方式array<类型>),map_type(定义方式map<key类型,value类型>),struct_type(结构体)
        基本类型tinyint,smallint,int,bigint,boolean,float,double,string
    hive中表分为内部表和外部表
        外部表:数据存放在指定的HDFS路径中,即使执行了删除表命令,但是hdfs上数据不会删除,只是删除了元数据
        内部表:数据存放在hive配置文件所指定的位置中,执行删除表命令,元数据和hdfs数据都会删除
    DDL数据定义语言(对数据库表创建、删除、修改等操作)
        创建数据库
            create (database|schema) [if not exists] database_name
            [comment database_comment]
            [location hdfs_path]
            [with dbproperties (property_name=property_value, ...)];
        删除数据库
            drop (database|schema) [if exists] database_name [restrict|cascade];(当前不可以在需要删的库内)
        使用数据库
            use database_name;
        创建表(不指定库会在default库中创建)
            create [external] table [if not exists] [db_name.]table_name
            [(col_name data_type [comment col_comment],...)]
            [comment table_comment]
            [partitioned by (col_name data_type [comment col_comment],...)]
            [[row format row_format]
                row format delimited [fields terminated by char [escaped by char]]
                [collection items terminated by char]
                [map keys terminated by char]
                [lines terminated by char]
                [null defined as char]
            [stored as file_format]]
            [location hdfs_path]
            含义
            external指定内部表还是外部表,不写默认内部表。如果是外部表需要指定location关键字
            [db_name.]指定库
            col_name字段名
            data_type数据类型
            col_comment对字段的描述
            table_comment对表的描述
            partitioned by(注意partitionby的顺序)按照哪些列(这些列不能在前面出现过的)做分区处理,可以对不同场景的数据进行分开管理
                col_name列名
                data_type数据类型
                comment可选的描述
            row_format对行做格式化或者规定序列化和反序列化规则,不指定就用hive默认的规则来做,hive操作的是hdfs上数据所以需要row_format。
                比如:hdfs上数据为1,xiaoming,man,book-shejian-shoot,beijing:wudaokou-huoxing:weizhi,一条结构化数据要映射到hive中需要为它标识以什么做分割为哪一列哪一个数据。
            fields terminated by char指定字段和字段之间的分隔符  
            escaped by char指定分割的类型,默认char类型
            collection items terminated by char指定复合类型array_type里面数据的切分方式
            map keys terminated by char指定复合类型map_type里面数据的切分方式
            lines terminated by char指定每行数据的分隔符,默认/n
            null defined as char指定什么字符为空值
            file_format指定数据存储在hdfs中的文件类型,默认文本类型(也可以做压缩等)
            location指定表为外部表时加上设置存放表数据的hdfs路径
            例如一:通过delimited关键字指定分隔符的方式(hive中已经写好的序列化和反序列化的规则)创建一张表
                create table psn (id int,name string,sex string,likes array<string>,address map<string,string>)
                row format delimited
                fields terminated by ','
                collection items terminated by '-'
                map keys terminated by ':';
            例如二:通过serde关键字指定序列化和反序列化的方式来创建一张表,这样可以自定义序列化和反序列化的规则
                create table psn2
                row format serde "org.apache.hadoop.hive.serde2.columnar.columnarserde"
                stored as rcfile
                as
                select * from psn;
                参照psn表的元数据来创建psn2表(就是两张表的schema一样),并且将as后面的语句所查询的数据放到psn2中
            例如三:通过like关键字来创建表
                create table table_name2
                like table_name
                根据table_name表的元数据来创建table_name2表,两个表的schema相同
        删除表
            drop table table_name;
        截断表,将表中数据清空
            truncate table table_name
        修改表,
            语法和关系型数据库一样
        添加分区
            alter table table_name add partition (dt='2008-08-08', country='us') 根据分区字段来添加具体的值而已,不会添加分区字段
        删除分区(分区中的数据也会跟着删除掉,而且该分区下的所有分区也会删除)
            alter table table_name drop partition (dt='2008-08-08')
        视图和关系型数据库中一样,一般数据库不能对视图插入数据
    DML数据操作语言
        插入数据(load方式和insert)
        load:load data [local] inpath 'filepath' [overwrite] into table tablename [partition (partcol1=val1, partcol2=val2 ...)]
            local如果需要上传的文件在hdfs上不用加,如果在本地需要加上(它会先将本地文件上传到HDFS然后再加载到指定分区目录中)
            filepath文件路径
            overwrite是否覆盖
            partition如果创建表的时候使用了分区,那么导入的时候需要加上,而且分区个数要对应
            partcol1=val1分区字段名和分区字段所指定的值
        insert方式插入的速度很慢一般不会使用,但是一般如果需要将结果存到临时表中会用insert
        比如:from table_name 别名
                insert into table table_name1
                select 别名.col1,别名.col2,别名.col3
          或:from table_name 别名
                insert into table table_name1
                    select 别名.col1,别名.col2,别名.col3
                insert table table_name2
                    select 别名.col1,别名.col2,别名.col3
            如果要覆盖之前的数据,将into换成overwrite
        查询
        select * from table_name where partcol1=val1(根据分区来查找)
        修改数据
        update tablename set column = value [, column = value ...] [where expression]
        删除数据
        delete from tablename [where expression]
    正则表达式(官网->Getting Started Guide->Apache Weblog Data)
    比如
        create table apachelog (
          host string,
          identity string,
          user string,
          time string,
          request string,
          status string,
          size string,
          referer string,
          agent string)
        row format serde 'org.apache.hadoop.hive.serde2.regexserde'   接的是正则表达式的标准类
        with serdeproperties (
          "input.regex" = "([^]*) ([^]*) ([^]*) (-|\[^\]*\]) ([^ "]*|"[^"]*") (-|[0-9]*) (-|[0-9]*)(?: ([^ "]*|".*") ([^ "]*|".*"))?"
        )
        stored as textfile;
    hive内置函数
    https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF或链接:https://pan.baidu.com/s/1o26fIzJtTF-kqaDiufvqSQ 提取码:b5dl
    自定义函数
    UDF一进一出,进入一条数据返回一条数据
    UDAF多进一出
    UDTF一进多出,复杂类型会用到UDTF
    例如:自定义的UDF实现转小写(类继承UDF类重写evaluate方法,类型必须是Hadoop中类型并且结合业务来定)
        import org.apache.hadoop.hive.ql.exec.UDF;
        import org.apache.hadoop.io.Text;
        public final class Lower extends UDF {
          public Text evaluate(final Text s) {
            if (s == null) { return null; }
            return new Text(s.toString().toLowerCase());
          }
        }
    打jar包,将jar包放到MetaStoreServer节点
    然后在hive客户端上执行hive>add jar jar包路径 上传jar包。
    创建临时函数,在hive客户端执行hive>create temporary function 自定义函数名称(随意起) as 'hive.udf.add(程序的类入口)';
    测试
    select id,name,tm(sex) from psn;
    删除自定义函数hive> drop temporary function 自定义函数名称;
    hive优化,链接:https://pan.baidu.com/s/10jVPjYTTecGFPWyJv57Qhg 提取码:9aih



  • 相关阅读:
    登录界面
    动手动脑
    关于二进制
    Java考试
    D
    威尔逊定理 k!%p
    11.46.2020质检
    最长上升序列输出方案
    问题 G: 汽车的最终位置
    奶牛大会(二分)
  • 原文地址:https://www.cnblogs.com/timeTraveler/p/10781069.html
Copyright © 2011-2022 走看看