美文网首页
11.Hadoop:Hive基本使用

11.Hadoop:Hive基本使用

作者: 負笈在线 | 来源:发表于2020-07-04 06:23 被阅读0次

    本节主要内容:

    Hive基本使用

    一.Hive存储模式

    Hive中建立的表都叫metastore表。这些表并不真实的存储数据,而是定义真实数据跟hive之间的映射,就像传统数据库中表的meta信息,所以叫做metastore。

    实际存储的时候可以定义的存储模式有四种:

    ---内部表(默认)

    ---分区表

    ---桶表

    ---外部表

    二.内部表

    建立内部表

    CREATE TABLE worker(id INT, name STRING)

    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\054';

    建立一个worker的内部表,内部表是默认的类型,所以不用写存储的模式,并且使用逗号作为分隔符存储。

          # hive

    Logging initialized using configuration in file:/etc/hive/conf.dist/hive-log4j.properties

    WARNING: Hive CLI is deprecated and migration to Beeline is recommended.

    hive> show tables;

    OK

    Time taken: 0.948 seconds

    hive> CREATE TABLE worker(id INT, name STRING)

         > ROW FORMAT DELIMITED FIELDS TERMINATED BY '\054';

    OK

    Time taken: 34.248 seconds

    hive>

          > CREATE TABLE worker(id INT, name STRING)

          > ROW FORMAT DELIMITED FIELDS TERMINATED BY '\054';

    054为ascii码中的逗号,Hive没有专门的数据存储格式,也没有为数据建立索引,用户可以非常自由的组织Hive中的表,只需要在创建表的时候告诉Hive,数据中的列分隔符和行分隔符,Hive就可以解析数据。

    比如:

    create table  user_info (user_id int, cid string, ckid string, username string) 

    row format delimited 

    fields terminated by '\t'

    lines terminated by '\n';

    导入数据表的数据格式是:字段之间是tab键分割,行之间是断行。

    文件内容格式如下:

    100636  100890  c5c86f4cddc15eb7        yyyvybtvt

    100612  100865  97cc70d411c18b6f        gyvcycy

    100078  100087  ecd6026a15ffddf5        qa000100

    hive> show tables;

    OK

    worker

    Time taken: 0.28 seconds, Fetched: 1 row(s)

    hive>

    表的存储位置

           #  sudo -u hdfs hadoop fs -ls /user/hive/warehouse

    Found 1 items

    drwxrwxrwt  - root supergroup          0 2020-07-03 03:34 /user/hive/warehouse/worker

    插入数据:

    Hive不支持单句插入的语句,必须批量,不能像sql一样使用insert into worker value(1,'zhangsan')

    插入的方式有两种:

    其一:从文件读取数据

    其二:从别的表读出数据插入(insert from select)

    从文件读取数据

           # cat /worker.txt

    1,zhangsan

    2,lisi

    3,wangwu

    4,zhaoliu

    插入数据到表中:

    hive> LOAD DATA LOCAL INPATH '/worker.txt' INTO TABLE worker;

    Loading data to table default.worker

    Table default.worker stats: [numFiles=1, totalSize=37]

    OK

    Time taken: 4.477 seconds

    hive> select * from worker;

    OK

    1 zhangsan

    2 lisi

    3 wangwu

    4 zhaoliu

    Time taken: 1.293 seconds, Fetched: 4 row(s)

    查看数据存储:

              # sudo -u hdfs hadoop fs -ls /user/hive/warehouse/worker

    Found 1 items

    -rwxrwxrwt  3 root supergroup        37 2020-07-03 03:34  /user/hive/warehouse/worker/worker.txt

    继续插入数据

             # cat /worker.abc

    5,tianqi

    6,wangba

    7,pijiu

    注意,hive不需要扩展名,扩展名可以随意写

    hive> LOAD DATA LOCAL INPATH '/worker.txt' INTO TABLE worker;

    Loading data to table default.worker

    Table default.worker stats: [numFiles=1, totalSize=37]

    OK

    Time taken: 34.11 seconds

    hive> select * from worker;

    OK

    1      zhangsan

    2      lisi

    3      wangwu

    4      zhaoliu

    Time taken: 28.489 seconds, Fetched: 4 row(s)

    hive>

             # sudo -u hdfs hadoop fs -ls /user/hive/warehouse/worker

    Found 1 items

    -rwxrwxrwt  3 root supergroup        37 2020-07-03 03:48 /user/hive/warehouse/worker/worker.txt

    LOAD DATA LOCAL INPATH '/worker.txt' INTO TABLE worker;

    LOAD DATA LOCAL INPATH 跟 LOAD DATA INPATH 的区别是一个是从你本地磁盘上找源文件,一个是从hdfs上找文件

    三.分区表

    分区表是用来加速查询的,主要依赖于指定条件

    举例:我们按照日期查询数据,所以我们要根据日期分区

    创建分区表

    hive> create table partition_student(id int,name string)

        > partitioned by(daytime string)

        > row format delimited fields TERMINATED BY '\054';

    OK

    Time taken: 2.492 seconds

    hive> show tables;

    OK

    partition_student

    worker

    Time taken: 8.952 seconds, Fetched: 2 row(s)

    hive>

    创建数据文件:

             # vi 2020070301

    1,zhangsan

    2,lisi

    3,wangwu

    4,zhaoliu

               # vi 2020070302

    33,tianqi

    44,xiongda

    55,xionger

    导入数据表的数据格式是:字段之间是tab键分割,行之间是断行。

    hive> LOAD DATA LOCAL INPATH '/2020070301' INTO TABLE partition_student partition(daytime='2020070301');

    Loading data to table default.partition_student partition (daytime=2020070301)

    Partition default.partition_student{daytime=2020070301} stats: [numFiles=1, numRows=0, totalSize=37, rawDataSize=0]

    OK

    Time taken: 56.454 seconds

    hive> LOAD DATA LOCAL INPATH '/2020070302' INTO TABLE partition_student partition(daytime='2020070302');

    Loading data to table default.partition_student partition (daytime=2020070302)

    Partition default.partition_student{daytime=2020070302} stats: [numFiles=1, numRows=0, totalSize=32, rawDataSize=0]

    OK

    Time taken: 9.389 seconds

    hive>

    注意:每次导入文件进去,要手动定义daytime=,作为后面分区查询的依据

    hive> select * from partition_student where daytime='2020070301';

    OK

    1      zhangsan        2020070301

    2      lisi    2020070301

    3      wangwu  2020070301

    4      zhaoliu 2020070301

    Time taken: 15.493 seconds, Fetched: 4 row(s)

    hive> select * from partition_student where daytime='2020070302';

    OK

    33      tianqi  2020070302

    44      xiongda 2020070302

    55      xionger 2020070302

    Time taken: 2.219 seconds, Fetched: 3 row(s)

    hive>

    hive> select * from partition_student;

    OK

    1      zhangsan        2020070301

    2      lisi    2020070301

    3      wangwu  2020070301

    4      zhaoliu 2020070301

    33      tianqi  2020070302

    44      xiongda 2020070302

    55      xionger 2020070302

    Time taken: 4.861 seconds, Fetched: 7 row(s)

    hive>

    注意:

    select * from partition_student where daytime='2020070302';支持where 使用and,当然应该使用在多维表中,并在创建表时声明多个分区类型。

    例如:

    create table student(id int, name string)

    partitioned by(daytime string,telnum string)定义了两个分区类型,就可以在where后使用and

    row format delimited fields TERMINATED BY '\054';

    存储结构

                 # sudo -u hdfs hadoop fs -ls /user/hive/warehouse/partition_student

    Found 2 items

    drwxrwxrwt  - root supergroup          0 2020-07-03 04:02 /user/hive/warehouse/partition_student/daytime=2020070301

    drwxrwxrwt  - root supergroup          0 2020-07-03 04:03 /user/hive/warehouse/partition_student/daytime=2020070302

    四.分桶:

    分桶是相对分区进行更细粒度的划分。

    分桶将整个数据内容安装某列属性值得hash值进行区分,

    如要按照name属性分为3个桶,

    就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。

    如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件。

    与分区不同的是,分区依据的不是真实数据表文件中的列,而是我们指定的伪列,

    但是分桶是依据数据表中真实的列而不是伪列。所以在指定分区依据的列的时候要指定列的类型,

    因为在数据表文件中不存在这个列,相当于新建一个列。而分桶依据的是表中已经存在的列,

    这个列的数据类型显然是已知的,所以不需要指定列的类型。

    1、建表

    通过 clustered by(字段名) into bucket_num buckets 分桶,意思是根据字段名分成bucket_num个桶

    > create table test_bucket (

    > id int comment 'ID',

    > name string comment '名字'

    > )

    > comment '测试分桶'

    > clustered by(id) into 3 buckets

    > ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;

    测试数据

              # for i in {1..10}; do echo $i,name$i >> bucket_data.txt;done

              # cat bucket_data.txt

    1,name1

    2,name2

    3,name3

    4,name4

    5,name5

    6,name6

    7,name7

    8,name8

    9,name9

    10,name10

    load data

    直接load data不会有分桶的效果,这样和不分桶一样,在HDFS上只有一个文件。

    load data local inpath '/buckt_data.txt' into table test_bucket;

    需要借助中间表

    > create table test (

    > id int comment 'ID',

    > name string comment '名字'

    > )

    > comment '测试分桶中间表'

    > ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;

    OK

    Time taken: 0.483 seconds

    hive> load data local inpath '/bucket_data.txt' into table test;

    Loading data to table default.test

    Table default.test stats: [numFiles=1, totalSize=82]

    OK

    Time taken: 2.077 seconds

    然后通过下面的语句,将中间表的数据插入到分桶表中,这样会产生三个文件。

    hive> set hive.enforce.bucketing = true;

    强制分桶。

    hive> set hive.enforce.bucketing = true;

    hive> insert into test_bucket select * from test;

    Query ID = root_20200703042727_918a62fa-bdce-4ca8-8a07-e1db2d085076

    Total jobs = 1

    Launching Job 1 out of 1

    Number of reduce tasks determined at compile time: 3

    In order to change the average load for a reducer (in bytes):

      set hive.exec.reducers.bytes.per.reducer=<number>

    In order to limit the maximum number of reducers:

      set hive.exec.reducers.max=<number>

    In order to set a constant number of reducers:

      set mapreduce.job.reduces=<number>

    Starting Job = job_1593650776473_0001, Tracking URL = http://node1.hadoop.com:8088/proxy/application_1593650776473_0001/

    Kill Command = /usr/lib/hadoop/bin/hadoop job  -kill job_1593650776473_0001

    http://172.26.37.245:19888/jobhistory/app中可以看到分布式任务

    查看文件结构

              # sudo -u hdfs hadoop fs -ls /user/hive/warehouse/test_bucket

    Found 3 items

    -rwxrwxrwt  3 hdfs supergroup        24 2020-07-03 23:06 /user/hive/warehouse/test_bucket/000000_0

    -rwxrwxrwt  3 hdfs supergroup        34 2020-07-03 23:06 /user/hive/warehouse/test_bucket/000001_0

    -rwxrwxrwt  3 hdfs supergroup        24 2020-07-03 23:06 /user/hive/warehouse/test_bucket/000002_0

    五.外部表:

    外部表不是由hive来存储的,可以依赖Hbase来存储,hive只是做一个映射。

    1.创建hbase表

           # hbase shell

    hbase(main):011:0> create 'student','info'

    0 row(s) in 2.2390 seconds

    => Hbase::Table - student

    hbase(main):012:0> put 'student',1,'info:id',1

    0 row(s) in 0.2780 seconds

    hbase(main):014:0> put 'student',1,'info:name','zhangsan'

    0 row(s) in 0.0200 seconds

    hbase(main):016:0> put 'student',2,'info:id',2

    0 row(s) in 0.0100 seconds

    hbase(main):018:0> put 'student',2,'info:name','lisi'

    0 row(s) in 0.0100 seconds

    hbase(main):019:0> scan 'student'

    ROW                        COLUMN+CELL                                                               

    1                        column=info:id, timestamp=1556032332227, value=1                           

    1                        column=info:name, timestamp=1556032361655, value=zhangsan                 

    2                        column=info:id, timestamp=1556032380941, value=2                           

    2                        column=info:name, timestamp=1556032405776, value=lisi                     

    2 row(s) in 0.0490 seconds

    建立hbase和hive的映射

    hive> CREATE EXTERNAL TABLE ex_student(key int, id int, name string) 

        > STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' 

        > WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key, info:id,info:name") 

        > TBLPROPERTIES ("hbase.table.name" = "student"); 

    hive> CREATE EXTERNAL TABLE ex_student(key int, id int, name string)

        > STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' 

        > WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key, info:id,info:name") 

        > TBLPROPERTIES ("hbase.table.name" = "student"); 

    OK

    Time taken: 5.019 seconds

    hive> select * from ex_student;

    OK

    1 1 zhangsan

    2 2 lisi

    Time taken: 1.072 seconds, Fetched: 2 row(s)

    hive>

    文件结构

            # sudo -u hdfs hadoop fs -ls /user/hive/warehouse/

    Found 6 items

    drwxrwxrwt  - root supergroup          0 2020-07-03 23:19 /user/hive/warehouse/ex_student

    drwxrwxrwt  - root supergroup          0 2020-07-03 23:18 /user/hive/warehouse/h_employee

    drwxrwxrwt  - root supergroup          0 2020-07-03 22:03 /user/hive/warehouse/partition_student

    drwxrwxrwt  - root supergroup          0 2020-07-03 22:49 /user/hive/warehouse/test

    drwxrwxrwt  - root supergroup          0 2020-07-03 23:06 /user/hive/warehouse/test_bucket

    drwxrwxrwt  - root supergroup          0 2020-07-03 21:42 /user/hive/warehouse/worker

    # sudo -u hdfs hadoop fs -ls /user/hive/warehouse/ex_student/

    因为是映射,看不到存储的文件。

    相关文章

      网友评论

          本文标题:11.Hadoop:Hive基本使用

          本文链接:https://www.haomeiwen.com/subject/rcreqktx.html