IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Hadoop大数据练习(一)——环境的安装配置 -> 正文阅读

[大数据]Hadoop大数据练习(一)——环境的安装配置

大数据实战练习

第一章 环境的安装配置



前言

Hadoop是一种分析和处理大数据的软件平台,是Appach的一个用Java语言所实现的开源软件的加框,在大量计算机组成的集群当中实现了对于海量的数据进行的分布式计算。
大数据(Big Data)指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。


一、节点准备

使用CentOS镜像进行安装三台虚拟机,此处不进行讲解;或者在阿里云购买三个服务器进行配置,首先我们要讲一下在配置Hadoop之前对三个节点的修改。

1.配置SSH免密登录

配置免密码登录的目的是为了能够让主机之间相互信任,不需要密码即可访【类似于配钥匙一样】
过程如下:

#! 每台机器均进入~/.ssh 目录进行操作
[root@xja66 ~]# cd ~/.ssh
#! 输入以下命令,一路回车,用以产生公钥和秘钥
[root@xja66 .ssh]# ssh-keygen -t rsa -P ''
#! 出现以下信息说明生成成功
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
******************** root@xja66
The key's randomart image is:
+---[RSA 2048]----+
|        .   ...o.|
|..     . o ..... |
|o.. . o =  ...+. |
| Eoo + * o .. oo |
|  =o* + S .    o.|
| o =.* . .    .. |
|..o.. o   . . .  |
| o+o..     . o   |
| .++.      .o    |
+----[SHA256]-----+
#! 将所有的id_rsa.pub文件进行合并(最简单的方法是将所有节点的文件内容追加到xja66主机上)
[root@xja66 .ssh]# cat ~/.ssh/id_rsa.pub | ssh root@xja66 'cat >> ~/.ssh/authorized_keys'
[root@xja67 .ssh]# cat ~/.ssh/id_rsa.pub | ssh root@xja66 'cat >> ~/.ssh/authorized_keys'
[root@xja68 .ssh]# cat ~/.ssh/id_rsa.pub | ssh root@xja66 'cat >> ~/.ssh/authorized_keys'
#! 查看xja66上的authorized_keys文件内容,类似如下即可
[root@xja66 .ssh]# more authorized_keys 
ssh-rsa ***************************
ssh-rsa ***************************
ssh-rsa ***************************
#! 将xja66上的authorized_keys文件分发到其他主机上
[root@xja66 .ssh]# scp ~/.ssh/authorized_keys root@xja67:~/.ssh/
[root@xja66.ssh]# scp ~/.ssh/authorized_keys root@xja68:~/.ssh/
#! 每台机器之间进行ssh免密码登录操作,包括自己与自己
[root@xja66 ~]# ssh xja66
[root@xja66 ~]# ssh xja67
[root@xja67 ~]# ssh xja66
[root@xja66 ~]# ssh xja68
[root@xja68 ~]# ssh xja66
[root@xja66 ~]# ssh xja67
[root@xja67 ~]# ssh xja67
[root@xja67 ~]# ssh xja68
[root@xja68 ~]# ssh xja67
[root@xja67 ~]# ssh xja68
[root@xja68 ~]# ssh xja68

本处不需要设置第三个节点的SSH免密登录,这里设置的时候可以修改内容,根据自己的需要设置。

2.创建普通用户admin

在这里我们使用普通用户,如大家所知,进入公司后我们不会得到root用户,并且root用户的权限过高,对我们使用学习等并不好。

useradd admin  创建admin用户 
Passwd admin 对admin用户设置密码

3.为普通用户设置sudo切换

sudo 命令是 Linux 系统环境下,普通用户在普通用户状态下,完成超级用户所需要完成的任务时执行的命令。
安装如下文档配置步骤,分别安装xja66,xja67,xja68三台主机。
chmod u+w /etc/sudoers
修改/etc/sudoers文件,找到下面一行(91行),在root下面添加一行,如下所示:

## Allow root to run any commands anywhere
root    ALL=(ALL)     ALL
#whell ALL=(ALL)     ALL
admin   ALL=(ALL)     NOPASSWD: ALL

改完之后 再把权限改回去
chmod u-w /etc/sudoers

4.准备文件

在/opt目录下创建文件夹
(1)在/opt目录下创建module、software文件夹

sudo mkdir module
sudo mkdir software

(2)修改module、software文件夹的所有者cd

sudo mkdir /opt/module /opt/software
sudo chown bw:bw /opt/module /opt/software

上传文件到software文件夹下

[admin@xja66 ~]$ cd /opt/software/
[admin@xja66 software]$ ll
总用量 1392412
-rw-rw-r--. 1 admin admin    277604 125 02:36 01_mysql-community-common-5.7.16-1.el7.x86_64.rpm
-rw-rw-r--. 1 admin admin   2237116 125 02:36 02_mysql-community-libs-5.7.16-1.el7.x86_64.rpm
-rw-rw-r--. 1 admin admin   2112700 125 02:36 03_mysql-community-libs-compat-5.7.16-1.el7.x86_64.rpm
-rw-rw-r--. 1 admin admin  25034716 125 02:36 04_mysql-community-client-5.7.16-1.el7.x86_64.rpm
-rw-rw-r--. 1 admin admin 159295840 125 02:37 05_mysql-community-server-5.7.16-1.el7.x86_64.rpm
-rw-rw-r--. 1 admin admin  67938106 125 02:37 apache-flume-1.9.0-bin.tar.gz
-rw-rw-r--. 1 admin admin 314027421 125 02:37 apache-hive-3.1.2-bin.tar.gz
-rw-rw-r--. 1 admin admin   9311744 125 02:37 apache-zookeeper-3.5.7-bin.tar.gz
-rw-rw-r--. 1 admin admin 224565455 125 02:37 bigtable.lzo
-rw-rw-r--. 1 admin admin 338075860 125 02:36 hadoop-3.1.3.tar.gz
-rw-rw-r--. 1 admin admin 195013152 125 02:36 jdk-8u212-linux-x64.tar.gz
-rw-rw-r--. 1 admin admin  70159813 125 02:36 kafka_2.11-2.4.1.tgz
-rw-rw-r--. 1 admin admin    872303 125 02:37 mysql-connector-java-5.1.27-bin.jar
-rw-rw-r--. 1 admin admin  16870735 125 02:36 sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz

解释

software文件夹是存放软件压缩包的,而module文件夹是软件安装的

5.卸载JDK

当使用阿里云服务器时,每个节点都是纯净的,所以节点里面没有自带的JDK,本步不需要操作。

[admin@xja66 ~]$ rpm -qa|grep java
python-javapackages-3.4.1-11.el7.noarch
java-1.8.0-openjdk-headless-1.8.0.161-2.b14.el7.x86_64
tzdata-java-2018c-1.el7.noarch
java-1.7.0-openjdk-1.7.0.171-2.6.13.2.el7.x86_64
java-1.8.0-openjdk-1.8.0.161-2.b14.el7.x86_64
javapackages-tools-3.4.1-11.el7.noarch
java-1.7.0-openjdk-headless-1.7.0.171-2.6.13.2.el7.x86_64
[admin@xja66 ~]$ rpm -e --nodeps python-javapackages-3.4.1-11.el7.noarch java-1.8.0-openjdk-headless-1.8.0.161-2.b14.el7.x86_64 tzdata-java-2018c-1.el7.noarch java-1.7.0-openjdk-1.7.0.171-2.6.13.2.el7.x86_64 java-1.8.0-openjdk-1.8.0.161-2.b14.el7.x86_64 javapackages-tools-3.4.1-11.el7.noarch java-1.7.0-openjdk-headless-1.7.0.171-2.6.13.2.el7.x86_64
错误:can't create 事务 lock on /var/lib/rpm/.rpm.lock (权限不够)
[admin@xja66 ~]$ su root
密码:
[root@xja66 admin]# rpm -e --nodeps python-javapackages-3.4.1-11.el7.noarch java-1.8.0-openjdk-headless-1.8.0.161-2.b14.el7.x86_64 tzdata-java-2018c-1.el7.noarch java-1.7.0-openjdk-1.7.0.171-2.6.13.2.el7.x86_64 java-1.8.0-openjdk-1.8.0.161-2.b14.el7.x86_64 javapackages-tools-3.4.1-11.el7.noarch java-1.7.0-openjdk-headless-1.7.0.171-2.6.13.2.el7.x86_64

解释

第一步:先查 rpm -qa|grep java 给你出来一大堆东西 全删
第二步:rpm -e --nodeps 把一大堆东西 复制上 空格隔开
另外,删除操作是root用户下的权限,我在这里就出现了错误,又切换到root用户下。
三个节点都需要删除!!!

6.配置环境变量

必须使用 root 
sudo vi /etc/profile.d/my-env.sh
使其生效  不加sudo
source /etc/profile.d/my-env.sh 

到此我们前期准备工作就完成了。


二、Hadoop环境搭建

本次的练习中不使用MapReduce处理数据,仅使用hdfs存放数据,yarn管理,所以对MapReduce的配置没有过多讲解,仅进行了基本的配置,需要的例行配置。

1.安装JDK

解压

[admin@xja66 ~]$ tar -zxvf /opt/software/jdk-8u212-linux-x64.tar.gz -C /opt/module/

配置环境变量
(1)新建/etc/profile.d/my_env.sh文件

[admin@xja66 ~]$ sudo vim /etc/profile.d/my_env.sh
[sudo] admin 的密码:
[admin@xja66 ~]$ source /etc/profile.d/my_env.sh
添加如下内容,然后保存(:wq)退出
##JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_212
export PATH=$PATH:$JAVA_HOME/bin

(2) 测试安装成功

[admin@xja66 ~]$ java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)

(3)分发JDK

[admin@xja66 ~]$ scp -r /opt/module/jdk1.8.0_212/ admin@xja67:/opt/module/
[admin@xja66 ~]$ scp -r /opt/module/jdk1.8.0_212/ admin@xja68:/opt/module/

注意

分发过后不要忘记配置另外两个节点的环境变量并source

2.Hadoop安装

(1)解压安装包

[admin@xja66 ~]$ tar -zxvf /opt/software/hadoop-3.1.3.tar.gz -C /opt/module/
[admin@xja66 ~]$ cd /opt/module/
[admin@xja66 module]$ ll
总用量 8
drwxr-xr-x. 9 admin admin 4096 912 2019 hadoop-3.1.3
drwxr-xr-x. 7 admin admin 4096 42 2019 jdk1.8.0_212

(2)配置环境变量

[admin@xja66 module]$ sudo vim /etc/profile.d/my_env.sh
[sudo] admin 的密码:
[admin@xja66 module]$ source /etc/profile.d/my_env.sh 
添加如下内容
##HADOOP_HOME
export HADOOP_HOME=/opt/module/hadoop-3.1.3
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin

注意

在后面配置完相关文件后,进行Hadoop的分发,不要忘记需要在另外两个节点上进行环境变量的配置。

(3)配置集群

我们需要修改Hadoop的核心文件core-site.xml,hdfs-site.xml,yarn-site.xml,mapred-site.xml,workers。这五个文件都在Hadoop里/etc/hadoop文件夹里。进入文件夹后对几个文件进行如下修改。

[admin@xja66 ~]$ cd /opt/module/hadoop-3.1.3/etc/hadoop/
[admin@xja66 hadoop]$ ls
capacity-scheduler.xml            kms-log4j.properties
configuration.xsl                 kms-site.xml
container-executor.cfg            log4j.properties
core-site.xml                     mapred-env.cmd
hadoop-env.cmd                    mapred-env.sh
hadoop-env.sh                     mapred-queues.xml.template
hadoop-metrics2.properties        mapred-site.xml
hadoop-policy.xml                 shellprofile.d
hadoop-user-functions.sh.example  ssl-client.xml.example
hdfs-site.xml                     ssl-server.xml.example
httpfs-env.sh                     user_ec_policies.xml.template
httpfs-log4j.properties           workers
httpfs-signature.secret           yarn-env.cmd
httpfs-site.xml                   yarn-env.sh
kms-acls.xml                      yarnservice-log4j.properties
kms-env.sh                        yarn-site.xml

core-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
	<!-- 指定NameNode的地址 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://xja66:8020</value>
</property>
<!-- 指定hadoop数据的存储目录 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/module/hadoop-3.1.3/data</value>
</property>

<!-- 配置HDFS网页登录使用的静态用户为admin -->
    <property>
        <name>hadoop.http.staticuser.user</name>
        <value>admin</value>
</property>

<!-- 配置该admin(superUser)允许通过代理访问的主机节点 -->
    <property>
        <name>hadoop.proxyuser.admin.hosts</name>
        <value>*</value>
</property>
<!-- 配置该bw(superUser)允许通过代理用户所属组 -->
    <property>
        <name>hadoop.proxyuser.admin.groups</name>
        <value>*</value>
</property>
</configuration>

hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
	<!-- nn web端访问地址-->
	<property>
        <name>dfs.namenode.http-address</name>
        <value>xja66:9870</value>
    </property>
    
	<!-- 2nn web端访问地址-->
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>xja68:9868</value>
    </property>
    
    <!-- 测试环境指定HDFS副本的数量1 -->
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
</configuration>

yarn-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
	<!-- 指定MR走shuffle -->
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    
    <!-- 指定ResourceManager的地址-->
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>xja67</value>
    </property>
    
    <!-- task继承nodemanager环境变量-->
    <property>
        <name>yarn.nodemanager.env-whitelist</name>
        <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
    </property>
    
    <!-- yarn容器允许分配的最大最小内存 -->
    <property>
        <name>yarn.scheduler.minimum-allocation-mb</name>
        <value>512</value>
    </property>
    <property>
        <name>yarn.scheduler.maximum-allocation-mb</name>
        <value>4096</value>
    </property>
    
    <!-- yarn容器允许管理的物理内存大小 -->
    <property>
        <name>yarn.nodemanager.resource.memory-mb</name>
        <value>4096</value>
    </property>
    
    <!-- 关闭yarn对物理内存和虚拟内存的限制检查 -->
    <property>
        <name>yarn.nodemanager.pmem-check-enabled</name>
        <value>false</value>
    </property>
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
</configuration>

mapred-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
	<!-- 指定MapReduce程序运行在Yarn上 -->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
</configuration>

workers

xja66
xja67
xja68

注意

该文件中添加的内容结尾不允许有空格,文件中不允许有空行。

(4)配置日志的聚集

日志聚集概念:应用运行完成以后,将程序运行日志信息上传到HDFS系统上。
日志聚集功能好处:可以方便的查看到程序运行详情,方便开发调试。
注意:开启日志聚集功能,需要重新启动NodeManager 、ResourceManager和HistoryManager。

配置yarn-site.xml
vim yarn-site.xml
在该文件里面增加如下配置。

<!-- 开启日志聚集功能 -->
<property>
    <name>yarn.log-aggregation-enable</name>
    <value>true</value>
</property>

<!-- 设置日志聚集服务器地址 -->
<property>  
    <name>yarn.log.server.url</name>  
    <value>http://xja66:19888/jobhistory/logs</value>
</property>

<!-- 设置日志保留时间为7天 -->
<property>
    <name>yarn.log-aggregation.retain-seconds</name>
    <value>604800</value>
</property>

(5)分发

[admin@xja66 ~]$ scp -r /opt/module/hadoop-3.1.3/ admin@xja67:/opt/module/
[admin@xja66 ~]$ scp -r /opt/module/hadoop-3.1.3/ admin@xja68:/opt/module/

注意
分发后将另外两个节点的环境变量进行配置

(6)启动集群

1.格式化
如果集群是第一次启动,需要在bw33节点格式化NameNode(注意格式化之前,一定要先停止上次启动的所有namenode和datanode进程,然后再删除data和log数据)

[admin@xja66 ~]$ hdfs namenode -format

2.启动HDFS

[admin@xja66 ~]$ start-dfs.sh
Starting namenodes on [xja66]
xja66: Warning: Permanently added the ECDSA host key for IP address '192.168.189.76' to the list of known hosts.
Starting datanodes
xja68: WARNING: /opt/module/hadoop-3.1.3/logs does not exist. Creating.
xja67: WARNING: /opt/module/hadoop-3.1.3/logs does not exist. Creating.
Starting secondary namenodes [xja68]

3.启动YARN

[admin@xja67 ~]$ start-yarn.sh
Starting resourcemanager
Starting nodemanagers
xja68: Warning: Permanently added the ECDSA host key for IP address '192.168.189.78' to the list of known hosts.
xja67: Warning: Permanently added the ECDSA host key for IP address '192.168.189.77' to the list of known hosts.

4.查看web页面

HDFS的web页面
在这里插入图片描述
关闭

先关闭yarn
[admin@xja67 ~]$ stop-yarn.sh
Stopping nodemanagers
Stopping resourcemanager
再关闭hdfs
[admin@xja66 ~]$ stop-dfs.sh
Stopping namenodes on [xja66]
Stopping datanodes
Stopping secondary namenodes [xja68]

附加
为了更加便捷的开启Hadoop集群,我们可以编写一个脚本一键启动Hadoop,接下来我们讲解一下如何编写,此处可以跳过,感兴趣可以学习一下。

首先我们需要创建一个bin目录存放脚本
1.在家目录下创建bin目录
2.进入bin目录
3.编写hdp.sh脚本
4.保存:wq
5.修改脚本的权限

[admin@xja66 ~]$ mkdir bin
[admin@xja66 ~]$ cd bin
[admin@xja66 bin]$ vim hdp.sh
#在hdp.sh里面编写如下内容
#!/bin/bash
if [ $# -lt 1 ]
then
    echo "No Args Input..."
    exit ;
fi
case $1 in
"start")
        echo " =================== 启动 hadoop集群 ==================="

        echo " --------------- 启动 hdfs ---------------"
        ssh xja66 "/opt/module/hadoop-3.1.3/sbin/start-dfs.sh"
        echo " --------------- 启动 yarn ---------------"
        ssh xja67 "/opt/module/hadoop-3.1.3/sbin/start-yarn.sh"
        echo " --------------- 启动 historyserver ---------------"
        ssh xja66 "/opt/module/hadoop-3.1.3/bin/mapred --daemon start historyserver"
;;
"stop")
        echo " =================== 关闭 hadoop集群 ==================="

        echo " --------------- 关闭 historyserver ---------------"
        ssh xja66 "/opt/module/hadoop-3.1.3/bin/mapred --daemon stop historyserver"
        echo " --------------- 关闭 yarn ---------------"
        ssh xja67 "/opt/module/hadoop-3.1.3/sbin/stop-yarn.sh"
        echo " --------------- 关闭 hdfs ---------------"
        ssh xja66 "/opt/module/hadoop-3.1.3/sbin/stop-dfs.sh"
;;
*)
    echo "Input Args Error..."
;;
esac

[admin@xja66 bin]$ sudo chmod 777 hdp.sh 
[sudo] admin 的密码:
[admin@xja66 ~]$ hdp.sh start
 =================== 启动 hadoop集群 ===================
 --------------- 启动 hdfs ---------------
Starting namenodes on [xja66]
Starting datanodes
Starting secondary namenodes [xja68]
 --------------- 启动 yarn ---------------
Starting resourcemanager
Starting nodemanagers
 --------------- 启动 historyserver ---------------

为了更加便捷的查看集群情况,我们可以编写一个脚本一键查看。

1.进入bin目录
2.编写xcall.sh脚本
3.保存:wq
4.修改脚本的权限

[admin@xja66 ~]$ cd bin
[admin@xja66 bin]$ vim xcall.sh
#在xcall.sh里编写如下内容:
#! /bin/bash
 
for i in xja66 xja67 xja68
do
    echo --------- $i ----------
    ssh $i "$*"
done

[admin@xja66 bin]$ sudo chmod 777 xcall.sh 
[sudo] admin 的密码:
[admin@xja66 bin]$ xcall.sh jps
--------- xja66 ----------
7043 Jps
6360 DataNode
6682 NodeManager
6188 NameNode
6877 JobHistoryServer
--------- xja67 ----------
6500 Jps
5909 ResourceManager
5702 DataNode
6055 NodeManager
--------- xja68 ----------
5411 SecondaryNameNode
5283 DataNode
5752 Jps
5517 NodeManager

3.LZO压缩

hadoop本身并不支持lzo压缩,故需要使用twitter提供的hadoop-lzo开源组件。hadoop-lzo需依赖hadoop和lzo进行编译,编译步骤如下。

1.将编译好后的hadoop-lzo-0.4.20.jar 放入hadoop-3.1.3/share/hadoop/common/
2.同步hadoop-lzo-0.4.20.jar到另外两个节点
3.core-site.xml增加配置支持LZO压缩
4.对另外两个节点的core-site.xml进行配置

[admin@xja66 common]$ pwd
/opt/module/hadoop-3.1.3/share/hadoop/common
[admin@xja66 common]$ rz -E
rz waiting to receive.
[admin@xja66 common]$ ll
总用量 7352
-rw-r--r--. 1 admin admin 4096811 912 2019 hadoop-common-3.1.3.jar
-rw-r--r--. 1 admin admin 2878235 912 2019 hadoop-common-3.1.3-tests.jar
-rw-r--r--. 1 admin admin  129977 912 2019 hadoop-kms-3.1.3.jar
-rw-r--r--. 1 admin admin  193831 127 15:34 hadoop-lzo-0.4.20.jar
-rw-r--r--. 1 admin admin  201616 912 2019 hadoop-nfs-3.1.3.jar
drwxr-xr-x. 2 admin admin    4096 912 2019 jdiff
drwxr-xr-x. 2 admin admin    4096 912 2019 lib
drwxr-xr-x. 2 admin admin    4096 912 2019 sources
drwxr-xr-x. 3 admin admin    4096 912 2019 webapps
[admin@xja66 ~]$ cd /opt/module/hadoop-3.1.3/etc/hadoop/
[admin@xja66 hadoop]$ vim core-site.xml
#core-site.xml中添加如下内容:
<configuration>
    <property>
        <name>io.compression.codecs</name>
        <value>
            org.apache.hadoop.io.compress.GzipCodec,
            org.apache.hadoop.io.compress.DefaultCodec,
            org.apache.hadoop.io.compress.BZip2Codec,
            org.apache.hadoop.io.compress.SnappyCodec,
            com.hadoop.compression.lzo.LzoCodec,
            com.hadoop.compression.lzo.LzopCodec
        </value>
    </property>

    <property>
        <name>io.compression.codec.lzo.class</name>
        <value>com.hadoop.compression.lzo.LzoCodec</value>
    </property>
</configuration>

三、服务

1.Zookeeper安装

集群规划

项目服务器1服务器2服务器3
ZookeeperZookeeperZookeeperZookeeper

1.解压

[admin@xja66 ~]$ tar -zxvf /opt/software/apache-zookeeper-3.5.7-bin.tar.gz -C /opt/module/

2.修改名称

[admin@xja66 ~]$ cd /opt/module/
[admin@xja66 module]$ ll
总用量 12
drwxrwxr-x.  6 admin admin 4096 129 19:07 apache-zookeeper-3.5.7-bin
drwxr-xr-x. 11 admin admin 4096 129 07:05 hadoop-3.1.3
drwxr-xr-x.  7 admin admin 4096 42 2019 jdk1.8.0_212
[admin@xja66 module]$ mv apache-zookeeper-3.5.7-bin/ zookeeper-3.5.7

3.配置服务器编号

创建zkData文件夹,进入zkData后编写myid文件,在每个节点的myid里面添加服务器编号1,2,3

[admin@xja66 module]$ cd zookeeper-3.5.7/
[admin@xja66 zookeeper-3.5.7]$ mkdir zkData
[admin@xja66 zookeeper-3.5.7]$ cd zkData/
[admin@xja66 zkData]$ vim myid

注意 在分发后每个节点都需要修改myid文件,每个节点的编号都不一样。如下
在这里插入图片描述
4.配置zoo.cfg文件
【1】重命名zoo_sample_cfg文件

[admin@xja66 conf]$ ll
总用量 12
-rw-r--r--. 1 admin admin  535 54 2018 configuration.xsl
-rw-r--r--. 1 admin admin 2712 27 2020 log4j.properties
-rw-r--r--. 1 admin admin  922 27 2020 zoo_sample.cfg
[admin@xja66 conf]$ mv zoo_sample.cfg zoo.cfg 
[admin@xja66 conf]$ ll
总用量 12
-rw-r--r--. 1 admin admin  535 54 2018 configuration.xsl
-rw-r--r--. 1 admin admin 2712 27 2020 log4j.properties
-rw-r--r--. 1 admin admin  922 27 2020 zoo.cfg

【2】修改zoo_cfg文件

修改数据存储路径配置
dataDir=/opt/module/zookeeper-3.5.7/zkData
增加如下配置
#######################cluster##########################
server.1=xja66:2888:3888
server.2=xja67:2888:3888
server.3=xja68:2888:3888

5.分发到另外两个节点

[admin@xja66 conf]$ scp -r /opt/module/zookeeper-3.5.7/ admin@xja67:/opt/module/
[admin@xja66 conf]$ scp -r /opt/module/zookeeper-3.5.7/ admin@xja68:/opt/module/

6.配置3个节点环境变量

[admin@xja66 conf]$ sudo vim /etc/profile.d/my_env.sh 
[sudo] admin 的密码:
##在环境变量中添加ZOOKEEPER
##ZOOKEEPER_HOME
export ZOOKEEPER_HOME=/opt/module/zookeeper-3.5.7
export PATH=$PATH:$ZOOKEEPER_HOME/bin
[admin@xja66 conf]$ source /etc/profile.d/my_env.sh

7.修改服务器编号
在这里插入图片描述
在这里插入图片描述
具体操作查看步骤3

8.编写启动脚本

进入bin目录
编写zk.sh脚本
增加zk.sh权限
启动
关闭

[admin@xja66 ~]$ cd bin
[admin@xja66 bin]$ ll
总用量 8
-rwxrwxrwx. 1 admin admin 1104 129 07:33 hdp.sh
-rwxrwxrwx. 1 admin admin   99 129 07:39 xcall.sh
[admin@xja66 bin]$ vim zk.sh
[admin@xja66 bin]$ sudo chmod u+x zk.sh 
[sudo] admin 的密码:
[admin@xja66 bin]$ zk.sh start
---------- zookeeper xja66 启动 ------------
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
---------- zookeeper xja67 启动 ------------
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
---------- zookeeper xja68 启动 ------------
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

脚本内容

#!/bin/bash

case $1 in
"start"){
	for i in xja66 xja67 xja68
	do
        echo ---------- zookeeper $i 启动 ------------
		ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"
	done
};;
"stop"){
	for i in xja66 xja67 xja68
	do
        echo ---------- zookeeper $i 停止 ------------    
		ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh stop"
	done
};;
"status"){
	for i in xja66 xja67 xja68
	do
        echo ---------- zookeeper $i 状态 ------------    
		ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh status"
	done
};;
esac

2.Kafka安装

集群规划

服务器1服务器2服务器3
KafkaKafkaKafkaKafka

1.解压

[admin@xja66 ~]$ tar -zxvf /opt/software/kafka_2.11-2.4.1.tgz -C /opt/module/

2.修改文件名

[admin@xja66 ~]$ mv /opt/module/kafka_2.11-2.4.1/ /opt/module/kafka
[admin@xja66 ~]$ cd /opt/module/
[admin@xja66 module]$ ll
总用量 16
drwxr-xr-x. 11 admin admin 4096 129 07:05 hadoop-3.1.3
drwxr-xr-x.  7 admin admin 4096 42 2019 jdk1.8.0_212
drwxr-xr-x.  6 admin admin 4096 33 2020 kafka
drwxrwxr-x.  8 admin admin 4096 129 23:28 zookeeper-3.5.7

3.创建日志文件

[admin@xja66 module]$ cd kafka/
[admin@xja66 kafka]$ mkdir logs
[admin@xja66 kafka]$ ll
总用量 56
drwxr-xr-x. 3 admin admin  4096 33 2020 bin
drwxr-xr-x. 2 admin admin  4096 33 2020 config
drwxr-xr-x. 2 admin admin  4096 129 23:43 libs
-rw-r--r--. 1 admin admin 32216 33 2020 LICENSE
drwxrwxr-x. 2 admin admin  4096 129 23:45 logs
-rw-r--r--. 1 admin admin   337 33 2020 NOTICE
drwxr-xr-x. 2 admin admin  4096 33 2020 site-docs

4.修改配置文件

[admin@xja66 kafka]$ cd config/
[admin@xja66 config]$ vim server.properties
##修改内容如下
#broker的全局唯一编号,不能重复(修改)
broker.id=1
#删除topic功能使能(增加)
delete.topic.enable=true
#kafka运行日志存放的路径(修改)
log.dirs=/opt/module/kafka/logs
#配置连接Zookeeper集群地址(修改)
zookeeper.connect=xja66:2181,xja67:2181,xja68:2181

注意:broker.id在每个节点都不一样,在分发到其他节点后,要将另外两个节点的broker.id分别改为2,3。

5.配置环境变量

[admin@xja66 ~]$ sudo vim /etc/profile.d/my_env.sh 
[sudo] admin 的密码:
##KAFKA_HOME
export KAFKA_HOME=/opt/module/kafka
export PATH=$PATH:$KAFKA_HOME/bin
[admin@xja66 ~]$ source /etc/profile.d/my_env.sh

6.分发

[admin@xja66 ~]$ scp -r /opt/module/kafka/ admin@xja67:/opt/module/
[admin@xja66 ~]$ scp -r /opt/module/kafka/ admin@xja68:/opt/module/

分发完成后不要忘记配置环境变量,另外还有节点的broker.id也需要修改。

7.编写脚本

脚本的编写跟之前的过程类似,先来到bin目录下,编写kf.sh文件,将脚本代码写进去,完成后将文件修改权限,即可使用。

[admin@xja66 ~]$ cd bin
[admin@xja66 bin]$ vim kf.sh
[admin@xja66 bin]$ sudo chmod u+x kf.sh 
[sudo] admin 的密码:
[admin@xja66 bin]$ zk.sh start
---------- zookeeper xja66 启动 ------------
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
---------- zookeeper xja67 启动 ------------
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
---------- zookeeper xja68 启动 ------------
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[admin@xja66 bin]$ kf.sh start
 --------启动 xja66 Kafka-------
 --------启动 xja67 Kafka-------
 --------启动 xja68 Kafka-------
[admin@xja66 bin]$ xcall.sh jps
--------- xja66 ----------
3248 QuorumPeerMain
3786 Jps
3724 Kafka
--------- xja67 ----------
4023 Jps
3484 QuorumPeerMain
3948 Kafka
--------- xja68 ----------
4004 Kafka
3545 QuorumPeerMain
4061 Jps

脚本内容

#! /bin/bash

case $1 in
"start"){
    for i in xja66 xja67 xja68
    do
        echo " --------启动 $i Kafka-------"
        ssh $i "/opt/module/kafka/bin/kafka-server-start.sh -daemon /opt/module/kafka/config/server.properties"
    done
};;
"stop"){
    for i in xja66 xja67 xja68
    do
        echo " --------停止 $i Kafka-------"
        ssh $i "/opt/module/kafka/bin/kafka-server-stop.sh stop"
    done
};;
esac

Kafka常用命令
1)查看Kafka Topic列表
kafka-topics.sh --zookeeper xja66:2181/kafka --list
2)创建Kafka Topic
创建日志主题
kafka-topics.sh --zookeeper xja66:2181,xja67:2181,xja68:2181 --create --replication-factor 1 --partitions 1 --topic topic_log
3)删除Kafka Topic
kafka-topics.sh --delete --zookeeper xja66:2181,xja67:2181,xja68:2181 --topic topic_log
4)Kafka生产消息
kafka-console-producer.sh --broker-list xja66:9092 --topic topic_log
hello world
5)Kafka消费消息
kafka-console-consumer.sh --bootstrap-server xja67:9092 --topic topic_log
–from-beginning:会把主题中以往所有的数据都读取出来。根据业务场景选择是否增加该配置。
6)查看Kafka Topic详情
kafka-topics.sh --zookeeper bw33:2181/kafka
–describe --topic topic_log

创建topic_log为后面操作使用
kafka-topics.sh --topic topic_log --partitions 3 --zookeeper xja66:2181 --create --replication-factor 3

3.Flume安装

日志采集Flume

集群规划

服务器1服务器2服务器3
Flume(采集日志)FlumeFlume

1.解压

解压apache-flume-1.9.0-bin.tar.gz到/opt/module/目录下

[admin@xja66 ~]$ tar -zxvf /opt/software/apache-flume-1.9.0-bin.tar.gz -C /opt/module/

2.修改文件名

[admin@xja66 ~]$ mv /opt/module/apache-flume-1.9.0-bin/ /opt/module/flume
[admin@xja66 ~]$ cd /opt/module/
[admin@xja66 module]$ ll
总用量 20
drwxrwxr-x.  7 admin admin 4096 1210 06:05 flume
drwxr-xr-x. 11 admin admin 4096 129 07:05 hadoop-3.1.3
drwxr-xr-x.  7 admin admin 4096 42 2019 jdk1.8.0_212
drwxr-xr-x.  7 admin admin 4096 129 23:45 kafka
drwxrwxr-x.  8 admin admin 4096 129 23:28 zookeeper-3.5.7

3.删除架包

将lib文件夹下的guava-11.0.2.jar删除以兼容Hadoop 3.1.3

[admin@xja66 module]$ rm /opt/module/flume/lib/guava-11.0.2.jar

4.配置文件

将flume/conf下的flume-env.sh.template文件修改为flume-env.sh,并配置flume-env.sh文件
在/opt/module/flume/conf目录下创建并配置file-flume-kafka.conf文件

[admin@xja66 flume]$ cd conf/
[admin@xja66 conf]$ mv flume-env.sh.template flume-env.sh
[admin@xja66 conf]$ vim flume-env.sh 
[admin@xja66 conf]$ vim file-flume-kafka.conf

flume-env.sh

##修改JAVA_HOME为自己的JDK安装目录即可
export JAVA_HOME=/opt/module/jdk1.8.0_212

file-flume-kafka.conf

#为各组件命名
a1.sources = r1
a1.channels = c1

#描述source
a1.sources.r1.type = TAILDIR
a1.sources.r1.filegroups = f1
a1.sources.r1.filegroups.f1 = /opt/module/applog/log/app.*
a1.sources.r1.positionFile = /opt/module/flume/taildir_position.json

#描述channel
a1.channels.c1.type = org.apache.flume.channel.kafka.KafkaChannel
a1.channels.c1.kafka.bootstrap.servers = xja66:9092,xja67:9092
a1.channels.c1.kafka.topic = topic_log
a1.channels.c1.parseAsFlumeEvent = false

#绑定source和channel以及sink和channel的关系
a1.sources.r1.channels = c1

5.配置环境变量

##FLUME_HOME
export FLUME_HOME=/opt/module/flume
export PATH=$PATH:$FLUME_HOME/bin

6.分发

由于日志采集只需要前两个节点,我们只需要将flume分发给第二个节点就可以了,分发完成后不要忘记配置环境变量,分发过程如下:

[admin@xja66 conf]$ scp -r /opt/module/flume/ admin@xja67:/opt/module/

启动命令

flume-ng agent --name a1 --conf-file /opt/module/flume/conf/file-flume-kafka.conf &

日志采集Flume启动停止脚本
f1.sh

#! /bin/bash

case $1 in
"start"){
        for i in xja66 xja67
        do
                echo " --------启动 $i 采集flume-------"
                ssh $i "nohup /opt/module/flume/bin/flume-ng agent --conf-file /opt/module/flume/conf/file-flume-kafka.conf --name a1 -Dflume.root.logger=INFO,LOGFILE >/opt/module/flume/log1.txt 2>&1  &"
        done
};;	
"stop"){
        for i in xja66 xja67
        do
                echo " --------停止 $i 采集flume-------"
                ssh $i "ps -ef | grep file-flume-kafka | grep -v grep |awk  '{print \$2}' | xargs kill -9 "
        done

};;
esac

注意:不要忘记修改权限

消费Kafka数据Flume

集群规划

服务器1服务器2服务器3
Flume(消费Kafka)Flume

安装

将第一个节点上的flume分发给第三个节点,然后再进行配置,不要忘记配置环境变量

配置

在节点3的/opt/module/flume/conf目录下创建kafka-flume-hdfs.conf文件

kafka-flume-hdfs.conf

## 组件
a1.sources=r1
a1.channels=c1
a1.sinks=k1

## source1
a1.sources.r1.type = org.apache.flume.source.kafka.KafkaSource
##每个批次写入到channel中的event数量
a1.sources.r1.batchSize = 5000
##隔多长时间写入一次  这两个参数谁先达到按谁算 
a1.sources.r1.batchDurationMillis = 2000
a1.sources.r1.kafka.bootstrap.servers = xja66:9092,xja67:9092,xja68:9092
a1.sources.r1.kafka.topics=topic_log
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = com.bw.flume.interceptor.TimeStampInterceptor$Builder

## channel1
a1.channels.c1.type = file
##定期做快照的磁盘文件所在的目录
a1.channels.c1.checkpointDir = /opt/module/flume/checkpoint/behavior1
##真正存放数据的目录 
a1.channels.c1.dataDirs = /opt/module/flume/data/behavior1/
每个文件最大的值  
a1.channels.c1.maxFileSize = 2146435071
##最多能存放多少个索引 
a1.channels.c1.capacity = 1000000
##put写入到channel之前 需要先检查channel中是否有空间存放这批数据 如果有 
##那么就去写 如果没有 就等  如果 过了时间 就回滚 
a1.channels.c1.keep-alive = 6


## sink1
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = /origin_data/gmall/log/topic_log/%Y-%m-%d
a1.sinks.k1.hdfs.filePrefix = log-
##假如我想每个小时生成一个目录如何写? 
a1.sinks.k1.hdfs.round = true 
a1.sinks.k1.hdfs.roundValue = 1 
a1.sinks.k1.hdfs.rounvUnit = hour 

##这三个属性是处理小文件专用的  rollInterval 根据时间生成文件
##Rollsize 根据数据量生成  128m一个文件 
##Rollcount 根据数据个数生成 
a1.sinks.k1.hdfs.rollInterval = 10
a1.sinks.k1.hdfs.rollSize = 134217728
a1.sinks.k1.hdfs.rollCount = 0

## 控制输出文件是原生文件。
a1.sinks.k1.hdfs.fileType = CompressedStream
a1.sinks.k1.hdfs.codeC = lzop

## 拼装
a1.sources.r1.channels = c1
a1.sinks.k1.channel= c1

日志消费Flume启动停止脚本
f2.sh

#! /bin/bash

case $1 in
"start")
        for i in xja68
        do
                echo " --------启动 $i 消费flume-------"
                ssh $i "nohup /opt/module/flume/bin/flume-ng agent --conf-file /opt/module/flume/conf/kafka_flume_hdfs.conf --name a1 -Dflume.root.logger=INFO,LOGFILE >/opt/module/flume/log2.txt   2>&1 &"
        done
;;
"stop")
        for i in xja68
        do
                echo " --------停止 $i 消费flume-------"
                ssh $i "ps -ef | grep kafka_flume_hdfs | grep -v grep |awk '{print \$2}' | xargs -n1 kill"
        done

;;
esac

注意:不要忘记修改权限


四、其他

文章已经多次介绍如何编写脚本,此处就不进行讲解。

1.采集通道启动/停止脚本

为了简便打开各个服务,我们使用一键启动脚本。
接下来简单讲解一下采集通道启动/停止脚本
1.管理的集群服务有Zookeeper,Hadoop,Kafka,Flume
2.脚本汇总名称为cluster.sh,启动为start,关闭为stop

#!/bin/bash

case $1 in
"start"){
        echo ================== 启动 集群 ==================

        #启动 Zookeeper集群
        zk.sh start

        #启动 Hadoop集群
        hdp.sh start
        #启动 Kafka采集集群
        kf.sh start

        #启动 Flume采集集群
        f1.sh start

        #启动 Flume消费集群
        f2.sh start

        };;
"stop"){
        echo ================== 停止 集群 ==================

        #停止 Flume消费集群
        f2.sh stop

        #停止 Flume采集集群
        f1.sh stop

        #停止 Kafka采集集群
        kf.sh stop

        #停止 Hadoop集群
        hdp.sh stop

        #停止 Zookeeper集群
        zk.sh stop

};;
esac

2.集群所有进程查看脚本

为了快速操作3个节点,我们编写了集群所有进程查看脚本

#! /bin/bash
 
for i in bw33 bw34 bw35
do
    echo --------- $i ----------
    ssh $i "$*"
done

3.模拟数据

为了模拟实际运行情况,我们在这里模拟用户行为日志,下面讲解日志生成的内容。

1.创建日志目录

在module路径下创建applog目录,用于存放生成的日志和日志生成架包。

2.配置application.properties文件

# 外部配置打开
logging.config=./logback.xml
#业务日期
#根据自己情况设置日期,如2021-12-10
mock.date=****-**-**

#模拟数据发送模式
mock.type=log
#mock.type=http
#http模式下,发送的地址
mock.url=http://localhost:8080/applog

#启动次数
mock.startup.count=100
#设备最大值
mock.max.mid=50
#会员最大值
mock.max.uid=500
#商品最大值
mock.max.sku-id=10
#页面平均访问时间
mock.page.during-time-ms=20000
#错误概率 百分比
mock.error.rate=3
#每条日志发送延迟 ms
mock.log.sleep=10
#商品详情来源  用户查询,商品推广,智能推荐, 促销活动
mock.detail.source-type-rate=40:25:15:20

3.path.json
该文件用来配置访问路径
根据需求,可以灵活配置用户点击路径。

[
  {"path":["home","good_list","good_detail","cart","trade","payment"],"rate":20 },
  {"path":["home","search","good_list","good_detail","login","good_detail","cart","trade","payment"],"rate":50 },
  {"path":["home","mine","orders_unpaid","trade","payment"],"rate":10 },
  {"path":["home","mine","orders_unpaid","good_detail","good_spec","comments","trade","payment"],"rate":10 },
  {"path":["home","mine","orders_unpaid","good_detail","good_spec","comments","home"],"rate":10 }
]

4.logback配置文件
可配置日志生成路径,修改内容如下

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="LOG_HOME" value="/opt/module/applog/log" />
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

    <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

</configuration>

注意:这里应该还有一个日志生成架包,并将其上传到applog文件夹下
5.运行架包

java -jar 架包

6.日志生成脚本

lg.sh

#!/bin/bash
for i in xja66 xja67; do
    echo "========== $i =========="
    ssh $i "cd /opt/module/applog/; java -jar gmall2020-mock-log-2020-05-10.jar >/dev/null 2>&1 &"
done 

五、用户行为日志收集

1.启动集群,使用我们的一键启动脚本cluster.sh
2.生成用户行为日志信息,我们通过lg.sh手动模拟数据到来
3.查看hdfs上数据生成

在这里插入图片描述

总结

本章主要是在安装环境,我们通过flume采集用户行为日志,将其传到kafka,再由另一个flume接收kafka收集的信息,并上传至hdfs上。通过本章的学习,我们了解到了大数据各个服务是如何联系在一起,并依次完成任务。

文档为个人学习时记录,仅供参考学习,不涉及商业用途,如有侵权,请联系删除如有侵权请联系我删除

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-12-11 15:47:32  更:2021-12-11 15:47:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:33:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码