hadoop-3.2.2hive-3.1.2hbase-

一、虚拟机环境

1.1 校园网 NAT 配置静态 IP

参考:

需要注意的是:共享网卡时无法开启热点,可以选择在有开启热点需求的时候取消网卡共享,之后再重新启用网卡共享。

教主 VMnet8 网卡分配到的 IP 为 192.168.137.1/24,因此将虚拟机的 VMnet8 子网网段设置为 192.168.137.0/24,并且习惯性的选择将网关 IP 设置为和宿主机的 VMnet8 网卡相同。

1.2 安装 ubuntu-20.04

参考:VM安装ubuntu-20.04-live-server-amd64.iso

镜像源选择:http://mirrors.aliyun.com/ubuntu

尽量在安装阶段就配置好静态 IP、hostname、镜像源等,可以方便后续的修改。

静态 IP

ip addr
vim /etc/netplan/00-installer-config.yaml
复制代码
network:
  ethernets:
    ens33:
      addresses:
      - 192.168.137.100/24
      gateway4: 192.168.137.1
      nameservers:
        addresses:
        - 192.168.137.1
        search: []
  version: 2
复制代码

需要注意的是:VIM 对 YAML 的默认格式化效果不是特别理想,可以考虑手动调整缩进。

netplan apply
复制代码

hostname

hostnamectl set-hostname ubuntu
# 重新登录
复制代码

镜像源

参考:[Linux]Ubuntu 20.04换阿里源

vim /etc/apt/sources.list
复制代码
deb http://mirrors.aliyun.com/ubuntu focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu focal-updates main restricted  universe multiverse
deb http://mirrors.aliyun.com/ubuntu focal-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu focal-security main restricted universe multiverse
复制代码

启用 root SSH

# 设置 root 密码
sudo passwd root

# 取消 PermitRootLogin 的注释并将其值改为 yes
sudo vim /etc/ssh/sshd_config

# 重启 sshd
sudo systemctl restart sshd
复制代码

root 用户没有 bash 颜色高亮:

sudo cp /etc/skel/.bashrc /root

# 取消 force_color_prompt=yes 的注释
sudo vim /root/.bashrc

# 重新登录
复制代码

hosts

vim /etc/hosts
复制代码
# ...
192.168.137.1   win10
192.168.137.101 node101
192.168.137.102 node102
192.168.137.103 node103
复制代码

需要注意的是:为了通过网页正常访问 HDFS 也需要在宿主机(C:\Windows\System32\drivers\etc\hosts)配置域名的解析。

SSH 免密登录

# node101 node102 node103
ssh-keygen -t rsa
ssh-copy-id root@node101
ssh-copy-id root@node102
ssh-copy-id root@node103
复制代码

安装 open-jdk8

apt install openjdk-8-jdk
复制代码

默认安装位置在 usr/lib/jvm/java-8-openjdk-amd64

vim /etc/profile
复制代码
# ...
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
复制代码
source /etc/profile && source ~/.bashrc
复制代码

1.3 SSH 和 FTP 方案

Windows Terminal

文档:Windows / 开发环境 / Windows 终端 / 概述

Cascadia Code 字体:github.com/microsoft/c…

为了弥补 “将命令发送到所有窗口” 的功能缺失,可以拿一些脚本来替代:

vim ~/bin/cluster.sh
复制代码
#!/bin/bash

case $1 in
exec)
    for host in node101 node102 node103; do
        echo "========== ${host} =========="
        ssh "${host}" "${@:2}"
    done
    ;;
rsync)
    for host in node101 node102 node103; do
        if [[ "$(hostname)" != "${host}" ]]; then
            echo "========== ${host} =========="
            rsync -a -r -v "$2" "${host}":"$2/../"
        fi
    done
    ;;
esac
复制代码
chmod 777 ~/bin/cluster.sh
复制代码
~/bin/cluster.sh exec "jps"
~/bin/cluster.sh rsync "$HADOOP_HOME/etc"
复制代码

需要宿主机和虚拟机传输文件的时候可能就不得不借助一些工具了,比如 XFTP、MobaXterm 等。不过当然也可以有一些其它的办法。

sftp

cd <local_dir>

sftp <user>@<host>

cd <remote_dir>

put -r <local_dir>

get -r <remote_file>
复制代码

Nginx 文件服务器 + curl

# ...
http {
    # ...
    server {
        # ...
        root /usr/share/nginx/html;
        charset utf-8;
        # ...
        location /public {
            autoindex on;
            autoindex_localtime on;
            autoindex_exact_size off;
        }
    }
}
复制代码
curl <url> -o <filename>
复制代码

Docker

docker cp <local_file> <container_id | container_name>:<container_dir>

docker cp <container_id | container_name>:<container_file> <local_dir>
复制代码

1.4 其它

VIM

vim /etc/vim/vimrc
复制代码
" ...
filetype plugin indent on

set showcmd
set showmatch
set ignorecase
set smartcase
set incsearch
set autowrite
set hidden

set number
set ruler
set expandtab
set tabstop=4
set cursorline
set confirm 
set hlsearch
复制代码

时区

timedatectl set-timezone Asia/Shanghai

timedatectl
复制代码

二、Hadoop

2.1 安装 hadoop-3.2.2

文档:

curl https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.2.2/hadoop-3.2.2.tar.gz -o hadoop-3.2.2.tar.gz

mkdir /opt/hadoop

tar -zxvf hadoop-3.2.2.tar.gz -C /opt/hadoop
复制代码
vim /etc/profile
复制代码
# ...
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

export HADOOP_HOME=/opt/hadoop/hadoop-3.2.2
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
复制代码

2.2 Zookeeper 集群

可以直接在宿主机启动一份 docker-compose:

version: '3'

services:
  zk1:
    image: zookeeper:3.7
    hostname: zk1
    ports:
      - 2181:2181
    volumes:
      - ./zk1/data/:/data/
      - ./zk1/datalog/:/datalog/
    environment:
      ZOO_MY_ID: 1
      ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zk2:2888:3888;2181 server.3=zk3:2888:3888;2181

  zk2:
    image: zookeeper:3.7
    hostname: zk2
    ports:
      - 2182:2181
    volumes:
      - ./zk2/data/:/data/
      - ./zk2/datalog/:/datalog/
    environment:
      ZOO_MY_ID: 2
      ZOO_SERVERS: server.1=zk1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zk3:2888:3888;2181

  zk3:
    image: zookeeper:3.7
    hostname: zk3
    ports:
      - 2183:2181
    volumes:
      - ./zk3/data/:/data/
      - ./zk3/datalog/:/datalog/
    environment:
      ZOO_MY_ID: 3
      ZOO_SERVERS: server.1=zk1:2888:3888;2181 server.2=zk2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181

networks:
  default:
    external: true
    name: local_net
复制代码
docker network create local_net

docker-compose up -d
复制代码

2.3 Hadoop 集群

配置文件

默认配置文件:

参考:

hadoop-env.sh
vim $HADOOP_HOME/etc/hadoop/hadoop-env.sh
复制代码
# ...
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
# ...
export HDFS_NAMENODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_JOURNALNODE_USER=root
export HDFS_ZKFC_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
复制代码
workers
vim $HADOOP_HOME/etc/hadoop/workers
复制代码
node101
node102
node103
复制代码
core-site.xml
vim $HADOOP_HOME/etc/hadoop/core-site.xml
复制代码
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hdfs-cluster</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/hadoop/hadoop-3.2.2/tmp</value>
    </property>
    <property>
        <name>hadoop.http.staticuser.user</name>
        <value>root</value>
    </property>

    <!-- HDFS zookeeper 地址 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>win10:2181,win10:8182,win10:2183</value>
    </property>

    <!-- YARN zookeeper 地址 -->
    <property>
        <name>hadoop.zk.address</name>
        <value>win10:2181,win10:2182,win10:2183</value>
    </property>
</configuration>
复制代码

需要注意的是:hadoop.tmp.dir 不能引用环境变量。

hdfs-site.xml
vim $HADOOP_HOME/etc/hadoop/hdfs-site.xml
复制代码
<configuration>
    <!-- HDFS HA -->
    <property>
        <name>dfs.nameservices</name>
        <value>hdfs-cluster</value>
    </property>
    <property>
        <name>dfs.ha.namenodes.hdfs-cluster</name>
        <value>nn1,nn2,nn3</value>
    </property>

    <!-- NameNode RPC 通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.hdfs-cluster.nn1</name>
        <value>node101:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.hdfs-cluster.nn2</name>
        <value>node102:8020</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.hdfs-cluster.nn3</name>
        <value>node103:8020</value>
    </property>

    <!-- NameNode HTTP 通信地址 -->
    <property>
        <name>dfs.namenode.http-address.hdfs-cluster.nn1</name>
        <value>node101:9870</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.hdfs-cluster.nn2</name>
        <value>node102:9870</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.hdfs-cluster.nn3</name>
        <value>node103:9870</value>
    </property>

    <!-- JournalNode -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://node101:8485;node102:8485;node103:8485/hdfs-cluster</value>
    </property>
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/opt/hadoop/hadoop-3.2.2/tmp/dfs/journalnode/</value>
    </property>

    <!-- 脑裂问题隔离机制 -->
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>
            sshfence
            shell(/bin/true)
        </value>
    </property>
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/root/.ssh/id_rsa</value>
    </property>

    <!-- HDFS 自动故障转移 -->
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>dfs.client.failover.proxy.provider.hdfs-cluster</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
</configuration>
复制代码
mapred-site.xml
vim $HADOOP_HOME/etc/hadoop/mapred-site.xml
复制代码
<configuration>
    <property>
        <name>yarn.app.mapreduce.am.env</name>
        <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
    </property>
    <property>
        <name>mapreduce.map.env</name>
        <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
    </property>
    <property>
        <name>mapreduce.reduce.env</name>
        <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
    </property>

    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>
复制代码
yarn-site.xml
vim $HADOOP_HOME/etc/hadoop/yarn-site.xml
复制代码
<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>

    <!-- ResourceManager HA -->
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>

    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>yarn-cluster</value>
    </property>
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2,rm3</value>
    </property>

    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>node101</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>node102</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm3</name>
        <value>node103</value>
    </property>

    <property>
        <name>yarn.resourcemanager.webapp.address.rm1</name>
        <value>node101:8088</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm2</name>
        <value>node102:8088</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm3</name>
        <value>node103:8088</value>
    </property>

    <!-- ResourceManager 自动恢复 -->
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.resourcemanager.store.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>
</configuration>
复制代码

日志聚集

mapred-site.xml
<configuration>
    <!-- ... -->

    <!-- JobHistoryServer -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>node101:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>node101:19888</value>
    </property>
</configuration>
复制代码
yarn-site.xml
<configuration>
    <!-- ... -->

    <!-- 日志聚集 -->
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.log.server.url</name>
        <value>http://node101:19888/jobhistory/logs</value>
    </property>
    <!-- 3600 * 24 * 7 -->
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>604800</value>
    </property>
</configuration>
复制代码

同步配置文件

# node101
rsync -a -r -v $HADOOP_HOME/etc node102:$HADOOP_HOME
rsync -a -r -v $HADOOP_HOME/etc node103:$HADOOP_HOME
复制代码

初始化集群

# 启动 JournalNode
# node101 node102 node103
hdfs --daemon start journalnode

# 格式化 NameNode
# node101
hdfs namenode -format

# 同步 NameNode 元数据
# node101
hdfs --daemon start namenode
# node102 node103
hdfs namenode -bootstrapStandby

# 格式化 ZookeeperFailoverController
# node101
hdfs zkfc -formatZK
复制代码

需要注意的:重新格式化前需要先删除 tmp 和 logs 目录:

rm -rf $HADOOP_HOME/tmp $HADOOP_HOME/logs
复制代码

启动集群

参考:hadoop ha模式下,kill active的namenode节点后,standby的namenode节点没能自动启动

# node101
start-dfs.sh
start-yarn.sh
mapred --daemon start historyserver
复制代码

单独启动:

hdfs --daemon <start|stop> namenode
hdfs --daemon <start|stop> secondarynamenode
hdfs --daemon <start|stop> datanode

yarn --daemon <start|stop> resourcemanager
yarn --daemon <start|stop> nodemanager

mapred --daemon <start|stop> historyserver
复制代码

查看 HA 状态:

hdfs haadmin -getAllServiceState

yarn rmadmin -getAllServiceState
复制代码

WordCount

cd $HADOOP_HOME
mkdir input
echo -e "i keep saying no\nthis can not be the way it was supposed to be\ni keep saying no\nthere has gotta be a way to get you close to me" > input/word.txt

hadoop fs -mkdir /input

hadoop fs -put input/word.txt /input
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.2.jar wordcount /input /output
复制代码

2.4 HDFS

HDFS 组成架构

在这里插入图片描述

NameNode
  • 管理 HDFS 的名称空间
  • 配置副本策略
  • 管理数据块映射信息
  • 处理客户端读写请求
DataNode
  • 存储实际的数据块
  • 执行数据块(Block)的读 / 写操作
SecondaryNameNode
  • 复制 NameNode,分担其工作量,比如定期合并 Fsimage 和 Edits,并推送给 NameNode
  • 在紧急情况下,可辅助恢复 NameNode
Client
  • 文件切分:文件上传到 HDFS 的时候,Client 将文件切分成一个一个的 Block,然后进行上传
  • 与 NameNode 交互,获取文件的位置信息
  • 与 DataNode 交互,读取或者写入数据
  • Client 提供一些命令来管理 HDFS,比如 NameNode 格式化
  • Client 可以通过一些命令来访问 HDFS,比如对 HDFS 的增删改查操作

HDFS 常用命令

文档:FileSystemShell

# 剪切上传
hadoop fs -moveFromLocal <local_file> <hdfs_dir>

# 复制上传
hadoop fs -copyFromLocal <local_file> <hdfs_dir>
hadoop fs -put <local_file> <hdfs_dir>

# 追加上传
hadoop fs -appendToFile <local_file> <hdfs_file>

# 下载
hadoop fs -copyToLocal <hdfs_file> <local_dir>
hadoop fs -get <hdfs_file> <local_dir>

# 设置副本数量
hadoop fs -setrep <replication> <hdfs_file>
复制代码

HDFS Java API

参考:Install Hadoop 3.3.0 on Windows 10 Step by Step Guide

下载:github.com/kontext-tec…

pom.xml

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>3.2.2</version>
</dependency>
复制代码

查看文件状态:

public static void main(String[] args) throws IOException, InterruptedException {
    FileSystem fs = FileSystem.get(URI.create("hdfs://node101:8020"), new Configuration(), "root");
    FileStatus status = fs.getFileStatus(new Path("/input/word.txt"));
    System.out.println(status);
    fs.close();
}
复制代码

2.5 MapReduce

MapReduce 进程

一个完整的 MapReduce 程序在分布式运行时有三类实例进程:

  • ApplicationMaster:负责整个程序的过程调度及状态协调
  • MapTask:负责 Map 阶段的整个数据处理流程
  • ReduceTask:负责 Reduce 阶段的整个数据处理流程

MapTask 工作机制

  1. Read 阶段

    MapTask 通过 InputFormat 获得的 RecordReader InputSplit 中解析出一个个 KV。

  2. Map 阶段

    该阶段主要是将解析出的 KV 交给用户编写的 map()函数处理,并产生一系列新的 KV。

  3. Collect 阶段

    在用户编写的map()函数中,当数据处理完成后,一般会调用 OutputCollector.collect() 输出结果。

    在该函数内部,它会将生成的 KV 进行分区,并写入到一个环形缓冲区中。

  4. Spill 阶段

    即溢写,当环形缓存区满后,MapReduce 会将数据写到本地磁盘上,生成一个临时文件。

    需要注意的是,将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并、压缩等操作。

ReduceTask 工作机制

  1. Copy 阶段

    ReduceTask 从各个 MapTask 上远程拷贝一片数据,如果其大小超过一定阈值则写到磁盘上,否则直接放到内存中。

  2. Sort 阶段

    在远程拷贝数据的同时,ReduceTask 启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。

    按照 MapReduce 语义,用户编写的 reduce() 函数输入数据是按 Key 进行聚集的一组数据。

    为了将 Key 相同的疏忽聚在一起,Hadoop 采用了基于排序的策略。

    由于各个 MapTask 已经实现对自己的处理结果进行了局部排序,因此 ReduceTask 只需对所有数据进行一次归并排序即可。

  3. Reduce 阶段

    reduce() 函数将计算结果写到 HDFS 中。

WordCount

public class WordCount {
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        Job job = Job.getInstance();

        job.setJarByClass(WordCount.class);

        job.setMapperClass(WordCount.WordCountMapper.class);
        job.setReducerClass(WordCount.WordCountReducer.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        boolean successful = job.waitForCompletion(true);
        System.exit(successful ? 0 : 1);
    }

    public static class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String line = value.toString();
            String[] words = line.split(" ");
            for (String word : words) {
                context.write(new Text(word), new IntWritable(1));
            }
        }
    }

    public static class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
        @Override
        protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            int count = 0;
            for (IntWritable value : values) {
                count += value.get();
            }
            context.write(key, new IntWritable(count));
        }
    }
}
复制代码

打包上传执行:

# 删除 /output 目录
hadoop fs -rmdir --ignore-fail-on-non-empty /output
# 执行
hadoop jar word-count-0.0.1.jar xyz.icefery.mr.wc.WordCount /input/word.txt /output
复制代码

2.6 YARN

YARN 组成架构

在这里插入图片描述

ResourceManager
  • 处理客户端请求
  • 监控 NodeManager
  • 启动或监控 ApplicationMaster
  • 资源的分配与调度
NodeManager
  • 管理单个节点上的资源
  • 处理来自 ResourceManager 的命令
  • 处理来自 ApplicationMaster 的命令
ApplicationMaster
  • 为应用程序申请资源并分配给内部的任务
  • 任务的监控与容错
Container
  • Container 是 YARN 中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等

YARN 工作机制

  1. MR 程序提交到客户端所在的节点
  2. YarnRunner 向 ResourceManager 申请一个 Application
  3. ResourceManager 将该应用程序的资源路径返回给 YarnRunner
  4. 该程序将运行所需资源提交到 HDFS 上
  5. 程序资源提交完毕后,申请运行 ApplicationMaster
  6. ResourceManager 将用户的请求初始化成一个 Task
  7. 其中一个 NodeManager 领取到 Task 任务
  8. 该 NodeManager 创建容器 Container,并产生 ApplicationMaster
  9. Container 从 HDFS 上拷贝资源到本地
  10. ApplicationMaster 向 ResourceManager 申请运行 MapTask 资源
  11. ResourceManager 将运行 MapTask 任务分配给另外两个 NodeManager,另外两个 NodeManager 分别领取任务并创建容器
  12. MR 向两个接收到任务的 NodeManager 发送程序启动脚本,这两个 NodeManager 分别启动 MapTask,MapTask 对数据进行分区排序
  13. ApplicationMaster 等待所有 MapTask 运行完毕后,向 ResourceManager 申请容器,运行 ReduceTask
  14. ReduceTask 从 MapTask 获取相应分区的数据
  15. 程序运行完毕后, MR 会向 ResourceManager 申请注销自己

三、Hive

3.1 安装 hive-3.1.2

参考:Hive启动报错:java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument

curl https://mirrors.tuna.tsinghua.edu.cn/apache/hive/hive-3.1.2/apache-hive-3.1.2-bin.tar.gz -o apache-hive-3.1.2-bin.tar.gz

mkdir /opt/hive

tar -zxvf apache-hive-3.1.2-bin.tar.gz -C /opt/hive
复制代码

环境变量:

# ...
export HIVE_HOME=/opt/hive/apache-hive-3.1.2-bin
export PATH=$PATH:$HIVE_HOME/bin
复制代码

Jar 包冲突:

rm -rf $HIVE_HOME/lib/guava-19.0.jar
cp $HADOOP_HOME/share/hadoop/common/lib/guava-27.0-jre.jar $HIVE_HOME/lib
复制代码

3.2 QuickStart

MySQL

可以直接在宿主机启动一份 MySQL 并创建 hive 元数据数据库:

create database hive;
复制代码

在 Hive 的 lib 目录添加驱动:

curl https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.24/mysql-connector-java-8.0.24.jar -o $HIVE_HOME/lib/mysql-connector-java-8.0.24.jar
复制代码

配置文件

参考:

core-site.xml
vim $HADOOP_HOME/etc/hadoop/core-site.xml
复制代码
<configuraiton>
    <!-- ... -->
    <property>
        <name>hadoop.proxyuser.root.hosts</name>
        <value>*</value>
    </property>
    <property>
        <name>hadoop.proxyuser.root.groups</name>
        <value>*</value>
    </property>
</configuraiton>
复制代码
hive-site.xml
vim $HIVE_HOME/conf/hive-site.xml
复制代码
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <property>
        <name>javax.jdo.option.ConnectionDriverName</name>
        <value>com.mysql.cj.jdbc.Driver</value>
    </property>
    <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:mysql://win10:3306/hive</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.uris</name>
        <value>thrift://node101:9083</value>
    </property>

    <property>
        <name>hive.server2.thrift.bind.host</name>
        <value>node101</value>
    </property>
</configuration>
复制代码

初始化元数据库

schematool -initSchema -dbType mysql
复制代码

启动 MetaStore

nohup hive --service metastore 1>/dev/null 2>&1 &
# 使用 jps 和 kill -9 结束
复制代码

Hive Shell

create database test;
use test;
复制代码
create table student (
    name      string,
    gender    tinyint,
    deskmates array<string>,
    score     struct<chinese:int, math:int, english:int>,
    refs      map<string, string>
) row format delimited fields terminated by '|' collection items terminated by ',' map keys terminated by ':' lines terminated by '\n';
复制代码

insert 语句:

insert into student values ('教主', 1, array('雯玉', '芳'), named_struct('chinese', 90, 'math', 90, 'english', 90), map('height', '165', 'weight', '55', 'eyesight', '0.2'));
复制代码

文件导入:

vim ~/student.txt
复制代码
芳|2|教主|120,110,120|height:165,weight:50,eyesight:1.0
雯玉|2|教主|110,120,120|height:160,weight:45,eyesight:0.2
复制代码
load data local inpath '/root/student.txt' into table student;
复制代码
select * from student;
复制代码
dfs -ls /user/hive/warehouse;
复制代码

JDBC 访问 Hive

# 启动 hiveserver2
nohup hive --service hiveserver2 1>/dev/null 2>&1 &
复制代码

WEB 界面:http://node101:10002

使用 beeline 客户端连接:

beeline -u jdbc:hive2://node101:10000 -n root
复制代码

DataGrip 也支持 Hive 连接。

查看日志:

tail -n 300 /tmp/root/hive.log
复制代码

四、HBase

4.1 安装 hbase-2.3.5

curl https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/2.3.5/hbase-2.3.5-bin.tar.gz -o hbase-2.3.5-bin.tar.gz

mkdir -p /opt/hbase

tar -zxvf hbase-2.3.5-bin.tar.gz -C /opt/hbase
复制代码

环境变量:

# ...
export HBASE_HOME=/opt/hbase/hbase-2.3.5
export PATH=$PATH:$HBASE_HOME/bin
复制代码

4.2 HBase 集群

配置文件

HDFS 配置文件软链接
ln -s $HADOOP_HOME/etc/hadoop/core-ste.xml $HBASE_HOME/conf/core-site.xml
ln -s $HADOOP_HOME/etc/hadoop/hdfs-ste.xml $HBASE_HOME/conf/hdfs-site.xml
复制代码
hbase-env.sh
# ...
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
#...
export HBASE_MANAGES_ZK=false
# ...
export HBASE_DISABLE_HADOOP_CLASSPATH_LOOKUP=true
#...
复制代码
regionservers
node101
node102
node103
复制代码
backup-masters
node102
node103
复制代码
hbase-site.xml
<configuration>
    <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
    </property>
    <property>
        <name>hbase.rootdir</name>
        <value>hdfs://hdfs-cluster/hbase</value>
    </property>
    <property>
        <name>hbase.zookeeper.quorum</name>
        <value>win10:2181,win10:2182,win10:2183</value>
    </property>
</configuration>
复制代码

启动集群

# node101
start-hbase.sh
复制代码

WEB 界面:http://node101:16010http://node101:16030

HBase Shell

# 创建表
create 'student', 'info', 'score'

# 列出表
list

# 查看表结构
describe 'student'
复制代码
# 插入数据
put 'student', '1', 'info:name', 'icefery'
put 'student', '1', 'info:gender', '1'
put 'student', '1', 'score:math', '120'
put 'student', '2', 'info:name', 'fang'
put 'student', '2', 'info:gender', '2'
put 'student', '2', 'score:math', '110'
put 'student', '3', 'info:name', 'wenyu'
put 'student', '3', 'info:gender', '2'
put 'student', '3', 'score:math', '120'
复制代码
# 扫描查看表数据
scan 'student'

# 统计表行数
count 'student'

# 查看指定行
get 'student', '1'
get 'student', '1', 'info:name'
复制代码
# 删除指定行
delete 'student', '1', 'info:name'
deleteall 'student', '1'

# 禁用表
disable 'student'
# 删除表
drop 'student'
复制代码