HBase(三)shell 命令基本操作

进入HBase客户端命令操作界面

  • hadoop100执行以下命令,进入HBase的shell客户端
cd /opt/pkg/hbase-2.2.6/
bin/hbase shell

help 帮助命令

help
# 查看具体命令的帮助信息
help 'create'

list 查看有哪些表

  • 查看当前数据库中有哪些表
list

create 创建表

  • 创建user表,包含info、data两个列族
  • 使用create命令
create 'user', 'info', 'data'

#或者

create 'user',{NAME => 'info', VERSIONS => '3'},{NAME => 'data'}

put 插入数据操作

  • 向表中插入数据
  • 使用put命令
#向user表中插入信息,row key为rk0001,列族info中添加名为name的列,值为zhangsan
put 'user', 'rk0001', 'info:name', 'zhangsan'

#向user表中插入信息,row key为rk0001,列族info中添加名为gender的列,值为female
put 'user', 'rk0001', 'info:gender', 'female'

#向user表中插入信息,row key为rk0001,列族info中添加名为age的列,值为20
put 'user', 'rk0001', 'info:age', 20

#向user表中插入信息,row key为rk0001,列族data中添加名为pic的列,值为picture
put 'user', 'rk0001', 'data:pic', 'picture'

查询数据操作

  1. 通过rowkey进行查询
  • 获取user表中row key为rk0001的所有信息(即所有cell的数据)
  • 使用get命令
get 'user', 'rk0001'
  1. 查看rowkey下某个列族的信息
  • 获取user表中row key为rk0001,info列族的所有信息
get 'user', 'rk0001', 'info'
  1. 查看rowkey指定列族指定字段的值
  • 获取user表中row key为rk0001,info列族的name、age列的信息
get 'user', 'rk0001', 'info:name', 'info:age'
  1. 查看rowkey指定多个列族的信息
  • 获取user表中row key为rk0001,info、data列族的信息
get 'user', 'rk0001', 'info', 'data'

#或者你也可以这样写
get 'user', 'rk0001', {COLUMN => ['info', 'data']}

#或者你也可以这样写,也行
get 'user', 'rk0001', {COLUMN => ['info:name', 'data:pic']}
  1. 指定rowkey与列值过滤器查询
  • 获取user表中row key为rk0001,cell的值为zhangsan的信息
get 'user', 'rk0001', {FILTER => "ValueFilter(=, 'binary:zhangsan')"}
  1. 指定rowkey与列名模糊查询
  • 获取user表中row key为rk0001,列标示符中含有a的信息
get 'user', 'rk0001', {FILTER => "QualifierFilter(=,'substring:a')"}
  1. 查询所有行的数据
  • 查询user表中的所有信息
  • 使用scan命令
scan 'user'
  1. 列族查询
  • 查询user表中列族为info的信息
scan 'user', {COLUMNS => 'info'}

#当把某些列的值删除后,具体的数据并不会马上从存储文件中删除;查询的时候,不显示被删除的数据;如果想要查询出来的话,RAW => true
scan 'user', {COLUMNS => 'info', RAW => true, VERSIONS => 5}

scan 'user', {COLUMNS => 'info', RAW => true, VERSIONS => 3}
  1. 多列族查询
  • 查询user表中列族为info和data的信息
scan 'user', {COLUMNS => ['info', 'data']}
  1. 指定列族与某个列名查询
  • 查询user表中列族为info、列标示符为name的信息
scan 'user', {COLUMNS => 'info:name'}
  • 查询info:name列、data:pic列的数据
scan 'user', {COLUMNS => ['info:name', 'data:pic']}
  • 查询user表中列族为info、列标示符为name的信息,并且版本最新的5个
scan 'user', {COLUMNS => 'info:name', VERSIONS => 5}
  1. 指定多个列族与条件模糊查询
  • 查询user表中列族为info和data且列标示符中含有a字符的信息
scan 'user', {COLUMNS => ['info', 'data'], FILTER => "QualifierFilter(=,'substring:a')"}
  1. 指定rowkey的范围查询
  • 查询user表中列族为info,rk范围是[rk0001, rk0003)的数据
scan 'user', {COLUMNS => 'info', STARTROW => 'rk0001', ENDROW => 'rk0003'}
  1. 指定rowkey模糊查询
  • 查询user表中row key以rk字符开头的数据
scan 'user',{FILTER=>"PrefixFilter('rk')"}
  1. 指定数据版本的范围查询
  • 查询user表中指定范围的数据(前闭后开)
scan 'user', {TIMERANGE => [1392368783980, 1610288780669]}

更新数据操作

  1. 更新数据值
  • 更新操作同插入操作一模一样,只不过有数据就更新,没数据就添加
  • 使用put命令
  1. 更新版本号
  • 将user表的info列族版本数改为5
alter 'user', NAME => 'info', VERSIONS => 5

删除数据以及删除表操作

  1. 指定rowkey以及列名进行删除
  • 删除user表row key为rk0001,列标示符为info:name的数据
delete 'user', 'rk0001', 'info:name'
  1. 指定rowkey,列名以及版本号进行删除
  • 删除user表row key为rk0001,列标示符为info:name,timestamp为1392383705316的数据
delete 'user', 'rk0001', 'info:name', 1392383705316
  1. 删除一个列族
  • 删除一个列族:
alter 'user', NAME => 'data', METHOD => 'delete' 
#或 
alter 'user', 'delete' => 'info'
  1. 清空表数据
truncate 'user'
  1. 删除表
  • 首先需要先让该表为disable状态,使用命令:
disable 'user'
  • 然后使用drop命令删除这个表
drop 'user'

(注意:如果直接drop表,会报错:Drop the named table. Table must first be disabled)

统计一张表有多少行数据

count 'user'

HBase的高级shell管理命令

status
  • 例如:显示服务器状态
status 'hadoop100'
whoami
  • 显示HBase当前用户,例如:
whoami
list
  • 显示当前所有的表
list
count
  • 统计指定表的记录数,例如:
count 'user' 
describe
  • 展示表结构信息
describe 'user'
exists
  • 检查表是否存在,适用于表量特别多的情况
exists 'user'
is_enabled、is_disabled
  • 检查表是否启用或禁用
is_enabled 'user'
is_disabled 'user'
alter
  • 该命令可以改变表和列族的模式,例如:

  • 为当前表增加列族:

alter 'user', NAME => 'CF2', VERSIONS => 2
  • 为当前表删除列族:
alter 'user', 'delete' => 'CF2'
disable/enable
  • 禁用一张表/启用一张表
disable 'user'
enable 'user'
drop
  • 删除一张表,记得在删除表之前必须先禁用
truncate
  • 禁用表-删除表-创建表

Views: 24

HBase(二)数据模型和整体架构

HBase表的数据模型

hbase表 模型.xlsx

rowkey行键

  • table的主键,table中的记录按照rowkey 的字典序进行排序
  • Row key行键可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes)

Column Family列族

  • 列族或列簇
  • HBase表中的每个列,都归属与某个列族
  • 列族是表的schema的一部分(而列不是),即建表时至少指定一个列族
  • 比如创建一张表,名为user,有两个列族,分别是infodata,建表语句create 'user', 'info', 'data'

Column列

  • 列肯定是表的某一列族下的一个列,用列族名:列名表示,如info列族下的name列,表示为info:name
  • 属于某一个ColumnFamily,类似于我们mysql当中创建的具体的列

cell单元格

  • 指定row key行键、列族、列,可以确定的一个cell单元格

  • cell中的数据是没有类型的,全部是以字节数组进行存储

Timestamp时间戳

  • 可以对表中的Cell多次赋值,每次赋值操作时的时间戳timestamp,可看成Cell值的版本号version number
  • 即一个Cell可以有多个版本的值

HBase整体架构

Client客户端

  • Client是操作HBase集群的入口
    • 对于管理类的操作,如表的增、删、改操纵,Client通过RPC与HMaster通信完成
    • 对于表数据的读写操作,Client通过RPC与RegionServer交互,读写数据
  • Client类型:
    • HBase shell
    • Java编程接口
    • Thrift、Avro、Rest等等

ZooKeeper集群

  • 作用

    • 实现了HMaster的高可用,多HMaster间进行主备选举

    • 保存了HBase的元数据信息meta表,提供了HBase表中region的寻址入口的线索数据

    • 对HMaster和HRegionServer实现了监控

HMaster

  • HBase集群也是主从架构,HMaster是主的角色,是老大
  • 主要负责Table表和Region的相关管理工作:
  • 关于Table
    • 管理Client对Table的增删改的操作
    • 关于Region
    • 在Region分裂后,负责新Region分配到指定的HRegionServer上
    • 管理HRegionServer间的负载均衡,迁移region分布
    • 当HRegionServer宕机后,负责其上的region的迁移

HRegionServer

  • HBase集群中从的角色,是小弟
  • 作用

    • 响应客户端的读写数据请求
    • 负责管理一系列的Region
    • 切分在运行过程中变大的region

Region

  • HBase集群中分布式存储的最小单元

  • 一个Region对应一个Table表的部分数据

Views: 22

HBase(一)介绍和安装

HBase介绍

HBase基于Google的BigTable论文,是建立的HDFS之上,提供高可靠性、高性能、列存储、可伸缩、实时读写的分布式数据库系统。

在需要实时读、写随机访问、超大规模数据集时,可以使用HBase。

HBase的特点

  1. 极易扩展,海量存储
    底层依赖HDFS,当磁盘空间不足的时候,只需要动态增加datanode节点就可以了
    可以通过增加服务器来对集群的存储进行扩容
  2. 列式存储
    HBase表的数据是基于列族进行存储的,列族是在列的方向上的划分。
  3. 高并发
    支持高并发的读写请求
  4. 稀疏
    稀疏主要是针对HBase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。
  5. 数据的多版本
    HBase表中的数据可以有多个版本值,默认情况下是根据版本号去区分,版本号就是插入数据的时间戳
  6. 数据类型单一
    所有的数据在HBase中是以字节数组进行存储

Hbase在实际场景中的应用

  1. 交通方面

    船舶GPS信息,全长江的船舶GPS信息,每天有1千万左右的数据存储。

  2. 金融方面

    消费信息、贷款信息、信用卡还款信息等

  3. 电商方面

    电商网站的交易信息、物流信息、游览信息等

  4. 电信方面

    通话信息、语音详单等

总结:海量明细数据的存储,并且后期需要有很好的查询性能

HBase集群安装部署

准备安装包

[hadoop@hadoop100 ~]$ cd /opt/download
[hadoop@hadoop100 soft]$ tar -zxvf hbase-2.2.6-bin.tar.gz -C  /opt/pkg/

修改HBase配置文件

  1. hbase-env.sh

    修改文件

    [hadoop@hadoop100 softwares]$ cd /opt/pkg/hbase-2.2.6/conf
    [hadoop@hadoop100 conf]$ vim hbase-env.sh

    修改如下两项内容,值如下

    export JAVA_HOME=/opt/pkg/java
    export HBASE_MANAGES_ZK=false   
  2. hbase-site.xml

    修改文件

    [hadoop@hadoop100 conf]$ vim hbase-site.xml

    内容如下

    <configuration>
            <!-- 指定hbase在HDFS上存储的路径 -->
            <property>
                    <name>hbase.rootdir</name>
                    <value>hdfs://hadoop100:8020/hbase</value>
            </property>
            <!-- 指定hbase是否分布式运行 -->
            <property>
                    <name>hbase.cluster.distributed</name>
                    <value>true</value>
            </property>
            <!-- 指定zookeeper的地址,多个用“,”分割 -->
            <property>
                    <name>hbase.zookeeper.quorum</name>
                    <value>hadoop100,hadoop101,hadoop102:2181</value>
            </property>
            <!--指定hbase管理页面-->
            <property>
                  <name>hbase.master.info.port</name>
                  <value>16010</value>
            </property>
            <!-- 在分布式的情况下一定要设置,不然容易出现Hmaster起不来的情况 -->
            <property>
                    <name>hbase.unsafe.stream.capability.enforce</name>
                    <value>false</value>
            </property>
    </configuration>
  3. regionservers

    修改文件

    [hadoop@hadoop100 conf]$ vim regionservers

    指定HBase集群的从节点;原内容清空,添加如下两行

    hadoop101
    hadoop102
  4. back-masters

    创建back-masters配置文件,里边包含备份HMaster节点的主机名,每个机器独占一行,实现HMaster的高可用

    [hadoop@hadoop100 conf]$ vim backup-masters

    将hadoop101作为备份的HMaster节点,问价内容如下

    hadoop101

分发安装包

  • 将 hadoop100上的HBase安装包,拷贝到其他机器上
[hadoop@hadoop100 conf]$ cd /opt/pkg
[hadoop@hadoop100 install]$ scp -r hbase-2.2.6/ hadoop101:$PWD
[hadoop@hadoop100 install]$ scp -r hbase-2.2.6/ hadoop102:$PWD

创建软连接

  • 注意:三台机器均做如下操作

因为HBase集群需要读取hadoop的core-site.xml、hdfs-site.xml的配置文件信息,所以我们==三台机器==都要执行以下命令,在相应的目录创建这两个配置文件的软连接

ln -s /opt/pkg/hadoop-3.1.4/etc/hadoop/core-site.xml  /opt/pkg/hbase-2.2.6/conf/core-site.xml

ln -s /opt/pkg/hadoop-3.1.4/etc/hadoop/hdfs-site.xml  /opt/pkg/hbase-2.2.6/conf/hdfs-site.xml

执行完后,出现如下效果,以hadoop100为例

file

添加HBase环境变量

注意:三台机器均执行以下命令,添加环境变量

sudo vim /etc/profile

文件末尾添加如下内容

export HBASE_HOME=/opt/pkg/hbase-2.2.6
export PATH=$PATH:$HBASE_HOME/bin

重新编译/etc/profile,让环境变量生效

source /etc/profile

HBase的启动与停止

需要提前启动HDFS及ZooKeeper集群

  • 如果没开启hdfs,请在hadoop100运行start-dfs.sh命令
  • 如果没开启zookeeper,请在3个节点分别运行zkServer.sh start命令
    • 第一台机器hadoop100(HBase主节点)执行以下命令,启动HBase集群
      [hadoop@hadoop100 ~]$ start-hbase.sh
  • 启动完后,jps查看HBase相关进程
    hadoop100hadoop101上有进程HMasterHRegionServer
    hadoop102上有进程HRegionServer

警告提示:HBase启动的时候会产生一个警告,这是因为jdk7与jdk8的问题导致的,如果linux服务器安装jdk8就会产生这样的一个警告
file
可以注释掉所有机器的hbase-env.sh当中的 “HBASE_MASTER_OPTS”和“HBASE_REGIONSERVER_OPTS”配置 来解决这个问题。不过警告不影响我们正常运行,可以忽略。

我们也可以执行以下命令,单节点启动相关进程

#HMaster节点上启动HMaster命令
hbase-daemon.sh start master

#启动HRegionServer命令
hbase-daemon.sh start regionserver

访问WEB页面

浏览器页面访问 http://hadoop100:16010

file

停止HBase集群

停止HBase集群的正确顺序

hadoop100上运行,关闭hbase集群

[hadoop@hadoop100 ~]$ stop-hbase.sh
  • 关闭ZooKeeper集群
  • 关闭Hadoop集群
  • 关闭虚拟机
  • 关闭笔记本

Views: 45

电商日志分析项目 – 04 日志的抽取(Sqoop)

Sqoop 安装

参考SQOOP安装配置

编写Sqoop脚本

点击UI界面Sqoop导出时需要输入导出的源路径,存储位置:

/tmp/project-mapred-result.txt

然后编写Sqoop脚本如下:

#!/bin/bash
/opt/pkg/sqoop/bin/sqoop export \
--connect jdbc:mysql://192.168.186.100:3306/shop \
--username root \
--password niit1234 \
--input-fields-terminated-by '\t' \
--table t_mr_result \
--export-dir $(cat /tmp/project-mapred-result.txt) \
--class-name UpsertMrResult \
--update-key goodsId --update-mode allowinsert

等待一段时间执行完成,查看mysql数据是否发生更新

Views: 96

电商日志分析项目 – 03 日志的分析(MapReduce)

MapReduce工程代码

  1. 创建maven工程
    在项目根目录下创建input文件夹,创建一个文本文件access.log用来模拟nginx日志

    hadoop100,192.168.186.100 - - [21/Apr/2021:01:36:19 +0800] "GET /shop/detail.html?id=4028f00176e1aa620176e6aca6890003 HTTP/1.0" 200 4366 "-" "ApacheBench/2.3" "-"
    hadoop100,192.168.186.100 - - [21/Apr/2021:01:36:19 +0800] "GET /shop/detail.html?id=4028f00176e1aa620176e6aca6890003 HTTP/1.0" 200 4366 "-" "ApacheBench/2.3" "-"
    hadoop100,192.168.186.100 - - [21/Apr/2021:01:36:19 +0800] "GET /shop/detail.html?id=4028f00176e1aa620176e6aca6890003 HTTP/1.0" 200 4366 "-" "ApacheBench/2.3" "-"
    hadoop100,192.168.186.100 - - [21/Apr/2021:01:36:19 +0800] "GET /shop/detail.html?id=4028f00176e1aa620176e6aca6890003 HTTP/1.0" 200 4366 "-" "ApacheBench/2.3" "-"
    hadoop100,192.168.186.100 - - [21/Apr/2021:01:36:19 +0800] "GET /shop/detail.html?id=4028f00176e1aa620176e6aca6890003 HTTP/1.0" 200 4366 "-" "ApacheBench/2.3" "-"
  2. 引入maven依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>log</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <!--定义Hadoop版本-->
            <hadoop.version>3.1.4</hadoop.version>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <!---引入cdh的仓库-->
        <repositories>
            <repository>
                <id>cloudera</id>
                <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
            </repository>
        </repositories>
    
        <dependencies>
            <!--添加Hadoop依赖包-->
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-client</artifactId>
                <version>${hadoop.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-common</artifactId>
                <version>${hadoop.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-hdfs</artifactId>
                <version>${hadoop.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-mapreduce-client-core</artifactId>
                <version>${hadoop.version}</version>
            </dependency>
            <!--添加JUnit4依赖包-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    </project>
  3. 添加log4j.properties文件在资源目录下即resources,文件内容如下
    ### 配置根 ###
    log4j.rootLogger = debug,console,fileAppender
    ## 配置输出到控制台 ###
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    log4j.appender.console.Target = System.out
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern = %d{ABSOLUTE} %5p %c:%L - %m%n
    ### 配置输出到文件 ###
    log4j.appender.fileAppender = org.apache.log4j.FileAppender
    log4j.appender.fileAppender.File = /tmp/logs/log.log
    log4j.appender.fileAppender.Append = false
    log4j.appender.fileAppender.Threshold = DEBUG,INFO,WARN,ERROR
    log4j.appender.fileAppender.layout = org.apache.log4j.PatternLayout
    log4j.appender.fileAppender.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
  4. 编写MR程序之Mapper:LogMapper.java

    package com.niit.log;
    
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Mapper;
    
    import java.io.IOException;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class LogMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
        // 按指定模式在字符串查找
        String pattern = "\\?id=[0-9a-z]*";
        // 创建 Pattern 对象
        Pattern r = Pattern.compile(pattern);
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String data = value.toString();
            // 现在创建 matcher 对象
            Matcher m = r.matcher(data);
            if (m.find()) {
                String idStr = m.group(0);
                String id = idStr.substring(4);
                context.write(new Text(id),new IntWritable(1));
            }
        }
    }   
  5. 编写MR程序之Mapper:LogReducer.java

    package com.niit.log;
    
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Reducer;
    
    import java.io.IOException;
    
    public class LogReducer extends Reducer<Text, IntWritable,Text, IntWritable> {
    
        @Override
        protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            int sum = 0;
            for (IntWritable v: values) {
                sum += v.get();
            }
            context.write(key,new IntWritable(sum));
        }
    }
  6. 编写MR程序之Job:LogJob.java

    package com.niit.log;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    
    public class LogJob {
        public static void main(String[] args) throws Exception {
    
            // Windows
            System.setProperty("HADOOP_USER_NAME", "hadoop");
    
            // Linux
            // if (args.length < 2) {
            //     System.out.println("Usage:hadoop jar Log.jar " + LogJob.class.getName() + " input ouput");
            //     System.exit(0);
            // }
    
            Configuration configuration = new Configuration();
            Job job = Job.getInstance(configuration);
            job.setJarByClass(LogJob.class);
    
            job.setMapperClass(LogMapper.class);
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(IntWritable.class);
    
            job.setReducerClass(LogReducer.class);
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(IntWritable.class);
    
            FileSystem fileSystem = FileSystem.get(configuration);
    
            // Windows
            Path inputPath = new Path("./input/access.log");
            Path outputPath = new Path("./output/");
    
            // Linux
            // Path inputPath = new Path(args[0]);
            // Path outputPath = new Path(args[1]);
    
            if (fileSystem.exists(outputPath)) {
                fileSystem.delete(outputPath, true);
            }
    
            // Windwos
            FileInputFormat.setInputPaths(job, inputPath);
            FileOutputFormat.setOutputPath(job, outputPath);
    
            // Linux
            // FileInputFormat.setInputPaths(job, new Path(args[0]));
            // FileOutputFormat.setOutputPath(job, new Path(args[1]));
    
            boolean completion = job.waitForCompletion(true);
            System.exit(completion ? 0 : -1);
        }
    }
  7. 本地运行代码,测试下结果正确与否
  8. 本地运行测试结果正确后,需要对Driver类输入输出部分代码进行修改,具体修改如下:

    // Windows
    // System.setProperty("HADOOP_USER_NAME", "hadoop");
    
    // Linux
    if (args.length < 2) {
        System.out.println("Usage:hadoop jar Log.jar " + LogJob.class.getName() + " input ouput");
        System.exit(0);
    }
    
    // Windows
    // Path inputPath = new Path("./input/access.log");
    // Path outputPath = new Path("./output/");
    
    // Linux
    Path inputPath = new Path(args[0]);
    Path outputPath = new Path(args[1]);
    
    // Windwos
    // FileInputFormat.setInputPaths(job, inputPath);
    // FileOutputFormat.setOutputPath(job, outputPath);
    
    // Linux
    FileInputFormat.setInputPaths(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
  9. 打jar包,提交集群运行
    直接使用maven的生命周期的package工具构建jar包,并上传到服务器的/opt/data目录下,改名为Log.jar
  10. 为方便操作,编写脚本/opt/bin/project/exec-mapred-task.sh来执行MR程序

    
    #!/bin/bash
    
    input_path=$(cat /tmp/project-mapred-input-path.txt)
    
    #执行MapReduce程序
    dataformat=`date +%y-%m-%d`
    echo "/opt/pkg/hadoop/bin/hadoop jar /opt/data/log.jar com.niit.log.LogJob $input_path /output/result/$dataformat"
    /opt/pkg/hadoop/bin/hadoop jar /opt/data/log.jar com.niit.log.LogJob $input_path /output/result/$dataformat
    /opt/pkg/hadoop/bin/hdfs dfs -cat /output/result/$dataformat/part-r-00000 > /tmp/project_mr_result.txt
    
    echo "======== mapred task result ========"
    echo $(cat /tmp/project_mr_result.txt)

Views: 256