最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

大数据开发(黑马)

业界 admin 13浏览 0评论

启动步骤

:::color2 su - hadoop

:::


:::color2
#一键启动hdfs集群
start-dfs.sh

:::

一键关闭hdfs集群

stop-dfs.sh


:::color2
启动:start-yarn.sh

:::

停止:stop-yarn.sh

:::color2
历史服务器启动:mapred --daemon start historyserver

:::


:::color2
cd /export/server/hive

:::

启动元数据管理服务(必须启动,否则无法工作)

前台启动:bin/hive --service metastore

:::color2
后台启动:nohup bin/hive --service metastore >> logs/metastore.log 2>&1 &

:::

启动客户端端,二选一(当前先选择Hive Shell方式)

Hive Shell方式(可以直接写SQL):bin/hive

:::tips
Hive ThriftServer方式(不可以直接写SQL,需要外部客户端链接使用):bin/hive --service hiveserver2

:::


启动元数据管理服务(必须启动,否则无法工作) 前台启动:bin/hive --service metastore 后台启动:nohup bin/hive --service metastore >> logs/metastore.log 2>&1 &
●启动客户端端,二选一(当前先选择Hive Shell方式) Hive Shell方式(可以直接写SQL):bin/hive Hive ThriftServer方式(不可以直接写SQL,需要外部客户端链接使用):bin/hive --service hiveserver2


使用代理客户端启用hive

:::color2
nohup bin/hive –service hiveserver2 >> logs/hiveserver2.log 2>&1 &

:::

启动:在hive目录输入bin/beeline
连接:!connect jdbc:hive2://node1:10000
输入用户名hadoop,密码跳过

VMware

网段设置

![](https://img-blog.csdnimg/img_convert/8dca3a7b1aabd0e79226f1f4c971fbdc.png)

配置ip

![](https://img-blog.csdnimg/img_convert/e24b65cf270e18954caba4e9da729315.png)

vim /etc/sysconfig/network-scripts/ifcfg-ens33

static

IPADDR=“192.168.88.103”

NETMASK=“255.255.255.0”

GATEWAY=“192.168.88.2”

DNS1=“192.168.88.2”

systemctl restart network

ifconfig

配置主机名映射

1.在Windows系统中修改hosts文件,填入如下内容:

192.168.88.101 node1

192.168.88.102 node2

192.168.88.103 node3

2.在3台Linux的/etc/hosts文件中,填入如下内容(3台都要添加)

192.168.88.101 node1

192.168.88.102 node2

192.168.88.103 node3

ssh免密登录

![](https://img-blog.csdnimg/img_convert/fe111797587048b7b262f4ff0e2f5202.png)

ssh-keygen -t rsa -b 4096

ssh-copy-id node1/2/3(三台机器都执行)

创建hadoop用户并配置免密登录

![](https://img-blog.csdnimg/img_convert/4807c4e9b6bbdec6cd08ca275a3d06ef.png)

useradd hadoop

passwd hadoop

虚拟机jdk配置

![](https://img-blog.csdnimg/img_convert/d8c811d3a91c7dad94b8230960bcbfbc.png)

上传到root文件夹

mkdir -p /export/server

tar -zxvf jdk-8u361-linux-x64.tar.gz -C /export/server/

cd /export/server

ln -s /export/server/jdk1.8.0_361 jdk

vim /etc/profile

export JAVA_HOME=/export/server/jdk

export PATH= P A T H : PATH: PATH:JAVA_HOME/bin

source /etc/profile

rm -f /usr/bin/java

ln -s /export/server/jdk/bin/java /usr/bin/java

jdkj复制到node2

scp r jdk1.8.0_361 node2:pwd/

防火墙 SELinux 时间同步

![](https://img-blog.csdnimg/img_convert/55d952e9e09a9b6df49a0d22769dd0b4.png)

systemctl stop firewalld

systemctl disable firewalld

vim /etc/sysconfig/selinux

SELINUX=disabled

重启:init 6

yum install -y ntp

rm -f /etc/localtime;sudo ln -s /usr/share/zoneinfo/Asia/shanghai /etc/localtime

ntpdate -u ntp.aliyun

systemctl start ntpd

systemctl enable ntpd

大数据软件生态

![](https://img-blog.csdnimg/img_convert/22c059e2c71ec4dd91e2ee2b44e5e1dd.png)

hadoop分布式文件系统(HDFS)

架构

可以在多台服务器上构建存储集群,存储海量的数据。

部署到虚拟机

![](https://img-blog.csdnimg/img_convert/0d0594008850706d5925c960af951539.png)

tar -zxvf hadoop-3.3.4.tar.gz -C /export/server/

cd /export/server

ln -s /export/server/hadoop-3.3.4 hadoop

cd etc/hadoop

vim workers

node1

node2

node3

vim hadoop-env.sh

export JAVA_HOME=/export/server/jdk
export HADOOP_HOME=/export/server/hadoop
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HADOOP_LOG_DIR=$HADOOP_HOME/logs

vim core-site.xml

修改

<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://node1:8020</value>
  </property>

  <property>
    <name>io.file.buffer.size</name>
    <value>131072</value>
  </property>
</configuration>

vim hdfs-site.xml

修改

<configuration>
  <property>
    <name>dfs.datanode.data.dir.perm</name>
    <value>700</value>
  </property>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/data/nn</value>
  </property>
  <property>
    <name>dfs.namenode.hosts</name>
    <value>node1,node2,node3</value>
  </property>
  <property>
    <name>dfs.blocksize</name>
    <value>268435456</value>
  </property>
  <property>
    <name>dfs.namenode.handler.count</name>
    <value>100</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/data/dn</value>
  </property>
</configuration>

在node1节点:

mkdir -p /data/nn

mkdir /data/dn

在node2和node3节点:

mkdir -p /data/dn

分发

在node1执行如下命令

cd /export/server

scp -r hadoop-3.3.4 node2:pwd/

scp -r hadoop-3.3.4 node3:pwd/

在node2执行,为hadoop配置软链接

#在node2执行如下命令

ln -s /export/server/hadoop-3.3.4 hadoop

在node3执行,为hadoop配置软链接

#在node3执行如下命令

ln -s /export/server/hadoop-3.3.4 hadoop

vim /etc/profile

#在/etc/profile文件底部追加如下内容

export HADOOP_HOME=/export/server/hadoop

export PATH= P A T H : PATH: PATH:HADOOP_HOME/bin:$HADOOP_HOME/sbin

source /etc/profile

chown -R hadoop:hadoop /data

chown -R hadoop:hadoop /export

格式化namenode

#确保以hadoop用户执行

su - hadoop

  • **<font style="color:rgb(44, 44, 54);">su hadoop</font>**:不加载目标用户的环境变量和配置文件,适合快速简单的用户切换。
  • **<font style="color:rgb(44, 44, 54);">su - hadoop</font>**:加载目标用户的环境变量和配置文件,适合需要完整环境配置的情况。

#格式化namenode

hadoop namenode -format

启动

#一键启动hdfs集群

start-dfs.sh

一键关闭hdfs集群

stop-dfs.sh

如果遇到命令未找到的错误,表明环境变量未配置好,可以以绝对路径执行

/export/server/hadoop/sbin/start-dfs.sh

/export/server/hadoop/sbin/stop-dfs.sh

:::danger
快照:hadoop的HDFS部署完成

:::

HDFS集群启停

**一键启停**

#一键启动hdfs集群
start-dfs.sh
# 一键关闭hdfs集群
stop-dfs.sh

单进程启停

HDFS文件系统的操作命令

![](https://img-blog.csdnimg/img_convert/e64803cfe53bff72ac8fcb96b2129813.png)

使用协议头:

两套命令系统

![](https://img-blog.csdnimg/img_convert/7aac35127b09392b6bad6d538b317501.png)

创建文件夹

1. 使用`hadoop fs`命令:
hadoop fs -mkdir [-p] <path> ...
  1. 使用hdfs dfs命令:
hdfs dfs -mkdir [-p] <path> ...

<path>参数表示要创建的新目录的路径。

-p选项的行为类似于Linux中的mkdir -p命令,即如果指定的路径包含多级目录,则会递归地创建所有不存在的父目录。

下面是一些具体的示例:

  • hadoop fs -mkdir -p /itcast/bigdata
  • hdfs fs -mkdir -p /itheima/hadoop

查看指定目录下的内容

```plain hadoop fs -ls [-h] [-R] [path ...] hdfs dfs -ls [-h] [-R] [path ...] ```
  • -ls: 列出指定目录的内容。
  • -h: 人性化显示文件大小,即将字节数转换为更易读的形式(如 KB, MB, GB 等)。
  • -R: 递归列出目录及其所有子目录的内容。

示例

hadoop fs -ls /user/hadoop/input
hdfs dfs -ls /user/hadoop/input

上传文件到hdfs指定目录下

+ `hadoop fs -put [-f] [-p] ... ` + `hdfs dfs -put [-f] [-p] ... ` + `-f`: 覆盖目标文件。如果目标文件已经存在,使用 `-f` 选项会覆盖已有文件。 + `-p`: 保留属性。保留源文件的权限、所有权和其他元数据。 + ``: 指定要上传的本地文件或目录的路径。 + ``: 指定HDFS中存放文件的目标路径。

示例

  • hadoop fs -put words.txt /itcast:

  • 将本地文件 words.txt 上传至HDFS的 /itcast 目录下。

  • hdfs dfs -put file:///etc/profile hdfs://node1:8020/itcast:

  • 将本地文件 /etc/profile 上传至HDFS的 node1:8020/itcast 目录下。

查看HDFS文件内容

+ `hadoop fs -cat ...` + `hdfs dfs -cat ...`

示例

  • hadoop fs -cat /itcast/words.txt:
  • 显示HDFS中 /itcast/words.txt 文件的所有内容。
  • hdfs dfs -cat /itcast/words.txt:
  • 同样显示HDFS中 /itcast/words.txt 文件的所有内容。

处理大文件

对于较大的文件,直接使用 -cat 可能会导致输出过多,难以阅读。因此结合管道符 |more 命令来分页查看文件内容:

  • hadoop fs -cat <src> | more
  • hdfs dfs -cat <src> | more

这里的 more 命令可以让用户逐页查看文件内容,按空格键翻页,按 q 键退出。

下载HDFS文件

+ `hadoop fs -get [-f] [-p] ... ` + `hdfs dfs -get [-f] [-p] ... ` + `-f`: 覆盖目标文件。如果目标文件已经存在,使用 `-f` 选项会覆盖已有文件。 + `-p`: 保留属性。保留源文件的权限、所有权和其他元数据。 + ``: 指定HDFS中要下载的文件或目录的路径。 + ``: 指定本地文件系统中保存文件的目标路径。

示例

  • hadoop fs -get /itcast/zookeeper.out ./test:

  • 下载HDFS中 /itcast/zookeeper.out 文件到本地文件系统中的 ./test 目录下。

  • hdfs dfs -get /itcast/zookeeper.out ./test:

  • 同样的操作,但使用的是 hdfs dfs 命令。

拷贝HDFS文件

+ `hadoop fs -cp [-f] ... ` + `hdfs dfs -cp [-f] ... `
  • -f: 覆盖目标文件。如果目标文件已经存在,使用 -f 选项会覆盖已有文件。
  • <src>: 指定HDFS中要复制的文件或目录的路径。
  • <dst>: 指定HDFS中接收文件的目标路径。

示例

  • hadoop fs -cp /small/1.txt /itcast:
  • 复制HDFS中 /small/1.txt 文件到 /itcast 目录下。
  • hadoop fs -cp /small/1.txt /itcast/666.txt:
  • 复制HDFS中 /small/1.txt 文件到 /itcast 目录下,并命名为 666.txt

追加数据到HDFS文件

+ `hadoop fs -appendToFile ... ` + `hdfs dfs -appendToFile ... ` + ``: 指定一个或多个本地文件作为输入,这些文件的内容会被追加到HDFS中的目标文件。 + ``: 指定HDFS中要追加数据的目标文件路径。
  • 如果 <localsrc> 参数为 -,则从标准输入读取数据。
  • 如果 <dst> 文件不存在,命令会先创建该文件再进行追加操作。

示例

  • echo "Hello World" | hadoop fs -appendToFile - /itcast/file.txt: 将字符串 “Hello World” 写入标准输入,然后追加到HDFS中 /itcast/file.txt 文件的末尾。
  • hadoop fs -appendToFile localfile1.txt localfile2.txt /itcast/combinedfile.txt: 将本地文件 localfile1.txtlocalfile2.txt 的内容追加到HDFS中 /itcast/combinedfile.txt 文件的末尾。

HDFS数据移动操作

+ `hadoop fs -mv ... ` + `hdfs dfs -mv ... ` + ``: 指定一个或多个源文件或目录的路径,这些是要被移动的对象。 + ``: 指定目标位置的路径,可以是一个新的文件名(如果是文件的话)或者一个新的目录(如果是整个目录树的话)。

:::tips

  • 移动文件或目录:将指定的文件或目录从一个位置移到另一个位置。
  • 重命名文件:通过改变 <src><dst> 的名称,可以达到重命名文件的目的。
  • hadoop fs -mv /test2.txt /itheima/abc.txt

:::

示例

  • hadoop fs -mv /old/path/to/file /new/path/to/file: 将文件从 /old/path/to/file 移动到 /new/path/to/file
  • hdfs dfs -mv /old/path/to/directory /new/path/to/directory: 将目录从 /old/path/to/directory 移动到 /new/path/to/directory

HDFS数据删除操作

+ `hadoop fs -rm -r [-skipTrash] URI [URI ...]` + `hdfs dfs -rm -r [-skipTrash] URI [URI ...]` + `-r`: 表示递归删除,即如果删除对象是目录,则会递归删除该目录及其所有子目录和文件。 + `-skipTrash`: 默认情况下,HDFS会在删除文件时将其移至回收站(.Trash)而非立即永久删除。使用 `-skipTrash` 选项可以直接跳过回收站,立即永久删除文件。 + `URI`: 指定要删除的文件或目录的路径。
  • 回收站功能默认关闭,若要开启需在 core-site.xml 文件中添加以下配置:
<property>
  <name>fs.trash.interval</name>

  <value>1440</value>

</property>

这里 fs.trash.interval 设置了回收站在多少分钟后自动清空,默认值为1440分钟(24小时)。

  • 此外,还可以配置回收站的检查点间隔时间:
<property>
  <name>fs.trash.checkpoint.interval</name>

  <value>120</value>

</property>

这里 fs.trash.checkpoint.interval 设置了每隔多少秒检查一次是否有文件需要从回收站清除,默认值为120秒。

示例

  • hadoop fs -rm -r /path/to/file_or_directory: 删除指定的文件或目录。
  • hdfs dfs -rm -r -skipTrash /path/to/file_or_directory: 不经过回收站,直接永久删除指定的文件或目录。

big data tool安装

IED下载插件

NFS网关

把HDFS文件部署到win本地磁盘

cd /export/server/hadoop/etc/hadoop/

vim core-site.xml

<property>
    <name>hadoop.proxyuser.hadoop.groups</name>
    <value>*</value>
</property>

<property>
    <name>hadoop.proxyuser.hadoop.hosts</name>
    <value>*</value>
</property>

<property>
  <name>nfs.suerpser</name>
  <value>hadoop</value>
</property>

<property>
  <name>nfs.dump.dir</name>
  <value>/tmp/.hdfs-nfs</value>
</property>

<property>
  <name>nfs.exports.allowed.hosts</name>
  <value>192.168.88.1 rw</value>
</property>

scp core-site.xml hdfs-site.xml node3: pwd/

停止集群

exit 到root用户

systemctl stop nfs

systemctl disable nfs

yum remove -y rpcbind

hdfs --daemon start portmap

hdfs --daemon start nfs3

启动HDFS集群:start-dfs.sh

net use X: \192.168.88.101!

HDFS副本配置

![](https://img-blog.csdnimg/img_convert/5b86aa0888749c82577037576f3d262a.png)

HDFS数据读写流程

![](https://img-blog.csdnimg/img_convert/79d0abe47cf9a51f6abd231547044b23.png)

分布式计算MapReduce

![](https://img-blog.csdnimg/img_convert/636ed4538492b587497edd2a06ea2d89.png)

MapReduce提供了2个编程接口:

Map

Reduce

其中 Map功能接口提供了“分散”的功能,由服务器分布式对数据进行处理

        Reduce功能接口提供了“汇总(聚合)”的功能,将分布式的处理结果汇总统计

用户如需使用MapReduce框架完成自定义需求的程序开发需要使用lava、Python等编程语言,实现Map Reduce功能接口即可。


分布式资源调度YARN

![](https://img-blog.csdnimg/img_convert/a24c46b0550b84ab5c1465063e8bc2ff.png)

YARN架构

![](https://img-blog.csdnimg/img_convert/82df9d5d2906da23630cd608ca4f9397.png)

MapReduce配置文件

cd /export/server/hadoop/etc/hadoop/

vim mapred-env.sh

# 设置JDK路径
export JAVA_HOME=/export/server/jdk

# 设置JobHistoryServer进程内存量为1G
export HADOOP_JOB_HISTORYSERVER_HEAPSIZE=1000

# 设置日志级别为INFO
export HADOOP_MAPRED_ROOT_LOGGER=INFO,RFA

vim mapred-site.xml

<property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    <description>MapReduce的运行框架设置为 YARN</description>
</property>

<property>
    <name>mapreduce.jobhistory.address</name>
    <value>node1:10020</value>
    <description>历史服务器通讯端口为 node1:10020</description>
</property>

<property>
    <name>mapreduce.jobhistory.webapp.address</name>

    <value>node1:19888</value>

    <description>历史服务器web端口为 node1 的 19888</description>

</property>

<property>
    <name>mapreduce.jobhistory.intermediate-done-dir</name>

    <value>/data/mr-history/tmp</value>

    <description>历史信息在HDFS的记录临时路径</description>

</property>

<property>
    <name>mapreduce.jobhistory.done-dir</name>

    <value>/data/mr-history/done</value>

    <description>历史信息在HDFS的记录路径</description>

</property>

<property>
    <name>yarn.app.mapreduce.am.env</name>

    <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>

    <description>MapReduce HOME 设置为 $HADOOP_HOME</description>

</property>

<property>
    <name>mapreduce.map.env</name>

    <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>

    <description>MapReduce HOME 设置为 $HADOOP_HOME</description>

</property>

<property>
    <name>mapreduce.reduce.env</name>

    <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>

    <description>MapReduce HOME 设置为 $HADOOP_HOME</description>

</property>

YARN部署

![](https://img-blog.csdnimg/img_convert/42c3ae848e670803f9edadd509393985.png)

# 设置 JDK 路径的环境变量
export JAVA_HOME=/export/server/jdk

# 设置 HADOOP_HOME 的环境变量
export HADOOP_HOME=/export/server/hadoop

# 设置配置文件路径的环境变量
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop

# 设置日志文件路径的环境变量
export HADOOP_LOG_DIR=$HADOOP_HOME/logs

<property>
    <name>yarn.resourcemanager.hostname</name>

    <value>node1</value>

    <description>ResourceManager设置在node1节点</description>

</property>

<property>
    <name>yarn.nodemanager.local-dirs</name>

    <value>/data/nm-local</value>

    <description>NodeManager中间数据本地存储路径</description>

</property>

<property>
    <name>yarn.nodemanager.log-dirs</name>

    <value>/data/nm-log</value>

    <description>NodeManager数据日志本地存储路径</description>

</property>

<property>
    <name>yarn.nodemanager.aux-services</name>

    <value>mapreduce_shuffle</value>

    <description>为MapReduce程序开启Shuffle服务</description>

</property>


<property>
    <name>yarn.log.server.url</name>

    <value>http://node1:19888/jobhistory/logs</value>

    <description>历史服务器URL</description>

</property>

<property>
    <name>yarn.web-proxy.address</name>

    <value>node1:8089</value>

    <description>代理服务器主机和端口</description>

</property>

<property>
    <name>yarn.log-aggregation-enable</name>

    <value>true</value>

    <description>开启日志聚合</description>

</property>

<property>
    <name>yarn.nodemanager.remote-app-log-dir</name>

    <value>/tmp/logs</value>

    <description>程序日志HDFS的存储路径</description>

</property>

<property>
    <name>yarn.resourcemanager.scheduler.class</name>

    <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>

    <description>选择公平调度器</description>

</property>

scp mapred-env.sh mapred-site.xml yarn-env.sh yarn-site.xml node2:`pwd`/
scp mapred-env.sh mapred-site.xml yarn-env.sh yarn-site.xml node3:`pwd`/

启动:start-yarn.sh

停止:stop-yarn.sh

历史服务器启动:mapred --daemon start historyserver

http://node1:8088

提交MapReduce程序至YARN运行

![](https://img-blog.csdnimg/img_convert/9f8435fcd7dc8296f40363c48037510c.png)

cd /export/server/hadoop/share/hadoop/mapreduce

hadoop-mapreduce-examples-3.3.4.jar

  1. 输入路径:指定数据输入的HDFS(Hadoop Distributed File System)路径。
  2. 输出路径:指定结果输出的HDFS路径。
  3. 处理过程:对输入路径内的数据中的单词进行计数,并将结果写入到输出路径。

数据准备:

  • 准备一份包含以下内容的数据文件 words.txt,并上传到HDFS中:
itheima itcast itheima itcast hadoop hdfs hadoop hdfs hadoop mapreduce hadoop yarn itheima hadoop itcast hadoop itheima itcast hadoop yarn mapreduce

HDFS操作命令:

  1. 创建输入目录 /input/wordcount
hadoop fs -mkdir -p /input
  1. 创建输出目录 /output
hadoop fs -mkdir /output
  1. words.txt 文件上传到HDFS的输入目录:
hadoop fs -put words.txt /input

执行MapReduce程序:

运行以下命令提交WordCount MapReduce程序到YARN执行:

hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar wordcount hdfs://node1:8020/input/ hdfs://node1:8020/output/wc

其中:

  • 参数 wordcount 表示运行jar包中的单词计数程序(Java Class)。
  • 第一个参数是数据输入路径 (hdfs://node1:8020/input/wordcount/)。
  • 第二个参数是结果输出路径 (hdfs://node1:8020/output/wc1)。

通过这些步骤,可以实现对HDFS中特定路径下的文本文件进行单词计数,并将结果保存在指定的输出路径下。

分布式SQL计算-Hive

![](https://img-blog.csdnimg/img_convert/e596f2de9fb42529d5359ea806cf4e85.png)

Hive在虚拟机部署

![](https://img-blog.csdnimg/img_convert/b4fa4d6527551a62ac85bd0ba3801625.png)
# 更新密钥
rpm --import https://repo.mysql/RPM-GPG-KEY-mysql-2022

# 安装 MySQL yum 仓库
rpm -Uvh http://repo.mysql/mysql57-community-release-el7-7.noarch.rpm

# 使用 yum 安装 MySQL
yum -y install mysql-community-server

# 启动 MySQL 并设置为开机启动
systemctl start mysqld
systemctl enable mysqld

# 查看 MySQL 服务状态
systemctl status mysqld

# 获取临时密码
grep 'temporary password' /var/log/mysqld.log

#登录
mysql -uroot -p

# 设置密码策略为 LOW
set global validate_password_policy=LOW;

# 设置密码最小长度为 4
set global validate_password_length=4;

# 修改 root 用户密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';

# 授予所有权限
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;

# 刷新权限
flush privileges;

<property>
    <name>hadoop.proxyuser.hadoop.hosts</name>
    <value>*</value>
</property>

<property>
    <name>hadoop.proxyuser.hadoop.groups</name>
    <value>*</value>
</property>

su - hadoop

cd /export/server/hadoop/etc/hadoop/

vim core-site.xml

su - hadoop
wget http://archive.apache/dist/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gz
tar -zxvf apache-hive-3.1.3-bin.tar.gz -C /export/server/
ln -s /export/server/apache-hive-3.1.3-bin hive

mv mysql-connector-java-5.1.34.jar /export/server/apache-hive-3.1.3-bin/lib/

cd have/conf

mv hive-env.sh.template hive-env.sh

vim hive-env.sh

export HADOOP_HOME=/export/server/hadoop
export HIVE_CONF_DIR=/export/server/hive
export HIVE_AUX_JARS_PATH=/export/server/hive/lib

vim hive-site.xml

<configuration>
  <property>
    <name>javax.jdo.option.ConnectionURL</name>

    <value>jdbc:mysql://node1:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8</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>


    <property>
    <name>hive.server2.thrift.bind.host</name>

    <value>node1</value>

  </property>
  

  <property>
    <name>hive.metastore.uris</name>

    <value>thrift://node1:9083</value>

  </property>

  <property>
    <name>hive.metastore.event.db.notification.api.auth</name>

    <value>false</value>

  </property>



</configuration>

CREATE DATABASE hive CHARSET UTF8;
cd /export/server/hive
./bin/schematool -initSchema -dbType mysql -verbos

cd …

cd bin

./schematool -initSchema -dbType mysql -verbos

chown -R hadoop:hadoop apache-hive-3.1.3-bin hive

  • 确保Hive文件夹所属为hadoop用户
  • 创建一个hive的日志文件文件夹:
    mkdir /export/server/hive/logs
  • 启动元数据管理服务(必须启动,否则无法工作)
    前台启动:bin/hive --service metastore
    后台启动:nohup bin/hive --service metastore >> logs/metastore.log 2>&1 &
  • 启动客户端端,二选一(当前先选择Hive Shell方式)
    Hive Shell方式(可以直接写SQL):bin/hive
    Hive ThriftServer方式(不可以直接写SQL,需要外部客户端链接使用):bin/hive --service hiveserver2

Hive体验执行SQL语句

首先,确保启动了Metastore服务。

可以执行:bin/hive,进入到Hive Shell环境中,可以直接执行SQL语句。

  • 创建表

CREATE TABLE test(id INT, name STRING, gender STRING);(没有指定数据库,自动创建到default数据库中)

  • 插入数据

INSERT INTO test VALUES(1,‘王力红’,‘男’), (2,‘周杰轮’,‘男’), (3,‘林志灵’,‘女’);

  • 查询数据

SELECT gender, COUNT(*) AS cnt FROM test GROUP BY gender;

Hive客户端

![](https://img-blog.csdnimg/img_convert/dcc392b2964fe2908b88908e7a03db08.png)

HiveServer2服务

![](https://img-blog.csdnimg/img_convert/b8774666dc79cd834f6c41577e966d7b.png)
nohup bin/hive --service hiveserver2 >> logs/hiveserver2.log 2>&1 &

beeline

![](https://img-blog.csdnimg/img_convert/03ece57dd5471f43f0d38e56450d5eb2.png)

启动:在hive目录输入bin/beeline

连接:!connect jdbc:hive2://node1:10000

输入用户名hadoop,密码跳过

Hive语法

数据库操作

创建数据库

create database if not exists myhive;

use myhive;

• 查看数据库详细信息

desc database myhive;

  • 创建数据库并指定HDFS存储位置
create database myhive storage location '/myhive';

使用location关键字,可以指定数据库在HDFS上的存储路径。

删除数据库

+ 删除一个空数据库,如果数据库下面有数据表,那么就会报错
drop database myhive;
  • 强制删除数据库,包含数据库下面的表一起删除
drop database myhive cascade;

创建数据库表

```sql CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_comment], ...)] [COMMENT table_comment] [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...) INTO num_buckets BUCKETS]] [ROW FORMAT row_format] [STORED AS file_format] [LOCATION hdfs_path] ```
  • EXTERNAL, 创建外部表
  • PARTITIONED BY, 分区表
  • CLUSTERED BY, 分桶表
  • STORED AS, 存储格式
  • LOCATION, 存储位置

内部表/外部表

在 Apache Hive 中,表可以分为两种类型:内部表(Managed Tables)和外部表(External Tables)。这两种表在管理和数据删除方面有一些重要的区别。

内部表(Managed Tables)

  1. 定义
    • 内部表是由 Hive 完全管理的数据表。
    • 当你创建一个内部表时,Hive 会在默认的仓库目录(通常是 hdfs://<namenode>:<port>/user/hive/warehouse)下创建一个子目录来存储表的数据。
  2. 创建语法
CREATE TABLE table_name (
    column1 datatype,
    column2 datatype,
    ...
)
[PARTITIONED BY (column3 datatype, ...)]
[CLUSTERED BY (column4, ...) SORTED BY (column5) INTO num_buckets BUCKETS]
[ROW FORMAT DELIMITED FIELDS TERMINATED BY 'char']
[STORED AS file_format]
[LOCATION hdfs_path];
  1. 数据存储
    • 默认情况下,数据存储在 Hive 的仓库目录下的一个子目录中。
    • 例如,如果你创建一个名为 employees 的表,数据将存储在 hdfs://<namenode>:<port>/user/hive/warehouse/employees 目录下。
  2. 数据删除
    • 当你删除一个内部表时,Hive 不仅会删除表的元数据,还会删除表对应的数据文件。
    • 例如:
DROP TABLE employees;

这条命令会删除 employees 表及其所有数据。

外部表(External Tables)

  1. 定义
    • 外部表是指数据存储在 Hive 仓库目录之外的表。
    • 创建外部表时,你需要指定数据的实际存储位置。
  2. 创建语法
CREATE EXTERNAL TABLE table_name (
    column1 datatype,
    column2 datatype,
    ...
)
[PARTITIONED BY (column3 datatype, ...)]
[CLUSTERED BY (column4, ...) SORTED BY (column5) INTO num_buckets BUCKETS]
[ROW FORMAT DELIMITED FIELDS TERMINATED BY 'char']
[STORED AS file_format]
LOCATION 'hdfs_path'

ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LOCATION '/tmp/test/test_extl1';
  1. 数据存储
    • 数据存储在你指定的 HDFS 路径下。
    • 例如,如果你创建一个名为 external_employees 的外部表,并指定数据存储在 /user/data/external_employees 目录下:
CREATE EXTERNAL TABLE external_employees (
    id INT,
    name STRING,
    department STRING
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION '/user/data/external_employees';
  1. 数据删除
    • 当你删除一个外部表时,Hive 只会删除表的元数据,而不会删除表对应的数据文件。
    • 例如:
DROP TABLE external_employees;

这条命令只会删除 external_employees 表的元数据,而不会删除存储在 /user/data/external_employees 目录下的数据文件。

总结

  • 内部表:数据由 Hive 管理,删除表时会删除数据。因此内部表不适合和其他工具共享数据。
  • 外部表:数据存储在指定的 HDFS 路径,删除表时只删除元数据,保留数据。

相互转换

hive数据的导入和导出

![](https://img-blog.csdnimg/img_convert/c9861e71e37f9979613a61c089a74eff.png)

我们使用 LOAD 语法,从外部将数据加载到Hive内,语法如下:

LOAD DATA [LOCAL] INPATH ‘filepath’ [OVERWRITE] INTO TABLE tablename;

1:上传数据文件到Linux系统

2:创建表

CREATE TABLE myhive.test_load_load(
    dt string COMMENT '时间(时分秒)',
    user_id string COMMENT '用户ID',
    word string COMMENT '搜索词',
    url string COMMENT '用户访问网址'
) COMMENT '搜索引擎日志表'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';

3:数据加载

load data local inpath '/home/hadoop/search_log.txt'  [overwrite] into table myhive.test_load_load;

Hive 从Linux本地文件系统加载数据。关键字 <font style="color:rgb(44, 44, 54);">local</font> 表示数据源是在本地文件系统上的。

load data inpath '/tmp/search_log.txt' overwrite into table myhive.test_load;

Hive 从 HDFS 加载数据。源数据文件会消失(本质是被移动到表所在的目录中)

分区表

![](https://img-blog.csdnimg/img_convert/f7b56d5dddf628a3b5abd3c3289bbe95.png)

分区表的概念

分区表是将表的数据按照一个或多个列的值分成多个部分,每个部分称为一个分区。每个分区可以存储在一个独立的目录中,这样在查询时可以根据分区条件快速定位到所需的数据。

创建分区表
单分区表
假设我们有一个日志表 `logs`,我们希望按日期进行分区。可以使用以下 SQL 语句创建单分区表:
CREATE TABLE logs (
    id INT,
    message STRING
)
PARTITIONED BY (dt STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';

在这个例子中,dt 列用于分区,每个分区将存储在不同的目录中。

多分区表
如果需要按多个列进行分区,可以使用多个 `PARTITIONED BY` 列。例如,按日期和小时进行分区:
CREATE TABLE logs (
    id INT,
    message STRING
)
PARTITIONED BY (dt STRING, hr STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';

查询分区表
查询分区表时,可以通过指定分区条件来提高查询效率。例如:
SELECT * FROM logs WHERE dt = '2023-10-01';
删除分区
可以使用 `ALTER TABLE` 语句删除分区:
ALTER TABLE logs DROP PARTITION (dt = '2023-10-01');

分桶表

分桶概念(Bucketing)
分桶是 Hive 中一种用于优化查询的技术,它通过将数据按照某个列的值进行哈希散列,并根据散列值将数据分布到多个文件中,这些文件被称为“桶”。每个桶可以看作是一个小的数据集,这样可以使得在处理大规模数据集时更加高效,尤其是在进行连接操作或者采样时。

优点

  • 提升查询效率:当需要对特定列进行过滤或聚合时,分桶可以减少需要扫描的数据量,从而加快查询速度。
  • 并行处理:由于数据已经被均匀地分配到了不同的桶中,因此可以更容易地实现并行处理。
  • 采样:对于大数据集,如果数据已经均匀地分布在各个桶中,那么从每个桶中抽取少量数据就可以得到一个代表性的样本,这对于数据探索和分析非常有用。

缺点

  • 增加数据准备时间:创建分桶表时,需要额外的时间来计算哈希值并将数据正确地放入相应的桶中。
  • 桶的数量选择:需要合理选择桶的数量,太少会导致数据倾斜,太多则可能增加存储开销和管理复杂度。
创建分桶表
在创建分桶表时,通常会指定一个或多个列作为分桶列,并指定桶的数量。例如,假设我们有一个用户行为日志表,我们希望基于用户的 `user_id` 进行分桶,可以这样创建表:

set hive.enforce.bucketing=true;

CREATE TABLE user_behavior (
    user_id INT,
    action STRING,
    time TIMESTAMP
)
CLUSTERED BY (user_id) INTO 32 BUCKETS
row format delimited fields terminated by '\t';

这里,CLUSTERED BY (user_id) 指定了分桶列,而 INTO 32 BUCKETS 则指定了将数据分为32个桶。

加载数据到分桶表
![](https://img-blog.csdnimg/img_convert/aacd87cf13aa3a5227dffa581edd197a.png)

修改表的sql操作

1. 修改表注释
```sql ALTER TABLE table_name SET TBLPROPERTIES ('comment' = 'new_comment'); ```

table_name 是你想要修改的表的名字,new_comment 是新的注释信息。

2. 表重命名
```sql ALTER TABLE old_table_name RENAME TO new_table_name; ```

old_table_name 是当前表的名字,new_table_name 是新名字。

3. 添加列
```sql ALTER TABLE table_name ADD COLUMNS (column_name column_type [COMMENT 'column_comment']); ```

table_name 是你要添加列的表的名字,column_name 是新列的名字,column_type 是新列的数据类型,可选的 COMMENT 用来提供列的说明。

4. 修改列名
```sql ALTER TABLE table_name CHANGE COLUMN old_column_name new_column_name column_type [COMMENT 'column_comment']; ```

old_column_name 是旧列名,new_column_name 是新列名,column_type 是列的新数据类型,COMMENT 是可选的列说明。

5. 删除表
```sql DROP TABLE IF EXISTS table_name; ```

IF EXISTS 是可选的,但建议加上,以防表不存在时出错。

6. 清空表
清除表中的所有数据,但保留表结构,无法清空外部表
TRUNCATE TABLE table_name;

请注意,TRUNCATE 不同于 DELETE,因为它不会触发任何触发器,而且它的执行速度更快。

7.添加分区
使用 ` ALTER TABLE ... ADD PARTITION` 语句。例如,假设有一个按日期分区的表 ` web_logs` ,你可以这样添加一个新的分区:
ALTER TABLE web_logs ADD PARTITION (dt='2024-01-01') LOCATION '/user/hive/warehouse/web_logs/dt=2024-01-01';

<font style="color:rgb(44, 44, 54);">dt</font> 是分区列,<font style="color:rgb(44, 44, 54);">2024-01-01</font> 是分区值,<font style="color:rgb(44, 44, 54);">LOCATION</font> 指定了分区数据在 HDFS 上的存储路径。如果不指定 <font style="color:rgb(44, 44, 54);">LOCATION</font>,Hive 会默认在表的目录下创建一个子目录来存储该分区的数据。

8.删除分区
会删除hive里面的元数据,但是不会删除hdfs里面的数据文件。
ALTER TABLE web_logs DROP PARTITION (dt='2024-01-01');

array数组

![](https://img-blog.csdnimg/img_convert/6af82229d97b1530a426278be651966e.png)

可以使用array数组类型,存储locations的数据,要求数据类型一致

CREATE TABLE myhive.test_array(
    name STRING,
    work_locations ARRAY<STRING>
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ',';

SELECT id, name, courses[0] AS first_course FROM stu
SELECT id, name, size(courses) AS num_courses FROM students;
SELECT id, name, array_contains(courses, 'Math') AS has_math FROM students;

map映射

![](https://img-blog.csdnimg/img_convert/56bb972cedb2ba2359ea4ca356f99b43.png)

create table myhive.test_map(
    id int,
    name string,
    members map<string,string>,
    age int
)
row format delimited
fields terminated by ','
COLLECTION ITEMS TERMINATED BY '#'
MAP KEYS TERMINATED BY ':';
select 
    id, 
    name, 
    members['father'], 
    members['mother']
from 
    myhive.test_map;
select 
    map_keys(members)
from 
    myhive.test_map;
-- ,看看谁有 sister 这个 key
SELECT *
FROM myhive.test_map
WHERE ARRAY_CONTAINS(map_keys(members), 'sister');
SELECT *
FROM myhive.test_map
WHERE ARRAY_CONTAINS(map_values(members), '王林');

struct数据类型

![](https://img-blog.csdnimg/img_convert/b3dee2bd1b6dba2d31d50ce9ec59ee9f.png) ![](https://img-blog.csdnimg/img_convert/6a8aba61c77010e986fea76751548589.png)
CREATE TABLE myhive.test_struct (
    id STRING,
    info STRUCT<name:STRING, age:INT>
)#info是struct的整体列名
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '#'
COLLECTION ITEMS TERMINATED BY ':';
SELECT id, info.name, info.age
FROM myhive.test_struct;

基本查询

**1. SELECT 语句**

SELECT 语句用于从表中选择数据。基本语法如下:

SELECT column1, column2, ...
FROM table_name;

2. 聚合函数

聚合函数用于对一组值进行计算并返回单个值。常见的聚合函数包括:

  • COUNT(*):计算行数。
  • COUNT(column):计算指定列的非空值数量。
  • SUM(column):计算指定列的总和。
  • AVG(column):计算指定列的平均值。
  • MIN(column):计算指定列的最小值。
  • MAX(column):计算指定列的最大值。
-- 计算表中所有行的数量
SELECT COUNT(*) FROM sales;

-- 计算销售额的总和
SELECT SUM(amount) FROM sales;

-- 计算平均销售额
SELECT AVG(amount) FROM sales;

-- 计算最小和最大销售额
SELECT MIN(amount), MAX(amount) FROM sales;

3. GROUP BY 子句

GROUP BY 子句用于将数据分组,通常与聚合函数一起使用。语法如下:

SELECT column1, aggregate_function(column2)
FROM table_name
GROUP BY column1;
-- 按产品类别分组,计算每个类别的销售总额
SELECT category, SUM(amount) AS total_sales
FROM sales
GROUP BY category;

-- 按客户分组,计算每个客户的订单数量
SELECT customer, COUNT(order_id) AS order_count
FROM orders
GROUP BY customer;

4. JOIN 子句

JOIN 子句用于将多个表中的数据组合在一起。常见的 JOIN 类型包括:

  • INNER JOIN:返回两个表中匹配的行。
  • LEFT JOIN:返回左表中的所有行,以及右表中匹配的行。如果没有匹配的行,则返回 NULL。
  • RIGHT JOIN:返回右表中的所有行,以及左表中匹配的行。如果没有匹配的行,则返回 NULL。
  • FULL OUTER JOIN:返回两个表中的所有行,如果没有匹配的行,则返回 NULL。
-- INNER JOIN 示例
SELECT o.order_id, o.customer, p.product_name, o.amount
FROM orders o
INNER JOIN products p ON o.product_id = p.product_id;

-- LEFT JOIN 示例
SELECT o.order_id, o.customer, p.product_name, o.amount
FROM orders o
LEFT JOIN products p ON o.product_id = p.product_id;

-- RIGHT JOIN 示例
SELECT o.order_id, o.customer, p.product_name, o.amount
FROM orders o
RIGHT JOIN products p ON o.product_id = p.product_id;

-- FULL OUTER JOIN 示例
SELECT o.order_id, o.customer, p.product_name, o.amount
FROM orders o
FULL OUTER JOIN products p ON o.product_id = p.product_id;

5. ORDER BY 子句

ORDER BY 子句用于对查询结果进行排序。语法如下:

SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;
-- 按销售额降序排列
SELECT customer, SUM(amount) AS total_sales
FROM sales
GROUP BY customer
ORDER BY total_sales DESC;

-- 按客户升序排列,按订单日期降序排列
SELECT customer, order_date, amount
FROM orders
ORDER BY customer ASC, order_date DESC;

正则表达式

![](https://img-blog.csdnimg/img_convert/15abeedf416088b4bad7cda556beef15.png)

:::color2
.是对.的进一步解释,两个符号不是独立的存在

:::

union联合

union用于将多个select语句的结果组合成单个结果集。 每个select语句返回的列的数量和名称必须相同。否则,将引发架构错误。
  • UNION:合并结果集并去除重复行。
  • UNION ALL:合并结果集并保留所有行,包括重复的行。
SELECT column1, column2, ...
FROM table1
UNION
SELECT column1, column2, ...
FROM table2
[UNION
SELECT column1, column2, ...
FROM table3]
...

采样(Sampling)

![](https://img-blog.csdnimg/img_convert/a889668f56a6d2646f3bd5854ccc5c75.png)

1. 基于行的采样

基于行的采样使用 `TABLESAMPLE` 关键字,可以通过指定百分比或行数来抽取样本。

SELECT *
FROM table_name
TABLESAMPLE (type AND expression);

按百分比采样

-- 抽取表中 10% 的行
SELECT *
FROM sales
TABLESAMPLE (10 PERCENT);

按行数采样

-- 抽取表中 1000 行
SELECT *
FROM sales
TABLESAMPLE (1000 ROWS);

2. 埋点采样(Bucket Sampling)

基于桶的采样是一种更精确的采样方法,它将数据分成多个桶,然后从每个桶中抽取样本。这种方法适用于大数据集,可以确保样本的均匀分布。

  • x:要抽取的桶编号。
  • y:总的桶数。
  • colname指代列名,表示根据给出的列名把数据分成y个桶,rand()表示把数据随机分桶。

假设我们有一个表 sales,我们想从该表中抽取 1/10 的数据。

-- 将数据分成 10 个桶,抽取第 1 个桶的数据
SELECT *
FROM sales
TABLESAMPLE (BUCKET 1 OUT OF 10 ON date);

3. 随机采样

Hive 还支持使用随机函数进行采样。可以使用 `RAND()` 函数来抽取随机样本。
-- 抽取表中随机的 10% 的行
SELECT *
FROM sales
WHERE RAND() <= 0.1;

虚拟列

![](https://img-blog.csdnimg/img_convert/e6a89fa9a8215a74fcd5827f6b31df70.png)

案例

需求分析

建库建表

```sql --如果数据库已存在就删除 drop database if exists db_msg cascade ; --创建数据库 create database db_msg ; --切换数据库 use db_msg ; ```
--建表
CREATE TABLE db_msg.tb_msg_source(
    msg_time STRING COMMENT "消息发送时间",
    sender_name STRING COMMENT "发送人昵称",
    sender_account STRING COMMENT "发送人账号",
    sender_sex STRING COMMENT "发送人性别",
    sender_ip STRING COMMENT "发送人IP地址",
    sender_os STRING COMMENT "发送人操作系统",
    sender_phonetype STRING COMMENT "发送人手机型号",
    sender_network STRING COMMENT "发送人网络类型",
    sender_gps STRING COMMENT "发送人的GPS定位",
    receiver_name STRING COMMENT "接收人昵称",
    receiver_ip STRING COMMENT "接收人IP",
    receiver_account STRING COMMENT "接收人账号",
    receiver_os STRING COMMENT "接收人操作系统",
    receiver_phonetype STRING COMMENT "接收人手机型号",
    receiver_network STRING COMMENT "接收人网络类型",
    receiver_gps STRING COMMENT "接收人的GPS定位",
    receiver_sex STRING COMMENT "接收人性别",
    msg_type STRING COMMENT "消息类型",
    distance STRING COMMENT "双方距离",
    message STRING COMMENT "消息内容"
);
  • 数据文件上传到/home/hadoop,上传数据文件
  • 创建hadoop文件夹,上传数据文件到hdfs
hadoop fs -mkdir -p /chatdemo/data
hadoop fs -put chat_data-5W.csv /chatdemo/data/
  • 加载数据到表中
load data inpath '/chatdemo/data/chat_data-30W.csv' into table tb_msg_source;

ETL数据清洗

![](https://img-blog.csdnimg/img_convert/83b05bee47b0ac5c414000e859ad6dde.png)

// 创建新表
CREATE TABLE db_msg.tb_msg_etl(
    msg_time STRING COMMENT "消息发送时间",
    sender_name STRING COMMENT "发送人昵称",
    sender_account STRING COMMENT "发送人账号",
    sender_sex STRING COMMENT "发送人性别",
    sender_ip STRING COMMENT "发送人IP地址",
    sender_os STRING COMMENT "发送人操作系统",
    sender_phonetype STRING COMMENT "发送人手机型号",
    sender_network STRING COMMENT "发送人网络类型",
    sender_gps STRING COMMENT "发送人的GPS定位",
    receiver_name STRING COMMENT "接收人昵称",
    receiver_ip STRING COMMENT "接收人IP",
    receiver_account STRING COMMENT "接收人账号",
    receiver_os STRING COMMENT "接收人操作系统",
    receiver_phonetype STRING COMMENT "接收人手机型号",
    receiver_network STRING COMMENT "接收人网络类型",
    receiver_gps STRING COMMENT "接收人的GPS定位",
    receiver_sex STRING COMMENT "接收人性别",
    msg_type STRING COMMENT "消息类型",
    distance STRING COMMENT "双方距离",
    message STRING COMMENT "消息内容"
    msg_day string comment "消息日",
    msg_hour string comment "消息小时",
    sender_lng double comment "经度",
    sender_lat double comment "纬度"
);


SELECT 
    msg_time AS msg_time,
    DATE(msg_time) AS msg_day,
    *,
    HOUR(msg_time) AS msg_hour,
    SPLIT(sender_gps, ',')[0] AS sender_lng,
    SPLIT(sender_gps, ',')[1] AS sender_lat
FROM db_msg.tb_msg_source
WHERE LENGTH(sender_gps) > 0;

指标计算

![](https://img-blog.csdnimg/img_convert/ed8c8c387a92383c0b0500880d58f286.png)
// 统计今日消息总量
CREATE TABLE db_msg.tb_rs_total_msg_cnt COMMENT '每日消息总量' AS
SELECT msg_day, COUNT(*) AS total_msg_cnt FROM db_msg.tb_msg_etl GROUP BY msg_day;

-- 需求2:统计每小时的消息量、发送和接受的用户数量

create table db_msg.tb_rs_hour_msg_cnt comment '每小时消息量趋势' as
SELECT
    msg_hour,
    COUNT(*) AS total_msg_cnt,
    COUNT(DISTINCT sender_account) AS sender_user_cnt,
    COUNT(DISTINCT receiver_account) AS receiver_user_cnt
FROM db_msg.tb_msg_etl
GROUP BY msg_hour;

-- 统计今日各地区发送消息总数量
CREATE TABLE  db_msg.tb_rs_loc_cnt
COMMENT '今日各地区发送消息总数量'
AS
SELECT
    msg_day,
    sender_lng,
    sender_lat,
    COUNT(*) AS total_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY msg_day, sender_lng, sender_lat;

-- 统计今日发送和接收用户的数量
CREATE TABLE db_msg.tb_rs_user_cnt
COMMENT '每日发送和接收消息的人数'
AS
SELECT
    msg_day,
    COUNT(DISTINCT sender_account) AS sender_user_cnt,
    COUNT(DISTINCT receiver_account) AS receiver_user_cnt
FROM db_msg.tb_msg_etl
GROUP BY msg_day;

-- 统计发送消息最多的Top10用户
CREATE TABLE db_msg.tb_rs_s_user_top10
COMMENT '发送消息最多的10个用户'
AS
SELECT
    sender_name,
    COUNT(*) AS sender_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY sender_name
ORDER BY sender_msg_cnt DESC
LIMIT 10;

-- 统计接收消息最多的Top10用户
CREATE TABLE db_msg.tb_rs_r_user_top10
COMMENT '接收消息最多的10个用户'
AS
SELECT
    receiver_name,
    COUNT(*) AS receiver_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY receiver_name
ORDER BY receiver_msg_cnt DESC
LIMIT 10;


-- 统计发送人的手机型号分布情况
CREATE TABLE db_msg.tb_rs_sender_phone
COMMENT '发送人的手机型号分布'
AS
SELECT
    sender_phonetype,
    COUNT(*) AS cnt
FROM db_msg.tb_msg_etl
GROUP BY sender_phonetype;

-- 统计发送人的手机操作系统分布情况
CREATE TABLE db_msg.tb_rs_sender_os
COMMENT '发送人的手机型号分布'
AS
SELECT
    sender_os,
    COUNT(*) AS cnt
FROM db_msg.tb_msg_etl
GROUP BY sender_os;



可视化展现

![](https://img-blog.csdnimg/img_convert/eb7357ddd0444ec3f84e69ccbea4e7d9.png)

激活码:

启动步骤

:::color2 su - hadoop

:::


:::color2
#一键启动hdfs集群
start-dfs.sh

:::

一键关闭hdfs集群

stop-dfs.sh


:::color2
启动:start-yarn.sh

:::

停止:stop-yarn.sh

:::color2
历史服务器启动:mapred --daemon start historyserver

:::


:::color2
cd /export/server/hive

:::

启动元数据管理服务(必须启动,否则无法工作)

前台启动:bin/hive --service metastore

:::color2
后台启动:nohup bin/hive --service metastore >> logs/metastore.log 2>&1 &

:::

启动客户端端,二选一(当前先选择Hive Shell方式)

Hive Shell方式(可以直接写SQL):bin/hive

:::tips
Hive ThriftServer方式(不可以直接写SQL,需要外部客户端链接使用):bin/hive --service hiveserver2

:::


启动元数据管理服务(必须启动,否则无法工作) 前台启动:bin/hive --service metastore 后台启动:nohup bin/hive --service metastore >> logs/metastore.log 2>&1 &
●启动客户端端,二选一(当前先选择Hive Shell方式) Hive Shell方式(可以直接写SQL):bin/hive Hive ThriftServer方式(不可以直接写SQL,需要外部客户端链接使用):bin/hive --service hiveserver2


使用代理客户端启用hive

:::color2
nohup bin/hive –service hiveserver2 >> logs/hiveserver2.log 2>&1 &

:::

启动:在hive目录输入bin/beeline
连接:!connect jdbc:hive2://node1:10000
输入用户名hadoop,密码跳过

VMware

网段设置

![](https://img-blog.csdnimg/img_convert/8dca3a7b1aabd0e79226f1f4c971fbdc.png)

配置ip

![](https://img-blog.csdnimg/img_convert/e24b65cf270e18954caba4e9da729315.png)

vim /etc/sysconfig/network-scripts/ifcfg-ens33

static

IPADDR=“192.168.88.103”

NETMASK=“255.255.255.0”

GATEWAY=“192.168.88.2”

DNS1=“192.168.88.2”

systemctl restart network

ifconfig

配置主机名映射

1.在Windows系统中修改hosts文件,填入如下内容:

192.168.88.101 node1

192.168.88.102 node2

192.168.88.103 node3

2.在3台Linux的/etc/hosts文件中,填入如下内容(3台都要添加)

192.168.88.101 node1

192.168.88.102 node2

192.168.88.103 node3

ssh免密登录

![](https://img-blog.csdnimg/img_convert/fe111797587048b7b262f4ff0e2f5202.png)

ssh-keygen -t rsa -b 4096

ssh-copy-id node1/2/3(三台机器都执行)

创建hadoop用户并配置免密登录

![](https://img-blog.csdnimg/img_convert/4807c4e9b6bbdec6cd08ca275a3d06ef.png)

useradd hadoop

passwd hadoop

虚拟机jdk配置

![](https://img-blog.csdnimg/img_convert/d8c811d3a91c7dad94b8230960bcbfbc.png)

上传到root文件夹

mkdir -p /export/server

tar -zxvf jdk-8u361-linux-x64.tar.gz -C /export/server/

cd /export/server

ln -s /export/server/jdk1.8.0_361 jdk

vim /etc/profile

export JAVA_HOME=/export/server/jdk

export PATH= P A T H : PATH: PATH:JAVA_HOME/bin

source /etc/profile

rm -f /usr/bin/java

ln -s /export/server/jdk/bin/java /usr/bin/java

jdkj复制到node2

scp r jdk1.8.0_361 node2:pwd/

防火墙 SELinux 时间同步

![](https://img-blog.csdnimg/img_convert/55d952e9e09a9b6df49a0d22769dd0b4.png)

systemctl stop firewalld

systemctl disable firewalld

vim /etc/sysconfig/selinux

SELINUX=disabled

重启:init 6

yum install -y ntp

rm -f /etc/localtime;sudo ln -s /usr/share/zoneinfo/Asia/shanghai /etc/localtime

ntpdate -u ntp.aliyun

systemctl start ntpd

systemctl enable ntpd

大数据软件生态

![](https://img-blog.csdnimg/img_convert/22c059e2c71ec4dd91e2ee2b44e5e1dd.png)

hadoop分布式文件系统(HDFS)

架构

可以在多台服务器上构建存储集群,存储海量的数据。

部署到虚拟机

![](https://img-blog.csdnimg/img_convert/0d0594008850706d5925c960af951539.png)

tar -zxvf hadoop-3.3.4.tar.gz -C /export/server/

cd /export/server

ln -s /export/server/hadoop-3.3.4 hadoop

cd etc/hadoop

vim workers

node1

node2

node3

vim hadoop-env.sh

export JAVA_HOME=/export/server/jdk
export HADOOP_HOME=/export/server/hadoop
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HADOOP_LOG_DIR=$HADOOP_HOME/logs

vim core-site.xml

修改

<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://node1:8020</value>
  </property>

  <property>
    <name>io.file.buffer.size</name>
    <value>131072</value>
  </property>
</configuration>

vim hdfs-site.xml

修改

<configuration>
  <property>
    <name>dfs.datanode.data.dir.perm</name>
    <value>700</value>
  </property>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/data/nn</value>
  </property>
  <property>
    <name>dfs.namenode.hosts</name>
    <value>node1,node2,node3</value>
  </property>
  <property>
    <name>dfs.blocksize</name>
    <value>268435456</value>
  </property>
  <property>
    <name>dfs.namenode.handler.count</name>
    <value>100</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/data/dn</value>
  </property>
</configuration>

在node1节点:

mkdir -p /data/nn

mkdir /data/dn

在node2和node3节点:

mkdir -p /data/dn

分发

在node1执行如下命令

cd /export/server

scp -r hadoop-3.3.4 node2:pwd/

scp -r hadoop-3.3.4 node3:pwd/

在node2执行,为hadoop配置软链接

#在node2执行如下命令

ln -s /export/server/hadoop-3.3.4 hadoop

在node3执行,为hadoop配置软链接

#在node3执行如下命令

ln -s /export/server/hadoop-3.3.4 hadoop

vim /etc/profile

#在/etc/profile文件底部追加如下内容

export HADOOP_HOME=/export/server/hadoop

export PATH= P A T H : PATH: PATH:HADOOP_HOME/bin:$HADOOP_HOME/sbin

source /etc/profile

chown -R hadoop:hadoop /data

chown -R hadoop:hadoop /export

格式化namenode

#确保以hadoop用户执行

su - hadoop

  • **<font style="color:rgb(44, 44, 54);">su hadoop</font>**:不加载目标用户的环境变量和配置文件,适合快速简单的用户切换。
  • **<font style="color:rgb(44, 44, 54);">su - hadoop</font>**:加载目标用户的环境变量和配置文件,适合需要完整环境配置的情况。

#格式化namenode

hadoop namenode -format

启动

#一键启动hdfs集群

start-dfs.sh

一键关闭hdfs集群

stop-dfs.sh

如果遇到命令未找到的错误,表明环境变量未配置好,可以以绝对路径执行

/export/server/hadoop/sbin/start-dfs.sh

/export/server/hadoop/sbin/stop-dfs.sh

:::danger
快照:hadoop的HDFS部署完成

:::

HDFS集群启停

**一键启停**

#一键启动hdfs集群
start-dfs.sh
# 一键关闭hdfs集群
stop-dfs.sh

单进程启停

HDFS文件系统的操作命令

![](https://img-blog.csdnimg/img_convert/e64803cfe53bff72ac8fcb96b2129813.png)

使用协议头:

两套命令系统

![](https://img-blog.csdnimg/img_convert/7aac35127b09392b6bad6d538b317501.png)

创建文件夹

1. 使用`hadoop fs`命令:
hadoop fs -mkdir [-p] <path> ...
  1. 使用hdfs dfs命令:
hdfs dfs -mkdir [-p] <path> ...

<path>参数表示要创建的新目录的路径。

-p选项的行为类似于Linux中的mkdir -p命令,即如果指定的路径包含多级目录,则会递归地创建所有不存在的父目录。

下面是一些具体的示例:

  • hadoop fs -mkdir -p /itcast/bigdata
  • hdfs fs -mkdir -p /itheima/hadoop

查看指定目录下的内容

```plain hadoop fs -ls [-h] [-R] [path ...] hdfs dfs -ls [-h] [-R] [path ...] ```
  • -ls: 列出指定目录的内容。
  • -h: 人性化显示文件大小,即将字节数转换为更易读的形式(如 KB, MB, GB 等)。
  • -R: 递归列出目录及其所有子目录的内容。

示例

hadoop fs -ls /user/hadoop/input
hdfs dfs -ls /user/hadoop/input

上传文件到hdfs指定目录下

+ `hadoop fs -put [-f] [-p] ... ` + `hdfs dfs -put [-f] [-p] ... ` + `-f`: 覆盖目标文件。如果目标文件已经存在,使用 `-f` 选项会覆盖已有文件。 + `-p`: 保留属性。保留源文件的权限、所有权和其他元数据。 + ``: 指定要上传的本地文件或目录的路径。 + ``: 指定HDFS中存放文件的目标路径。

示例

  • hadoop fs -put words.txt /itcast:

  • 将本地文件 words.txt 上传至HDFS的 /itcast 目录下。

  • hdfs dfs -put file:///etc/profile hdfs://node1:8020/itcast:

  • 将本地文件 /etc/profile 上传至HDFS的 node1:8020/itcast 目录下。

查看HDFS文件内容

+ `hadoop fs -cat ...` + `hdfs dfs -cat ...`

示例

  • hadoop fs -cat /itcast/words.txt:
  • 显示HDFS中 /itcast/words.txt 文件的所有内容。
  • hdfs dfs -cat /itcast/words.txt:
  • 同样显示HDFS中 /itcast/words.txt 文件的所有内容。

处理大文件

对于较大的文件,直接使用 -cat 可能会导致输出过多,难以阅读。因此结合管道符 |more 命令来分页查看文件内容:

  • hadoop fs -cat <src> | more
  • hdfs dfs -cat <src> | more

这里的 more 命令可以让用户逐页查看文件内容,按空格键翻页,按 q 键退出。

下载HDFS文件

+ `hadoop fs -get [-f] [-p] ... ` + `hdfs dfs -get [-f] [-p] ... ` + `-f`: 覆盖目标文件。如果目标文件已经存在,使用 `-f` 选项会覆盖已有文件。 + `-p`: 保留属性。保留源文件的权限、所有权和其他元数据。 + ``: 指定HDFS中要下载的文件或目录的路径。 + ``: 指定本地文件系统中保存文件的目标路径。

示例

  • hadoop fs -get /itcast/zookeeper.out ./test:

  • 下载HDFS中 /itcast/zookeeper.out 文件到本地文件系统中的 ./test 目录下。

  • hdfs dfs -get /itcast/zookeeper.out ./test:

  • 同样的操作,但使用的是 hdfs dfs 命令。

拷贝HDFS文件

+ `hadoop fs -cp [-f] ... ` + `hdfs dfs -cp [-f] ... `
  • -f: 覆盖目标文件。如果目标文件已经存在,使用 -f 选项会覆盖已有文件。
  • <src>: 指定HDFS中要复制的文件或目录的路径。
  • <dst>: 指定HDFS中接收文件的目标路径。

示例

  • hadoop fs -cp /small/1.txt /itcast:
  • 复制HDFS中 /small/1.txt 文件到 /itcast 目录下。
  • hadoop fs -cp /small/1.txt /itcast/666.txt:
  • 复制HDFS中 /small/1.txt 文件到 /itcast 目录下,并命名为 666.txt

追加数据到HDFS文件

+ `hadoop fs -appendToFile ... ` + `hdfs dfs -appendToFile ... ` + ``: 指定一个或多个本地文件作为输入,这些文件的内容会被追加到HDFS中的目标文件。 + ``: 指定HDFS中要追加数据的目标文件路径。
  • 如果 <localsrc> 参数为 -,则从标准输入读取数据。
  • 如果 <dst> 文件不存在,命令会先创建该文件再进行追加操作。

示例

  • echo "Hello World" | hadoop fs -appendToFile - /itcast/file.txt: 将字符串 “Hello World” 写入标准输入,然后追加到HDFS中 /itcast/file.txt 文件的末尾。
  • hadoop fs -appendToFile localfile1.txt localfile2.txt /itcast/combinedfile.txt: 将本地文件 localfile1.txtlocalfile2.txt 的内容追加到HDFS中 /itcast/combinedfile.txt 文件的末尾。

HDFS数据移动操作

+ `hadoop fs -mv ... ` + `hdfs dfs -mv ... ` + ``: 指定一个或多个源文件或目录的路径,这些是要被移动的对象。 + ``: 指定目标位置的路径,可以是一个新的文件名(如果是文件的话)或者一个新的目录(如果是整个目录树的话)。

:::tips

  • 移动文件或目录:将指定的文件或目录从一个位置移到另一个位置。
  • 重命名文件:通过改变 <src><dst> 的名称,可以达到重命名文件的目的。
  • hadoop fs -mv /test2.txt /itheima/abc.txt

:::

示例

  • hadoop fs -mv /old/path/to/file /new/path/to/file: 将文件从 /old/path/to/file 移动到 /new/path/to/file
  • hdfs dfs -mv /old/path/to/directory /new/path/to/directory: 将目录从 /old/path/to/directory 移动到 /new/path/to/directory

HDFS数据删除操作

+ `hadoop fs -rm -r [-skipTrash] URI [URI ...]` + `hdfs dfs -rm -r [-skipTrash] URI [URI ...]` + `-r`: 表示递归删除,即如果删除对象是目录,则会递归删除该目录及其所有子目录和文件。 + `-skipTrash`: 默认情况下,HDFS会在删除文件时将其移至回收站(.Trash)而非立即永久删除。使用 `-skipTrash` 选项可以直接跳过回收站,立即永久删除文件。 + `URI`: 指定要删除的文件或目录的路径。
  • 回收站功能默认关闭,若要开启需在 core-site.xml 文件中添加以下配置:
<property>
  <name>fs.trash.interval</name>

  <value>1440</value>

</property>

这里 fs.trash.interval 设置了回收站在多少分钟后自动清空,默认值为1440分钟(24小时)。

  • 此外,还可以配置回收站的检查点间隔时间:
<property>
  <name>fs.trash.checkpoint.interval</name>

  <value>120</value>

</property>

这里 fs.trash.checkpoint.interval 设置了每隔多少秒检查一次是否有文件需要从回收站清除,默认值为120秒。

示例

  • hadoop fs -rm -r /path/to/file_or_directory: 删除指定的文件或目录。
  • hdfs dfs -rm -r -skipTrash /path/to/file_or_directory: 不经过回收站,直接永久删除指定的文件或目录。

big data tool安装

IED下载插件

NFS网关

把HDFS文件部署到win本地磁盘

cd /export/server/hadoop/etc/hadoop/

vim core-site.xml

<property>
    <name>hadoop.proxyuser.hadoop.groups</name>
    <value>*</value>
</property>

<property>
    <name>hadoop.proxyuser.hadoop.hosts</name>
    <value>*</value>
</property>

<property>
  <name>nfs.suerpser</name>
  <value>hadoop</value>
</property>

<property>
  <name>nfs.dump.dir</name>
  <value>/tmp/.hdfs-nfs</value>
</property>

<property>
  <name>nfs.exports.allowed.hosts</name>
  <value>192.168.88.1 rw</value>
</property>

scp core-site.xml hdfs-site.xml node3: pwd/

停止集群

exit 到root用户

systemctl stop nfs

systemctl disable nfs

yum remove -y rpcbind

hdfs --daemon start portmap

hdfs --daemon start nfs3

启动HDFS集群:start-dfs.sh

net use X: \192.168.88.101!

HDFS副本配置

![](https://img-blog.csdnimg/img_convert/5b86aa0888749c82577037576f3d262a.png)

HDFS数据读写流程

![](https://img-blog.csdnimg/img_convert/79d0abe47cf9a51f6abd231547044b23.png)

分布式计算MapReduce

![](https://img-blog.csdnimg/img_convert/636ed4538492b587497edd2a06ea2d89.png)

MapReduce提供了2个编程接口:

Map

Reduce

其中 Map功能接口提供了“分散”的功能,由服务器分布式对数据进行处理

        Reduce功能接口提供了“汇总(聚合)”的功能,将分布式的处理结果汇总统计

用户如需使用MapReduce框架完成自定义需求的程序开发需要使用lava、Python等编程语言,实现Map Reduce功能接口即可。


分布式资源调度YARN

![](https://img-blog.csdnimg/img_convert/a24c46b0550b84ab5c1465063e8bc2ff.png)

YARN架构

![](https://img-blog.csdnimg/img_convert/82df9d5d2906da23630cd608ca4f9397.png)

MapReduce配置文件

cd /export/server/hadoop/etc/hadoop/

vim mapred-env.sh

# 设置JDK路径
export JAVA_HOME=/export/server/jdk

# 设置JobHistoryServer进程内存量为1G
export HADOOP_JOB_HISTORYSERVER_HEAPSIZE=1000

# 设置日志级别为INFO
export HADOOP_MAPRED_ROOT_LOGGER=INFO,RFA

vim mapred-site.xml

<property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    <description>MapReduce的运行框架设置为 YARN</description>
</property>

<property>
    <name>mapreduce.jobhistory.address</name>
    <value>node1:10020</value>
    <description>历史服务器通讯端口为 node1:10020</description>
</property>

<property>
    <name>mapreduce.jobhistory.webapp.address</name>

    <value>node1:19888</value>

    <description>历史服务器web端口为 node1 的 19888</description>

</property>

<property>
    <name>mapreduce.jobhistory.intermediate-done-dir</name>

    <value>/data/mr-history/tmp</value>

    <description>历史信息在HDFS的记录临时路径</description>

</property>

<property>
    <name>mapreduce.jobhistory.done-dir</name>

    <value>/data/mr-history/done</value>

    <description>历史信息在HDFS的记录路径</description>

</property>

<property>
    <name>yarn.app.mapreduce.am.env</name>

    <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>

    <description>MapReduce HOME 设置为 $HADOOP_HOME</description>

</property>

<property>
    <name>mapreduce.map.env</name>

    <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>

    <description>MapReduce HOME 设置为 $HADOOP_HOME</description>

</property>

<property>
    <name>mapreduce.reduce.env</name>

    <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>

    <description>MapReduce HOME 设置为 $HADOOP_HOME</description>

</property>

YARN部署

![](https://img-blog.csdnimg/img_convert/42c3ae848e670803f9edadd509393985.png)

# 设置 JDK 路径的环境变量
export JAVA_HOME=/export/server/jdk

# 设置 HADOOP_HOME 的环境变量
export HADOOP_HOME=/export/server/hadoop

# 设置配置文件路径的环境变量
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop

# 设置日志文件路径的环境变量
export HADOOP_LOG_DIR=$HADOOP_HOME/logs

<property>
    <name>yarn.resourcemanager.hostname</name>

    <value>node1</value>

    <description>ResourceManager设置在node1节点</description>

</property>

<property>
    <name>yarn.nodemanager.local-dirs</name>

    <value>/data/nm-local</value>

    <description>NodeManager中间数据本地存储路径</description>

</property>

<property>
    <name>yarn.nodemanager.log-dirs</name>

    <value>/data/nm-log</value>

    <description>NodeManager数据日志本地存储路径</description>

</property>

<property>
    <name>yarn.nodemanager.aux-services</name>

    <value>mapreduce_shuffle</value>

    <description>为MapReduce程序开启Shuffle服务</description>

</property>


<property>
    <name>yarn.log.server.url</name>

    <value>http://node1:19888/jobhistory/logs</value>

    <description>历史服务器URL</description>

</property>

<property>
    <name>yarn.web-proxy.address</name>

    <value>node1:8089</value>

    <description>代理服务器主机和端口</description>

</property>

<property>
    <name>yarn.log-aggregation-enable</name>

    <value>true</value>

    <description>开启日志聚合</description>

</property>

<property>
    <name>yarn.nodemanager.remote-app-log-dir</name>

    <value>/tmp/logs</value>

    <description>程序日志HDFS的存储路径</description>

</property>

<property>
    <name>yarn.resourcemanager.scheduler.class</name>

    <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>

    <description>选择公平调度器</description>

</property>

scp mapred-env.sh mapred-site.xml yarn-env.sh yarn-site.xml node2:`pwd`/
scp mapred-env.sh mapred-site.xml yarn-env.sh yarn-site.xml node3:`pwd`/

启动:start-yarn.sh

停止:stop-yarn.sh

历史服务器启动:mapred --daemon start historyserver

http://node1:8088

提交MapReduce程序至YARN运行

![](https://img-blog.csdnimg/img_convert/9f8435fcd7dc8296f40363c48037510c.png)

cd /export/server/hadoop/share/hadoop/mapreduce

hadoop-mapreduce-examples-3.3.4.jar

  1. 输入路径:指定数据输入的HDFS(Hadoop Distributed File System)路径。
  2. 输出路径:指定结果输出的HDFS路径。
  3. 处理过程:对输入路径内的数据中的单词进行计数,并将结果写入到输出路径。

数据准备:

  • 准备一份包含以下内容的数据文件 words.txt,并上传到HDFS中:
itheima itcast itheima itcast hadoop hdfs hadoop hdfs hadoop mapreduce hadoop yarn itheima hadoop itcast hadoop itheima itcast hadoop yarn mapreduce

HDFS操作命令:

  1. 创建输入目录 /input/wordcount
hadoop fs -mkdir -p /input
  1. 创建输出目录 /output
hadoop fs -mkdir /output
  1. words.txt 文件上传到HDFS的输入目录:
hadoop fs -put words.txt /input

执行MapReduce程序:

运行以下命令提交WordCount MapReduce程序到YARN执行:

hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.4.jar wordcount hdfs://node1:8020/input/ hdfs://node1:8020/output/wc

其中:

  • 参数 wordcount 表示运行jar包中的单词计数程序(Java Class)。
  • 第一个参数是数据输入路径 (hdfs://node1:8020/input/wordcount/)。
  • 第二个参数是结果输出路径 (hdfs://node1:8020/output/wc1)。

通过这些步骤,可以实现对HDFS中特定路径下的文本文件进行单词计数,并将结果保存在指定的输出路径下。

分布式SQL计算-Hive

![](https://img-blog.csdnimg/img_convert/e596f2de9fb42529d5359ea806cf4e85.png)

Hive在虚拟机部署

![](https://img-blog.csdnimg/img_convert/b4fa4d6527551a62ac85bd0ba3801625.png)
# 更新密钥
rpm --import https://repo.mysql/RPM-GPG-KEY-mysql-2022

# 安装 MySQL yum 仓库
rpm -Uvh http://repo.mysql/mysql57-community-release-el7-7.noarch.rpm

# 使用 yum 安装 MySQL
yum -y install mysql-community-server

# 启动 MySQL 并设置为开机启动
systemctl start mysqld
systemctl enable mysqld

# 查看 MySQL 服务状态
systemctl status mysqld

# 获取临时密码
grep 'temporary password' /var/log/mysqld.log

#登录
mysql -uroot -p

# 设置密码策略为 LOW
set global validate_password_policy=LOW;

# 设置密码最小长度为 4
set global validate_password_length=4;

# 修改 root 用户密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';

# 授予所有权限
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;

# 刷新权限
flush privileges;

<property>
    <name>hadoop.proxyuser.hadoop.hosts</name>
    <value>*</value>
</property>

<property>
    <name>hadoop.proxyuser.hadoop.groups</name>
    <value>*</value>
</property>

su - hadoop

cd /export/server/hadoop/etc/hadoop/

vim core-site.xml

su - hadoop
wget http://archive.apache/dist/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gz
tar -zxvf apache-hive-3.1.3-bin.tar.gz -C /export/server/
ln -s /export/server/apache-hive-3.1.3-bin hive

mv mysql-connector-java-5.1.34.jar /export/server/apache-hive-3.1.3-bin/lib/

cd have/conf

mv hive-env.sh.template hive-env.sh

vim hive-env.sh

export HADOOP_HOME=/export/server/hadoop
export HIVE_CONF_DIR=/export/server/hive
export HIVE_AUX_JARS_PATH=/export/server/hive/lib

vim hive-site.xml

<configuration>
  <property>
    <name>javax.jdo.option.ConnectionURL</name>

    <value>jdbc:mysql://node1:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8</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>


    <property>
    <name>hive.server2.thrift.bind.host</name>

    <value>node1</value>

  </property>
  

  <property>
    <name>hive.metastore.uris</name>

    <value>thrift://node1:9083</value>

  </property>

  <property>
    <name>hive.metastore.event.db.notification.api.auth</name>

    <value>false</value>

  </property>



</configuration>

CREATE DATABASE hive CHARSET UTF8;
cd /export/server/hive
./bin/schematool -initSchema -dbType mysql -verbos

cd …

cd bin

./schematool -initSchema -dbType mysql -verbos

chown -R hadoop:hadoop apache-hive-3.1.3-bin hive

  • 确保Hive文件夹所属为hadoop用户
  • 创建一个hive的日志文件文件夹:
    mkdir /export/server/hive/logs
  • 启动元数据管理服务(必须启动,否则无法工作)
    前台启动:bin/hive --service metastore
    后台启动:nohup bin/hive --service metastore >> logs/metastore.log 2>&1 &
  • 启动客户端端,二选一(当前先选择Hive Shell方式)
    Hive Shell方式(可以直接写SQL):bin/hive
    Hive ThriftServer方式(不可以直接写SQL,需要外部客户端链接使用):bin/hive --service hiveserver2

Hive体验执行SQL语句

首先,确保启动了Metastore服务。

可以执行:bin/hive,进入到Hive Shell环境中,可以直接执行SQL语句。

  • 创建表

CREATE TABLE test(id INT, name STRING, gender STRING);(没有指定数据库,自动创建到default数据库中)

  • 插入数据

INSERT INTO test VALUES(1,‘王力红’,‘男’), (2,‘周杰轮’,‘男’), (3,‘林志灵’,‘女’);

  • 查询数据

SELECT gender, COUNT(*) AS cnt FROM test GROUP BY gender;

Hive客户端

![](https://img-blog.csdnimg/img_convert/dcc392b2964fe2908b88908e7a03db08.png)

HiveServer2服务

![](https://img-blog.csdnimg/img_convert/b8774666dc79cd834f6c41577e966d7b.png)
nohup bin/hive --service hiveserver2 >> logs/hiveserver2.log 2>&1 &

beeline

![](https://img-blog.csdnimg/img_convert/03ece57dd5471f43f0d38e56450d5eb2.png)

启动:在hive目录输入bin/beeline

连接:!connect jdbc:hive2://node1:10000

输入用户名hadoop,密码跳过

Hive语法

数据库操作

创建数据库

create database if not exists myhive;

use myhive;

• 查看数据库详细信息

desc database myhive;

  • 创建数据库并指定HDFS存储位置
create database myhive storage location '/myhive';

使用location关键字,可以指定数据库在HDFS上的存储路径。

删除数据库

+ 删除一个空数据库,如果数据库下面有数据表,那么就会报错
drop database myhive;
  • 强制删除数据库,包含数据库下面的表一起删除
drop database myhive cascade;

创建数据库表

```sql CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_comment], ...)] [COMMENT table_comment] [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...) INTO num_buckets BUCKETS]] [ROW FORMAT row_format] [STORED AS file_format] [LOCATION hdfs_path] ```
  • EXTERNAL, 创建外部表
  • PARTITIONED BY, 分区表
  • CLUSTERED BY, 分桶表
  • STORED AS, 存储格式
  • LOCATION, 存储位置

内部表/外部表

在 Apache Hive 中,表可以分为两种类型:内部表(Managed Tables)和外部表(External Tables)。这两种表在管理和数据删除方面有一些重要的区别。

内部表(Managed Tables)

  1. 定义
    • 内部表是由 Hive 完全管理的数据表。
    • 当你创建一个内部表时,Hive 会在默认的仓库目录(通常是 hdfs://<namenode>:<port>/user/hive/warehouse)下创建一个子目录来存储表的数据。
  2. 创建语法
CREATE TABLE table_name (
    column1 datatype,
    column2 datatype,
    ...
)
[PARTITIONED BY (column3 datatype, ...)]
[CLUSTERED BY (column4, ...) SORTED BY (column5) INTO num_buckets BUCKETS]
[ROW FORMAT DELIMITED FIELDS TERMINATED BY 'char']
[STORED AS file_format]
[LOCATION hdfs_path];
  1. 数据存储
    • 默认情况下,数据存储在 Hive 的仓库目录下的一个子目录中。
    • 例如,如果你创建一个名为 employees 的表,数据将存储在 hdfs://<namenode>:<port>/user/hive/warehouse/employees 目录下。
  2. 数据删除
    • 当你删除一个内部表时,Hive 不仅会删除表的元数据,还会删除表对应的数据文件。
    • 例如:
DROP TABLE employees;

这条命令会删除 employees 表及其所有数据。

外部表(External Tables)

  1. 定义
    • 外部表是指数据存储在 Hive 仓库目录之外的表。
    • 创建外部表时,你需要指定数据的实际存储位置。
  2. 创建语法
CREATE EXTERNAL TABLE table_name (
    column1 datatype,
    column2 datatype,
    ...
)
[PARTITIONED BY (column3 datatype, ...)]
[CLUSTERED BY (column4, ...) SORTED BY (column5) INTO num_buckets BUCKETS]
[ROW FORMAT DELIMITED FIELDS TERMINATED BY 'char']
[STORED AS file_format]
LOCATION 'hdfs_path'

ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LOCATION '/tmp/test/test_extl1';
  1. 数据存储
    • 数据存储在你指定的 HDFS 路径下。
    • 例如,如果你创建一个名为 external_employees 的外部表,并指定数据存储在 /user/data/external_employees 目录下:
CREATE EXTERNAL TABLE external_employees (
    id INT,
    name STRING,
    department STRING
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION '/user/data/external_employees';
  1. 数据删除
    • 当你删除一个外部表时,Hive 只会删除表的元数据,而不会删除表对应的数据文件。
    • 例如:
DROP TABLE external_employees;

这条命令只会删除 external_employees 表的元数据,而不会删除存储在 /user/data/external_employees 目录下的数据文件。

总结

  • 内部表:数据由 Hive 管理,删除表时会删除数据。因此内部表不适合和其他工具共享数据。
  • 外部表:数据存储在指定的 HDFS 路径,删除表时只删除元数据,保留数据。

相互转换

hive数据的导入和导出

![](https://img-blog.csdnimg/img_convert/c9861e71e37f9979613a61c089a74eff.png)

我们使用 LOAD 语法,从外部将数据加载到Hive内,语法如下:

LOAD DATA [LOCAL] INPATH ‘filepath’ [OVERWRITE] INTO TABLE tablename;

1:上传数据文件到Linux系统

2:创建表

CREATE TABLE myhive.test_load_load(
    dt string COMMENT '时间(时分秒)',
    user_id string COMMENT '用户ID',
    word string COMMENT '搜索词',
    url string COMMENT '用户访问网址'
) COMMENT '搜索引擎日志表'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';

3:数据加载

load data local inpath '/home/hadoop/search_log.txt'  [overwrite] into table myhive.test_load_load;

Hive 从Linux本地文件系统加载数据。关键字 <font style="color:rgb(44, 44, 54);">local</font> 表示数据源是在本地文件系统上的。

load data inpath '/tmp/search_log.txt' overwrite into table myhive.test_load;

Hive 从 HDFS 加载数据。源数据文件会消失(本质是被移动到表所在的目录中)

分区表

![](https://img-blog.csdnimg/img_convert/f7b56d5dddf628a3b5abd3c3289bbe95.png)

分区表的概念

分区表是将表的数据按照一个或多个列的值分成多个部分,每个部分称为一个分区。每个分区可以存储在一个独立的目录中,这样在查询时可以根据分区条件快速定位到所需的数据。

创建分区表
单分区表
假设我们有一个日志表 `logs`,我们希望按日期进行分区。可以使用以下 SQL 语句创建单分区表:
CREATE TABLE logs (
    id INT,
    message STRING
)
PARTITIONED BY (dt STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';

在这个例子中,dt 列用于分区,每个分区将存储在不同的目录中。

多分区表
如果需要按多个列进行分区,可以使用多个 `PARTITIONED BY` 列。例如,按日期和小时进行分区:
CREATE TABLE logs (
    id INT,
    message STRING
)
PARTITIONED BY (dt STRING, hr STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';

查询分区表
查询分区表时,可以通过指定分区条件来提高查询效率。例如:
SELECT * FROM logs WHERE dt = '2023-10-01';
删除分区
可以使用 `ALTER TABLE` 语句删除分区:
ALTER TABLE logs DROP PARTITION (dt = '2023-10-01');

分桶表

分桶概念(Bucketing)
分桶是 Hive 中一种用于优化查询的技术,它通过将数据按照某个列的值进行哈希散列,并根据散列值将数据分布到多个文件中,这些文件被称为“桶”。每个桶可以看作是一个小的数据集,这样可以使得在处理大规模数据集时更加高效,尤其是在进行连接操作或者采样时。

优点

  • 提升查询效率:当需要对特定列进行过滤或聚合时,分桶可以减少需要扫描的数据量,从而加快查询速度。
  • 并行处理:由于数据已经被均匀地分配到了不同的桶中,因此可以更容易地实现并行处理。
  • 采样:对于大数据集,如果数据已经均匀地分布在各个桶中,那么从每个桶中抽取少量数据就可以得到一个代表性的样本,这对于数据探索和分析非常有用。

缺点

  • 增加数据准备时间:创建分桶表时,需要额外的时间来计算哈希值并将数据正确地放入相应的桶中。
  • 桶的数量选择:需要合理选择桶的数量,太少会导致数据倾斜,太多则可能增加存储开销和管理复杂度。
创建分桶表
在创建分桶表时,通常会指定一个或多个列作为分桶列,并指定桶的数量。例如,假设我们有一个用户行为日志表,我们希望基于用户的 `user_id` 进行分桶,可以这样创建表:

set hive.enforce.bucketing=true;

CREATE TABLE user_behavior (
    user_id INT,
    action STRING,
    time TIMESTAMP
)
CLUSTERED BY (user_id) INTO 32 BUCKETS
row format delimited fields terminated by '\t';

这里,CLUSTERED BY (user_id) 指定了分桶列,而 INTO 32 BUCKETS 则指定了将数据分为32个桶。

加载数据到分桶表
![](https://img-blog.csdnimg/img_convert/aacd87cf13aa3a5227dffa581edd197a.png)

修改表的sql操作

1. 修改表注释
```sql ALTER TABLE table_name SET TBLPROPERTIES ('comment' = 'new_comment'); ```

table_name 是你想要修改的表的名字,new_comment 是新的注释信息。

2. 表重命名
```sql ALTER TABLE old_table_name RENAME TO new_table_name; ```

old_table_name 是当前表的名字,new_table_name 是新名字。

3. 添加列
```sql ALTER TABLE table_name ADD COLUMNS (column_name column_type [COMMENT 'column_comment']); ```

table_name 是你要添加列的表的名字,column_name 是新列的名字,column_type 是新列的数据类型,可选的 COMMENT 用来提供列的说明。

4. 修改列名
```sql ALTER TABLE table_name CHANGE COLUMN old_column_name new_column_name column_type [COMMENT 'column_comment']; ```

old_column_name 是旧列名,new_column_name 是新列名,column_type 是列的新数据类型,COMMENT 是可选的列说明。

5. 删除表
```sql DROP TABLE IF EXISTS table_name; ```

IF EXISTS 是可选的,但建议加上,以防表不存在时出错。

6. 清空表
清除表中的所有数据,但保留表结构,无法清空外部表
TRUNCATE TABLE table_name;

请注意,TRUNCATE 不同于 DELETE,因为它不会触发任何触发器,而且它的执行速度更快。

7.添加分区
使用 ` ALTER TABLE ... ADD PARTITION` 语句。例如,假设有一个按日期分区的表 ` web_logs` ,你可以这样添加一个新的分区:
ALTER TABLE web_logs ADD PARTITION (dt='2024-01-01') LOCATION '/user/hive/warehouse/web_logs/dt=2024-01-01';

<font style="color:rgb(44, 44, 54);">dt</font> 是分区列,<font style="color:rgb(44, 44, 54);">2024-01-01</font> 是分区值,<font style="color:rgb(44, 44, 54);">LOCATION</font> 指定了分区数据在 HDFS 上的存储路径。如果不指定 <font style="color:rgb(44, 44, 54);">LOCATION</font>,Hive 会默认在表的目录下创建一个子目录来存储该分区的数据。

8.删除分区
会删除hive里面的元数据,但是不会删除hdfs里面的数据文件。
ALTER TABLE web_logs DROP PARTITION (dt='2024-01-01');

array数组

![](https://img-blog.csdnimg/img_convert/6af82229d97b1530a426278be651966e.png)

可以使用array数组类型,存储locations的数据,要求数据类型一致

CREATE TABLE myhive.test_array(
    name STRING,
    work_locations ARRAY<STRING>
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ',';

SELECT id, name, courses[0] AS first_course FROM stu
SELECT id, name, size(courses) AS num_courses FROM students;
SELECT id, name, array_contains(courses, 'Math') AS has_math FROM students;

map映射

![](https://img-blog.csdnimg/img_convert/56bb972cedb2ba2359ea4ca356f99b43.png)

create table myhive.test_map(
    id int,
    name string,
    members map<string,string>,
    age int
)
row format delimited
fields terminated by ','
COLLECTION ITEMS TERMINATED BY '#'
MAP KEYS TERMINATED BY ':';
select 
    id, 
    name, 
    members['father'], 
    members['mother']
from 
    myhive.test_map;
select 
    map_keys(members)
from 
    myhive.test_map;
-- ,看看谁有 sister 这个 key
SELECT *
FROM myhive.test_map
WHERE ARRAY_CONTAINS(map_keys(members), 'sister');
SELECT *
FROM myhive.test_map
WHERE ARRAY_CONTAINS(map_values(members), '王林');

struct数据类型

![](https://img-blog.csdnimg/img_convert/b3dee2bd1b6dba2d31d50ce9ec59ee9f.png) ![](https://img-blog.csdnimg/img_convert/6a8aba61c77010e986fea76751548589.png)
CREATE TABLE myhive.test_struct (
    id STRING,
    info STRUCT<name:STRING, age:INT>
)#info是struct的整体列名
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '#'
COLLECTION ITEMS TERMINATED BY ':';
SELECT id, info.name, info.age
FROM myhive.test_struct;

基本查询

**1. SELECT 语句**

SELECT 语句用于从表中选择数据。基本语法如下:

SELECT column1, column2, ...
FROM table_name;

2. 聚合函数

聚合函数用于对一组值进行计算并返回单个值。常见的聚合函数包括:

  • COUNT(*):计算行数。
  • COUNT(column):计算指定列的非空值数量。
  • SUM(column):计算指定列的总和。
  • AVG(column):计算指定列的平均值。
  • MIN(column):计算指定列的最小值。
  • MAX(column):计算指定列的最大值。
-- 计算表中所有行的数量
SELECT COUNT(*) FROM sales;

-- 计算销售额的总和
SELECT SUM(amount) FROM sales;

-- 计算平均销售额
SELECT AVG(amount) FROM sales;

-- 计算最小和最大销售额
SELECT MIN(amount), MAX(amount) FROM sales;

3. GROUP BY 子句

GROUP BY 子句用于将数据分组,通常与聚合函数一起使用。语法如下:

SELECT column1, aggregate_function(column2)
FROM table_name
GROUP BY column1;
-- 按产品类别分组,计算每个类别的销售总额
SELECT category, SUM(amount) AS total_sales
FROM sales
GROUP BY category;

-- 按客户分组,计算每个客户的订单数量
SELECT customer, COUNT(order_id) AS order_count
FROM orders
GROUP BY customer;

4. JOIN 子句

JOIN 子句用于将多个表中的数据组合在一起。常见的 JOIN 类型包括:

  • INNER JOIN:返回两个表中匹配的行。
  • LEFT JOIN:返回左表中的所有行,以及右表中匹配的行。如果没有匹配的行,则返回 NULL。
  • RIGHT JOIN:返回右表中的所有行,以及左表中匹配的行。如果没有匹配的行,则返回 NULL。
  • FULL OUTER JOIN:返回两个表中的所有行,如果没有匹配的行,则返回 NULL。
-- INNER JOIN 示例
SELECT o.order_id, o.customer, p.product_name, o.amount
FROM orders o
INNER JOIN products p ON o.product_id = p.product_id;

-- LEFT JOIN 示例
SELECT o.order_id, o.customer, p.product_name, o.amount
FROM orders o
LEFT JOIN products p ON o.product_id = p.product_id;

-- RIGHT JOIN 示例
SELECT o.order_id, o.customer, p.product_name, o.amount
FROM orders o
RIGHT JOIN products p ON o.product_id = p.product_id;

-- FULL OUTER JOIN 示例
SELECT o.order_id, o.customer, p.product_name, o.amount
FROM orders o
FULL OUTER JOIN products p ON o.product_id = p.product_id;

5. ORDER BY 子句

ORDER BY 子句用于对查询结果进行排序。语法如下:

SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;
-- 按销售额降序排列
SELECT customer, SUM(amount) AS total_sales
FROM sales
GROUP BY customer
ORDER BY total_sales DESC;

-- 按客户升序排列,按订单日期降序排列
SELECT customer, order_date, amount
FROM orders
ORDER BY customer ASC, order_date DESC;

正则表达式

![](https://img-blog.csdnimg/img_convert/15abeedf416088b4bad7cda556beef15.png)

:::color2
.是对.的进一步解释,两个符号不是独立的存在

:::

union联合

union用于将多个select语句的结果组合成单个结果集。 每个select语句返回的列的数量和名称必须相同。否则,将引发架构错误。
  • UNION:合并结果集并去除重复行。
  • UNION ALL:合并结果集并保留所有行,包括重复的行。
SELECT column1, column2, ...
FROM table1
UNION
SELECT column1, column2, ...
FROM table2
[UNION
SELECT column1, column2, ...
FROM table3]
...

采样(Sampling)

![](https://img-blog.csdnimg/img_convert/a889668f56a6d2646f3bd5854ccc5c75.png)

1. 基于行的采样

基于行的采样使用 `TABLESAMPLE` 关键字,可以通过指定百分比或行数来抽取样本。

SELECT *
FROM table_name
TABLESAMPLE (type AND expression);

按百分比采样

-- 抽取表中 10% 的行
SELECT *
FROM sales
TABLESAMPLE (10 PERCENT);

按行数采样

-- 抽取表中 1000 行
SELECT *
FROM sales
TABLESAMPLE (1000 ROWS);

2. 埋点采样(Bucket Sampling)

基于桶的采样是一种更精确的采样方法,它将数据分成多个桶,然后从每个桶中抽取样本。这种方法适用于大数据集,可以确保样本的均匀分布。

  • x:要抽取的桶编号。
  • y:总的桶数。
  • colname指代列名,表示根据给出的列名把数据分成y个桶,rand()表示把数据随机分桶。

假设我们有一个表 sales,我们想从该表中抽取 1/10 的数据。

-- 将数据分成 10 个桶,抽取第 1 个桶的数据
SELECT *
FROM sales
TABLESAMPLE (BUCKET 1 OUT OF 10 ON date);

3. 随机采样

Hive 还支持使用随机函数进行采样。可以使用 `RAND()` 函数来抽取随机样本。
-- 抽取表中随机的 10% 的行
SELECT *
FROM sales
WHERE RAND() <= 0.1;

虚拟列

![](https://img-blog.csdnimg/img_convert/e6a89fa9a8215a74fcd5827f6b31df70.png)

案例

需求分析

建库建表

```sql --如果数据库已存在就删除 drop database if exists db_msg cascade ; --创建数据库 create database db_msg ; --切换数据库 use db_msg ; ```
--建表
CREATE TABLE db_msg.tb_msg_source(
    msg_time STRING COMMENT "消息发送时间",
    sender_name STRING COMMENT "发送人昵称",
    sender_account STRING COMMENT "发送人账号",
    sender_sex STRING COMMENT "发送人性别",
    sender_ip STRING COMMENT "发送人IP地址",
    sender_os STRING COMMENT "发送人操作系统",
    sender_phonetype STRING COMMENT "发送人手机型号",
    sender_network STRING COMMENT "发送人网络类型",
    sender_gps STRING COMMENT "发送人的GPS定位",
    receiver_name STRING COMMENT "接收人昵称",
    receiver_ip STRING COMMENT "接收人IP",
    receiver_account STRING COMMENT "接收人账号",
    receiver_os STRING COMMENT "接收人操作系统",
    receiver_phonetype STRING COMMENT "接收人手机型号",
    receiver_network STRING COMMENT "接收人网络类型",
    receiver_gps STRING COMMENT "接收人的GPS定位",
    receiver_sex STRING COMMENT "接收人性别",
    msg_type STRING COMMENT "消息类型",
    distance STRING COMMENT "双方距离",
    message STRING COMMENT "消息内容"
);
  • 数据文件上传到/home/hadoop,上传数据文件
  • 创建hadoop文件夹,上传数据文件到hdfs
hadoop fs -mkdir -p /chatdemo/data
hadoop fs -put chat_data-5W.csv /chatdemo/data/
  • 加载数据到表中
load data inpath '/chatdemo/data/chat_data-30W.csv' into table tb_msg_source;

ETL数据清洗

![](https://img-blog.csdnimg/img_convert/83b05bee47b0ac5c414000e859ad6dde.png)

// 创建新表
CREATE TABLE db_msg.tb_msg_etl(
    msg_time STRING COMMENT "消息发送时间",
    sender_name STRING COMMENT "发送人昵称",
    sender_account STRING COMMENT "发送人账号",
    sender_sex STRING COMMENT "发送人性别",
    sender_ip STRING COMMENT "发送人IP地址",
    sender_os STRING COMMENT "发送人操作系统",
    sender_phonetype STRING COMMENT "发送人手机型号",
    sender_network STRING COMMENT "发送人网络类型",
    sender_gps STRING COMMENT "发送人的GPS定位",
    receiver_name STRING COMMENT "接收人昵称",
    receiver_ip STRING COMMENT "接收人IP",
    receiver_account STRING COMMENT "接收人账号",
    receiver_os STRING COMMENT "接收人操作系统",
    receiver_phonetype STRING COMMENT "接收人手机型号",
    receiver_network STRING COMMENT "接收人网络类型",
    receiver_gps STRING COMMENT "接收人的GPS定位",
    receiver_sex STRING COMMENT "接收人性别",
    msg_type STRING COMMENT "消息类型",
    distance STRING COMMENT "双方距离",
    message STRING COMMENT "消息内容"
    msg_day string comment "消息日",
    msg_hour string comment "消息小时",
    sender_lng double comment "经度",
    sender_lat double comment "纬度"
);


SELECT 
    msg_time AS msg_time,
    DATE(msg_time) AS msg_day,
    *,
    HOUR(msg_time) AS msg_hour,
    SPLIT(sender_gps, ',')[0] AS sender_lng,
    SPLIT(sender_gps, ',')[1] AS sender_lat
FROM db_msg.tb_msg_source
WHERE LENGTH(sender_gps) > 0;

指标计算

![](https://img-blog.csdnimg/img_convert/ed8c8c387a92383c0b0500880d58f286.png)
// 统计今日消息总量
CREATE TABLE db_msg.tb_rs_total_msg_cnt COMMENT '每日消息总量' AS
SELECT msg_day, COUNT(*) AS total_msg_cnt FROM db_msg.tb_msg_etl GROUP BY msg_day;

-- 需求2:统计每小时的消息量、发送和接受的用户数量

create table db_msg.tb_rs_hour_msg_cnt comment '每小时消息量趋势' as
SELECT
    msg_hour,
    COUNT(*) AS total_msg_cnt,
    COUNT(DISTINCT sender_account) AS sender_user_cnt,
    COUNT(DISTINCT receiver_account) AS receiver_user_cnt
FROM db_msg.tb_msg_etl
GROUP BY msg_hour;

-- 统计今日各地区发送消息总数量
CREATE TABLE  db_msg.tb_rs_loc_cnt
COMMENT '今日各地区发送消息总数量'
AS
SELECT
    msg_day,
    sender_lng,
    sender_lat,
    COUNT(*) AS total_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY msg_day, sender_lng, sender_lat;

-- 统计今日发送和接收用户的数量
CREATE TABLE db_msg.tb_rs_user_cnt
COMMENT '每日发送和接收消息的人数'
AS
SELECT
    msg_day,
    COUNT(DISTINCT sender_account) AS sender_user_cnt,
    COUNT(DISTINCT receiver_account) AS receiver_user_cnt
FROM db_msg.tb_msg_etl
GROUP BY msg_day;

-- 统计发送消息最多的Top10用户
CREATE TABLE db_msg.tb_rs_s_user_top10
COMMENT '发送消息最多的10个用户'
AS
SELECT
    sender_name,
    COUNT(*) AS sender_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY sender_name
ORDER BY sender_msg_cnt DESC
LIMIT 10;

-- 统计接收消息最多的Top10用户
CREATE TABLE db_msg.tb_rs_r_user_top10
COMMENT '接收消息最多的10个用户'
AS
SELECT
    receiver_name,
    COUNT(*) AS receiver_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY receiver_name
ORDER BY receiver_msg_cnt DESC
LIMIT 10;


-- 统计发送人的手机型号分布情况
CREATE TABLE db_msg.tb_rs_sender_phone
COMMENT '发送人的手机型号分布'
AS
SELECT
    sender_phonetype,
    COUNT(*) AS cnt
FROM db_msg.tb_msg_etl
GROUP BY sender_phonetype;

-- 统计发送人的手机操作系统分布情况
CREATE TABLE db_msg.tb_rs_sender_os
COMMENT '发送人的手机型号分布'
AS
SELECT
    sender_os,
    COUNT(*) AS cnt
FROM db_msg.tb_msg_etl
GROUP BY sender_os;



可视化展现

![](https://img-blog.csdnimg/img_convert/eb7357ddd0444ec3f84e69ccbea4e7d9.png)

激活码:

发布评论

评论列表 (0)

  1. 暂无评论