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/hive2.单用户模式(依赖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/hiveBeelinehive2中提出,用来管理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/hiveserver2hive客户端 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,stringhive中表分为内部表和外部表 外部表:数据存放在指定的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内置函数或链接: 提取码: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优化,链接: 提取码:9aih