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 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> (超详细)基于Zookeeper的Hadoop HA集群的搭建 -> 正文阅读

[大数据](超详细)基于Zookeeper的Hadoop HA集群的搭建

基于Zookeeper的Hadoop HA集群的搭建

JunLeon——go big or go home


?前言:

????????高可用(high availability,HA)指的是若当前工作中的机器宕机了,系统会自动处理异常,并将工作无缝地转移到其他备用机器上,以保证服务的高可靠性与可用性。

????????Hadoop HA是hadoop2.0后新添加的特性,包括NameNode HA和ResourceManager HA。

????????NameNode HA采用双NameNode进行高可用,克服hadoop1.x中的单点问题。运行后,一个NameNode处于active状态,则另一处于standby状态。active NameNode节点对外提供服务,而standby NameNode节点不对外提供服务,仅仅同步active NameNode节点的状态,以便在active NameNode节点失效时快速切换继续提供服务。

????????Zookeeper是一个分布式协调服务,Zookeeper即可用来保证Hadoop集群的高可用性。通过zookeeper集群与Hadoop2.X中的两个NameNode节点之间的通信,保证集群中总有一个可用的NameNode(即active NameNode),从而实现双NameNode节点构成的NameNode HA,达到HDFS高可用性。同Zookeeper也可用来保证ResourceManager HA,即实现YARN高可用性。

说明:

该篇Zookeeper的安装及Hadoop HA的配置是基于Hadoop分布式的基础上去操作的,所用的命令都是在root用户下执行,hadoop的安装路径为:/opt/hadoop-2.7.3

Hadoop分布式的安装请查看:大数据学习——Hadoop集群完全分布式的搭建(超详细)_JunLeon的博客-CSDN博客

1、安装配置Zookeeper集群

? ? ? ? Zookeeper集群由基数台机器组成,分为leader和follower两个角色。写入数据时,要写入leader,leader同意后,再通知follower写入。客户端读取数据时,由于数据都是一样的,可以从任意一台机器上读取。而leader是选举出来的,集群中任意一台机器发现没有leader时,则会推荐自己为leader,当超过半数的机器同意它为leader时,选举结束。这样当leader宕机后很快就会选举出新的leader,保证工作正常进行。

(1)下载并上传解压Zookeeper安装包

  1. 环境准备

官网下载:Index of /zookeeper,自行选择版本下载即可

我使用的是zookeeper-3.4.12版本,如需下载:百度云链接:百度网盘 请输入提取码 提取码:8888

  1. 上传解压安装

使用XShell或者其他远程连接工具连接虚拟机进行上传到Linux系统的/opt/目录下

执行命令解压上传后的压缩包:

tar -zxvf /opt/zookeeper-3.4.12.tar.gz -C /opt/
  1. 配置环境变量

vi /etc/profile

以下包括jdk、hadoop的环境变量配置:

export JAVA_HOME=/opt/jdk1.8.0_161
export HADOOP_HOME=/opt/hadoop-2.7.3
export ZOOKEEPER_HOME=/opt/zookeeper-3.4.12
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin:$PATH

添加ZOOKEEPER_HOME变量:

使配置文件生效:

source /etc/profile

(2)修改配置文件

1 生成配置文件zoo.cfg

进入zookeeper主目录下的conf目录,将zoo_sample.cfg复制一份为zoo.cfg文件

cd /opt/zookeeper-3.4.12/conf
cp zoo_sample.cfg zoo.cfg

2 dataDir属性设置Zookeeper的数据存放的位置

vi zoo.cfg

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

参数说明:

tickTime=2000 表示zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,时间单位是毫秒

initLimit=10 表示Zookeeper服务器集群中连接到leader的Follower服务器初始化连接是最长能忍受多少个心跳的时间间隔数,总的时间长度就是10*2000=20秒。

syncLimit=5 表示标识leader与follower之间发送消息,请求和应答时间长度。最长不能超过多少个tickTime的时间长度,总的时间长度就是5*2000=10秒。

dataDir=/tmp/zookeeper 表示zookeeper的数据存放目录,默认在/tmp/zookeeper,此为修改项,默认情况下Zookeeper将写数据的日志文件也保存在这个目录里,也可以手动指定日志存放的目录。

clientPort=2181 表示客户端(应用程序)连接Zookeeper服务器的端口,Zookeeper会监听这个端口接受客户端的访问请求,默认为2181。

进入zoo.cfg文件后,定位到12行,配置Zookeeper数据存放的路径:

dataDir=/opt/zookeeper-3.4.12/data/zData

3 指定Zookeeper集群中各个节点的信息

vi zoo.cfg

打开zoo.cfg文件,在末尾添加如下几行

server.1=BigData01:2888:3888
server.2=BigData02:2888:3888
server.3=BigData03:2888:3888

各个节点的信息格式为: server.X=A:B:C

X-->指zookeeper节点的myid,标识这个是第几号服务器。

A-->指每个节点的IP地址或者主机名。

B-->指follower和leader交换消息所使用的端口。

C-->指选举leader所使用的端口。

注:server后面的数字是1到255,所以Zookeeper集群最多可以有255台机器。

3 创建myid文件

在Zookeeper主目录下创建dataDir指定的目录

mkdir -p data/zData

在创建好的目录下创建一个文件,文件名为myid,并输入id

cd /opt/zookeeper-3.4.12/data/zData
vi myid

输入1即可,另外两台节点分别为2、3

4 配置好的Zookeeper分发到其他节点

scp -r /opt/zookeeper-3.4.12 root@BigData02:/opt

scp -r /opt/zookeeper-3.4.12 root@BigData03:/opt

配置另外两台机器的myid,分别配置2、3

5 启动Zookeeper 集群及查看状态

启动Zookeeper命令:

在启动Zookeeper之前,首先关闭防火墙:service iptables stop

zkServer.sh start    # 需要在每一台机器上执行此命令

查看Zookeeper命令:

zkServer.sh status

此时能查看到其中有一台被选举为leader,另外两台为follower

?如果查看状态时出现如下问题:

?注:可能是防火墙没有关闭,关闭防火墙即可

关闭Zookeeper命令:

zkServer.sh stop

2、高可用分布式集群节点规划

????????本环境是在前面分布式的基础上增加的Zookeeper环境搭建,并采取Hadoop的双NameNode来保证HDFS的高可用性,故把Secondary NameNode改成NameNode。其中ResourceManager服务记录着当前集群的资源分配情况和Job的运行状态,可能会出现单点故障问题,故增加一个ResourceManager服务节点,并利用Zookeeper来实现ResourceManager自动故障转移,从而保证ResourceManager HA,实现YARN的高可用性。

节点规划

服务(角色)BigData01 (192.168.182.10)BigData02 (192.168.182.20)BigData03 (192.168.182.30)
NameNode
DataNode
ResourceManager
NodeManager
Zookeeper
JobHistoryServer

注:比较Hadoop分布式集群规划,将Secondary NameNode改为NameNode,采用了双ResourceManager,多了zookeeper节点。

3、安装配置Hadoop HA集群

因在Hadoop分布式的基础上进行配置,故无密码登录不做详细讲解,包括hadoop-env.sh、yarn-site.xml、mapred-site.xml、slaves等文件配置,详情请参照:大数据学习——Hadoop集群完全分布式的搭建(超详细)_JunLeon的博客-CSDN博客

(1)配置文件

  1. 配置hadoop-env.sh文件

    vi /opt/hadoop-2.7.3/etc/hadoop/hadoop-env.sh #在25行配置java路径即可

    配置此文件和hadoop完全分布式配置一样,可以不用去配置

  2. 配置core-site.xml文件

    vi /opt/hadoop-2.7.3/etc/hadoop/core-site.xml 在<configuration>中配置:

    <configuration>
     ? ?<property>
     ? ? ? ?<!-- 指定HDFS的通信地址,在NameNode HA中连接到nameservice的,
                            值为mycluster是需要在下一个hdfs-site.xml中配置的 -->
     ? ? ? ?<name>fs.defaultFS</name>
     ? ? ? ?<value>hdfs://mycluster</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 指定hadoop的临时目录,默认情况下NameNode和DataNode产生的数据都会存放在该路径 -->
     ? ? ? ?<name>hadoop.tmp.dir</name>
     ? ? ? ?<value>/opt/hadoopHA/tmp</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 指定Zookeeper地址(2181端口参考zoo.cfg配置文件) -->
     ? ? ? ?<name>ha.zookeeper.quorum</name>
     ? ? ? ?<value>BigData01:2181,BigData02:2181,BigData03:2181</value>
     ? ?</property>
    </configuration>
  3. 配置hdfs-site.xml文件

    vi /opt/hadoop-2.7.3/etc/hadoop/hdfs-site.xml 在<configuration>中配置:

    <configuration>
     ? ?<property>
     ? ? ? ?<!-- 给NameNode集群定义一个services name(NameNode集群服务名) -->
     ? ? ? ?<name>dfs.nameservices</name>
     ? ? ? ?<value>mycluster</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ? <!-- 设置nameservices包含的NameNode名称,分别命名为nn1,nn2 -->
     ? ? ? ?<name>dfs.ha.namenodes.mycluster</name>
     ? ? ? ?<value>nn1,nn2</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 设置名为nn1的NameNode的RPC的通信地址和端口号 -->
     ? ? ? ?<name>dfs.namenode.rpc-address.mycluster.nn1</name>
     ? ? ? ?<value>BigData01:9000</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 设置名为nn1的NameNode的HTTP的通信地址和端口号 -->
     ? ? ? ?<name>dfs.namenode.http-address.mycluster.nn1</name>
     ? ? ? ?<value>BigData01:50070</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 设置名为nn2的NameNode的RPC的通信地址和端口号 -->
     ? ? ? ?<name>dfs.namenode.rpc-address.mycluster.nn2</name>
     ? ? ? ?<value>BigData02:9000</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 设置名为nn2的NameNode的HTTP的通信地址和端口号 -->
     ? ? ? ?<name>dfs.namenode.http-address.mycluster.nn2</name>
     ? ? ? ?<value>BigData02:50070</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 设置NameNode的元数据在JournalNode上的存放路径
                    (即NameNode集群间的用于共享的edits日志的journal节点列表) -->
     ? ? ? ?<name>dfs.namenode.shared.edits.dir</name>
     ? ? ? ?<value>qjournal://BigData01:8485;BigData02:8485;BigData03:8485/mycluster</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ? <!-- 指定JournalNode上存放的edits日志的目录位置 -->
     ? ? ? ?<name>dfs.journalnode.edits.dir</name>
     ? ? ? ?<value>/opt/hadoopHA/tmp/dfs/journal</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 开启NameNode失败自动切换 -->
     ? ? ? ?<name>dfs.ha.automatic-failover.enabled</name>
     ? ? ? ?<value>true</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ? <!-- 配置NameNode失败后自动切换实现方式(客户端连接可用状态的NameNode所用的代理类) -->
     ? ? ? ?<name>dfs.client.failover.proxy.provider.mycluster</name>
     ? ? ? ?<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ? <!-- 配置隔离机制 -->
     ? ? ? ?<name>dfs.ha.fencing.methods</name>
     ? ? ? ?<value>sshfence</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ? <!-- 设置使用隔离机制时需要的SSH免密登录 -->
     ? ? ? ?<name>dfs.ha.fencing.ssh.private-key-files</name>
     ? ? ? ?<value>/root/.ssh/id_rsa</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ? <!-- 设置HDFS副本数量 -->
     ? ? ? ?<name>dfs.replication</name>
     ? ? ? ?<value>3</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ? <!-- 设置NameNode存放的路径 -->
     ? ? ? ?<name>dfs.namenode.name.dir</name>
     ? ? ? ?<value>/opt/hadoopHA/tmp/dfs/name</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ? <!-- 设置DataNode存放的路径 -->
     ? ? ? ?<name>dfs.datanode.data.dir</name>
     ? ? ? ?<value>/opt/hadoopHA/tmp/dfs/data</value>
     ? ?</property>
    </configuration>
  4. 配置yarn-site.xml文件

    vi /opt/hadoop-2.7.3/etc/hadoop/hdfs-site.xml 在<configuration>中配置:

    <configuration>
     ? ?<property>
     ? ? ? ?<!-- 启用ResourceManager的HA功能 -->
     ? ? ? ?<name>yarn.resourcemanager.ha.enabled</name>
     ? ? ? ?<value>true</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 开启ResourceManager失败自动切换 -->
     ? ? ? ?<name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
     ? ? ? ?<value>true</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 给ResourceManager HA集群命名id -->
     ? ? ? ?<name>yarn.resourcemanager.cluster-id</name>
     ? ? ? ?<value>yarn-cluster</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 指定ResourceManager HA有哪些节点 -->
     ? ? ? ?<name>yarn.resourcemanager.ha.rm-ids</name>
     ? ? ? ?<value>rm1,rm2</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 指定第一个节点在那一台机器 -->
     ? ? ? ?<name>yarn.resourcemanager.hostname.rm1</name>
     ? ? ? ?<value>BigData01</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 指定第二个节点在那一台机器 -->
     ? ? ? ?<name>yarn.resourcemanager.hostname.rm2</name>
     ? ? ? ?<value>BigData02</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 指定ResourceManager HA所用的Zookeeper节点 -->
     ? ? ? ?<name>yarn.resourcemanager.zk-address</name>
     ? ? ? ?<value>BigData01:2181,BigData02:2181,BigData03:2181</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 启用RM重启的功能,默认为false -->
     ? ? ? ?<name>yarn.resourcemanager.recovery.enabled</name>
     ? ? ? ?<value>true</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 用于状态存储的类 -->
     ? ? ? ?<name>yarn.resourcemanager.store.class</name>
     ? ? ? ?<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- NodeManager启用server的方式 -->
     ? ? ? ?<name>yarn-nodemanager.aux-services</name>
     ? ? ? ?<value>mapreduce_shuffle</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- NodeManager启用server使用算法的类 -->
     ? ? ? ?<name>yarn-nodemanager.aux-services.mapreduce.shuffle.class</name>
     ? ? ? ?<value>org.apache.hadoop.mapred.ShuffleHandler</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 启用日志聚合功能 -->
     ? ? ? ?<name>yarn.log-aggregation-enable</name>
     ? ? ? ?<value>true</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 聚集的日志在HDFS上保存最长的时间 -->
     ? ? ? ?<name>yarn.log-aggregation.retain-seconds</name>
     ? ? ? ?<value>106800</value>
     ? ?</property>
     ? ?<property>
     ? ? ? ?<!-- 聚集的日志在HDFS上保存最长的时间 -->
     ? ? ? ?<name>yarn.nodemanager.remote-app-log-dir</name>
     ? ? ? ?<value>/opt/hadoopHA/logs</value>
     ? ?</property>
    </configuration>

    以下配置属于默认的配置,有时运行MapReduce并行计算处理任务是=时出错而导致任务失败,故可以将以下配置参数加到yarn-site.xml文件内

    <property>
     ? ?<!-- ApplicationMaster通过该地址向RM申请资源、释放资源,
                    本设置是ResourceManager对ApplicationMaster暴露的地址 -->
     ? ?<name>yarn.resourcemanager.scheduler.address.rm1</name>
     ? ?<value>BigData01:8030</value>
    </property>
    <property>
     ? ?<!-- NodeManager通过该地址交换信息 -->
     ? ?<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
     ? ?<value>BigData01:8031</value>
    </property>
    <property>
     ? ?<!-- 客户机通过该地址向RM提交对应应用程序操作 -->
     ? ?<name>yarn.resourcemanager.address.rm1</name>
     ? ?<value>BigData01:8032</value>
    </property>
    <property>
     ? ?<!-- 管理员通过该地址向RM发送管理命令 -->
     ? ?<name>yarn.resourcemanager.admin.address.rm1</name>
     ? ?<value>BigData01:8033</value>
    </property>
    <property>
     ? ?<!-- RM HTTP访问地址,查看集群信息 -->
     ? ?<name>yarn.resourcemanager.webapp.address.rm1</name>
     ? ?<value>BigData01:8088</value>
    </property>
    <property>
     ? ?<!-- 同rm1对应内容 -->
     ? ?<name>yarn.resourcemanager.scheduler.address.rm2</name>
     ? ?<value>BigData02:8030</value>
    </property>
    <property>
     ? ?<!-- NodeManager通过该地址交换信息 -->
     ? ?<name>yarn.resourcemanager.resource-tracker.address.rm2</name>
     ? ?<value>BigData02:8031</value>
    </property>
    <property>
     ? ?<!-- 客户机通过该地址向RM提交对应应用程序操作 -->
     ? ?<name>yarn.resourcemanager.address.rm2</name>
     ? ?<value>BigData02:8032</value>
    </property>
    <property>
     ? ?<!-- 管理员通过该地址向RM发送管理命令 -->
     ? ?<name>yarn.resourcemanager.admin.address.rm2</name>
     ? ?<value>BigData02:8033</value>
    </property>
    <property>
     ? ?<!-- RM HTTP访问地址,查看集群信息 -->
     ? ?<name>yarn.resourcemanager.webapp.address.rm2</name>
     ? ?<value>BigData02:8088</value>
    </property>
  5. 配置mapred-site.xml文件

    配置此文件和hadoop完全分布式的MapReduce配置一样,可以不用去配置

  6. 配置slaves文件

    配置此文件和hadoop完全分布式的slaves配置一样,可以不用去配置

(2)将配置好的文件分发到其他节点上

scp ?-r  /opt/hadoop-2.7.3/etc/hadoop root@BigData02:/opt/hadoop-2.7.3/etc/
scp ?-r  /opt/hadoop-2.7.3/etc/hadoop root@BigData03:/opt/hadoop-2.7.3/etc/

(3)格式化NameNode

格式化之前先启动journalnode节点

hadoop-daemon.sh start journalnode  #三台机器都要执行该命令

格式化:

hdfs namenode -format   #格式化HDFS
hdfs zkfc -formatZK     #格式化Zookeeper

如果没有先启动journalnode节点,格式化出现以下问题:8485拒绝连接

如果启动journalnode还是出现上面问题, 可以在core-site.xml文件中添加如下参数:

<!--修改core-site.xml中的ipc参数,防止出现连接journalnode服务ConnectException-->
<property>
 ? ?<name>ipc.client.connect.max.retries</name>
 ? ?<value>100</value>
 ? ?<description>Indicates the number of retries a client will make to establish a server connection.</description>
</property>
<property>
 ? ?<name>ipc.client.connect.retry.interval</name>
 ? ?<value>10000</value>
 ? ?<description>Indicates the number of milliseconds a client will wait for before retrying to establish a server connection.</description>
</property>

注意:配置这两个参数化,NameNode稳定运行,但是格式化花的时间比较长,请耐心等待。

(4)启动/停止集群

启动集群命令:

开启全部节点(启动HDFS和YARN)

start-all.sh    #启动HDFS和YARN

启动Zookeeper

hadoop-daemon.sh start zkfc     #三台机器都要执行

启动HistoryServer节点(在BigData03机器上执行)

mr-jobhistory-daemon.sh start historyserver

单独启动HDFS和YARN

start-hdfs.sh   #启动HDFS
start-yarn.sh   #启动YARN

验证(查看是否启动成功)

jps

停止集群命令:

停止全部节点

stop-all.sh     #停止HDFS和YARN

单独停止HDFS和YARN

stop-hdfs.sh    #停止HDFS
stop-yarn.sh    #停止YARN

(5)Web端访问

?

4、查询集群信息及测试HDFS高可用性

(1)验证HDFS的高可用性

(2)验证YARN的高可用性

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-10-11 17:35:16  更:2021-10-11 17:36:24 
 
开发: 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 0:55:04-

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