目录
前言
一、GlusterFS概述
1、简介
2、特点
3、常用术语
4、模块化堆栈式架构
5、组件
二、工作原理
1、流程
2、弹性HASH算法
三、GlusterFS卷类型
1、分类
2、类型介绍
2.1 分布式卷
2.2 条带卷
2.3 复制卷
2.4 分布式条带卷
2.5 分布式复制卷
3、汇总
四、GlusterFS部署
1、环境
2、开局配置
2.1 所有的节点node都操作下面这些步骤,这里以node1:20.0.0.21为列
2.2 创建自动格式化,自动永久挂载脚本
2.3 搭建线网yum仓库
3、配置节点信息 任意一台
4、创建分布式卷
5、创建条带卷
6、创建复制卷
7、创建分布式条带
8、创建分布式复制卷
9、在客户机上安装gluster,创建挂载点后挂载
五、测试
1、卷中写入文件,客户端操作
2、查看文件分布
3.、破坏性测试
总结
开源的分布式文件系统
由存储服务器、可u段以及NFS/Samba存储网关组成
无元数据服务器
扩展性和高性能
高可用性
全局统一命名空间
弹性卷管理
基于标准协议
Brick(存储块)(砖):
指可信主机池中由主机提供的用于物理存储的专用分区(磁盘分区),是GlusterFS中的基本存储单元,同时也是可信存储池中服务器上对外提供的存储目录。
Volum(逻辑卷):
一个逻辑卷是一组Brick的集合。卷是数据存储的逻辑设备,类似于LVM中的逻辑卷。大部分Gluster管理操作是在卷上进行的
FUSE(filesystem inuserspace):
是一个内核模块,允许用户创建自己的文件系统,无需修改内核代码
VFS:
内核空间对用户空间提供的访问磁盘的接口。(客户机访问服务器的入口接口)
Gluster(后台管理进程):
在存储集群中每个节点上都要运行。
模块化,堆栈式的架构
通过对模块的组合,实现复杂的功能
存储服务器、客户端、NFS/Samba存储网关组成
客户端或应用程序通过GlusterFS的挂载点访问数据
linux系统内核通过VFS API收到请求并处理
VFS将数据递交给FUSE内核文件系统,fuse文件系统则是将数据通过/dev/fuse设备文件递交给了GlusterFS client端
GlusterFS client收到数据后,client根据配置文件的配置对数据进行处理
通过网络将数据传递至远端的GlusterFS Server,并且将数据写入到服务器存储设备上
通过HASH算法得到一个32位的整数
划分为N个连续的子空间,每个空间对应一个Brick
弹性HASH算法的优点
保证数据平均分布在每一个Brick中
解决了对元数据服务器的依赖,进而解决了单点故障以及访问瓶颈
分布式卷
条带卷
复制卷
分布式条带卷
分布式复制卷
条带复制卷
分布式条带复制卷
没有对文件进行分块处理
通过扩展文件属性保存hash值
支持底层的文件系统有EXT2、EXT4、ZFS、XFS等
没有分块处理,文件只能存在于以个server中,效率不提升
分布式卷的特点:
文件分布在不同的服务器,不具备冗余性
更容易和廉价地扩展卷的大小
单点故障会造成数据丢失
依赖底层的数据保护
创建分布式卷命令:
gluster volum create fb-volum server1:/dir1 server2:/dir2 server3:/dir3 force
#创建一个名为fb-volum的分布式卷,存储的文件将根据hash算法分布在server1、2、3:/dir1、2、3上。server1:/dir1是主机名:/挂载点
根据偏移量将文件分成N块(N个条带点),轮询的存储在每个brick server节点
存储大文件时,性能尤为突出
不具备冗余性,类似于raid0
从多个server中同时读取文件,效率提升
条带卷的特点:
数据被分割成更小块分布到块服务器群中的不同条带区
分布减少了负载且更小的文件加速了存取的速度
没有数据冗余
创建条带卷命令:
gluster volum create td-volum stricpe 2 transport tcp server1:/dir1 server2:/dir2 force
#创建一个名为td-volume的条带卷,文件将被分块轮询存储在server1:/dir1 server2:/dir2 两个brick中
同一文件保存一份或多份副本(类似raid1)
因为要保存副本,所以磁盘利用率较低
若多个节点上的存储空间不一致,将按照最低容量节点的容量作为该卷的总容量
复制卷的特点:
卷中所有的服务器均保存一个完整的副本
卷的副本数量可由客户创建的时候决定
至少由两个块服务器或更多服务器
具备冗余性
创建复制卷命令:
gluster volum create fz-volum replica 2 transport tcp server1:/dir1 server2:/dir2
#创建名为fz-volum的复制卷,文件将同时存储两个副本,分别在server1:/dir1 server2:/dir2 两个brick中
兼顾分布式卷和条带卷的功能(先条带后分布)
主要用于大文件访问处理
至少需要4台服务器
创建分布式条带卷的命令:
gluster volum create ft-volum stripe 2 transport tcp server1:/dir1 server2:/dir2 server3:/dir3 server4:/dir4
#创建名为ft-volum的分布式条带卷,配置分布式条带卷时,卷重brick所包含的存储服务器数量必须是条代卷数的倍数(两倍以上)
兼顾分布式卷和复制卷的功能
用于需要冗余的情况
创建分布式复制卷:
gluster volume create ff-volum replica 2 transport tcp server1:/dir1 server2:/dir2 server3:/dir3 server4:/dir4
#创建名为ff-volum的分布式条带卷,配置分布式复制卷时,卷重brick所包含的存储服务器数量必须是条带卷数的倍数(两倍以上)
分布式:存储brick不在一个区域范围,某一个区域内brick坏了,不影响另一个区域的brick。
条带式:多个brick形成一个整体,这个整体内的任意一块brick坏了,整个条带卷不可用。
复制卷:多个brick形成一个整体,这个整体内的每块brick都有完整的副本,由此,复制卷内任意一块brick坏了,不影响复制卷使用。
准备5台主机,分别位4台服务器和一台客户端
IP地址为:20.0.0.21,主机名为:node1,添加4块磁盘,均为20G大小
IP地址为:20.0.0.22,主机名为:node2,添加4块磁盘,均为20G大小
IP地址为:20.0.0.23,主机名为:node3,添加4块磁盘,均为20G大小
IP地址为:20.0.0.24,主机名为:node4,添加4块磁盘,均为20G大小
IP地址为:20.0.0.25,主机名为:client,当做测试机使用
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
[root@node1 ~]# vi /etc/hosts
20.0.0.21 node1
20.0.0.22 node2
20.0.0.23 node3
20.0.0.24 node4
更改主机名
hostnamectl set-hostname node1
hostnamectl set-hostname node2
hostnamectl set-hostname node3
hostnamectl set-hostname node4
[root@node1 ~]# vi gsf.sh
#!/bin/bash
for V in $(ls /dev/sd[b-z])
do
echo -e "n\np\n\n\n\nw\n" |fdisk $V
mkfs.xfs -i size=512 ${V}1 &>/dev/null
sleep 1
M=$(echo "$V" |awk -F "/" '{print $3}')
mkdir -p /data/${M}1 &>/dev/null
echo -e "${V}1 /data/${M}1 xfs defaults 0 0\n" >>/etc/fstab
mount -a &>/dev/null
done
[root@node1 ~]# chmod +x gsf.sh
[root@node1 ~]# ./gsf.sh
[root@node1 ~]# scp gsf.sh 20.0.0.22:/
[root@node1 ~]# scp gsf.sh 20.0.0.23:/
[root@node1 ~]# scp gsf.sh 20.0.0.24:/
[root@node1 abc]# cd /etc/yum.repos.d/
[root@node1 yum.repos.d]# mkdir bak
[root@node1 yum.repos.d]# mv C* /bak
[root@node1 yum.repos.d]# vim local.repo
[centos]
name=CentOS
baseurl=http://mirror.centos.org/centos/$releasever/storage/$basearch/gluster-3.12/
gpgcheck=0
enabled=1
[root@node1 yum.repos.d]# yum clean all
[root@node1 yum.repos.d]# yum list
[root@node1 yum.repos.d]# yum -y install glusterfs glusterfs-server glusterfs-fuse glusterfs-rdma
[root@node1 yum.repos.d]# ntpdate ntp1.aliyun.com
[root@node1 ~]# gluster peer probe node2 ##添加池子,peer匹配, probe信任+节点名称
peer probe: success.
[root@node1 ~]# gluster peer probe node3
peer probe: success.
[root@node1 ~]# gluster peer probe node4
peer probe: success.
查看节点池
[root@node1 ~]# gluster peer status
Number of Peers: 3
Hostname: node2
Uuid: 542a7be9-1a0c-43be-89db-57fe4db5a56f
State: Peer in Cluster (Connected)
Hostname: node3
Uuid: 2ca567f1-e92e-4215-9b09-e6c5e1f08f35
State: Peer in Cluster (Connected)
Hostname: node4
Uuid: 9110ff49-ab25-45d0-85fb-ad67fc266d7c
State: Peer in Cluster (Connected)
[root@node1 ~]# gluster peer status
Number of Peers: 3
[root@node2 ~]# gluster volume create dis-vol node1:/data/sdb1 node2:/data/sdb1 force
volume create: dis-vol: success: please start the volume to access data
查看分布式卷的详细信息
[root@node2 ~]# gluster volume info dis-vol
Volume Name: dis-vol
Type: Distribute
Volume ID: 028c2554-a6d6-48cd-a3ad-8778998c42da
Status: Created
Snapshot Count: 0
Number of Bricks: 2
Transport-type: tcp
Bricks:
Brick1: node1:/data/sdb1
Brick2: node2:/data/sdb1
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
开启分布式卷组
[root@node2 ~]# gluster volume start dis-vol
volume start: dis-vol: success
查看是不是开启状态
[root@node2 ~]# gluster volume info dis-vol
Volume Name: dis-vol
Type: Distribute
Volume ID: 028c2554-a6d6-48cd-a3ad-8778998c42da
Status: Started
Snapshot Count: 0
[root@node2 ~]# gluster volume create stripe-vol stripe 2 node1:/data/sdc1 node2:/data/sdc1 force
volume create: stripe-vol: success: please start the volume to access data
[root@node2 ~]# gluster volume info stripe-vol
Volume Name: stripe-vol
Type: Stripe
Volume ID: 4b9fe354-a14c-4cfa-9dbc-b887cf101d7c
Status: Created
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: node1:/data/sdc1
Brick2: node2:/data/sdc1
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
[root@node2 ~]# gluster volume start stripe-vol
volume start: stripe-vol: success
[root@node2 ~]# gluster volume info stripe-vol
Volume Name: stripe-vol
Type: Stripe
Volume ID: 4b9fe354-a14c-4cfa-9dbc-b887cf101d7c
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
[root@node2 ~]# gluster volume create rep-vol replica 2 node3:/data/sdb1 node4:/data/sdb1 force
volume create: rep-vol: success: please start the volume to access data
[root@node2 ~]# gluster volume info rep-vol
Volume Name: rep-vol
Type: Replicate
Volume ID: bb87f9dc-8260-44b8-8ba3-53aab9ae10be
Status: Created
Snapshot Count: 0
Xlator 1: BD
Capability 1: thin
Capability 2: offload_copy
Capability 3: offload_snapshot
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: node3:/data/sdb1
Brick1 VG:
Brick2: node4:/data/sdb1
Brick2 VG:
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
[root@node2 ~]# gluster volume start rep-vol
volume start: rep-vol: success
[root@node2 ~]# gluster volume create dis-stripe stripe 2 node1:/data/sdd1 node2:/data/sdd1 node3:/data/sdd1 node4:/data/sdd1 force
volume create: dis-stripe: success: please start the volume to access data
[root@node2 ~]# gluster volume info dis-stripe
Volume Name: dis-stripe
Type: Distributed-Stripe
Volume ID: 37af4c7c-4dcc-47a6-89b7-91443343b0a0
Status: Created
Snapshot Count: 0
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: node1:/data/sdd1
Brick2: node2:/data/sdd1
Brick3: node3:/data/sdd1
Brick4: node4:/data/sdd1
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
[root@node2 ~]# gluster volume start dis-stripe
volume start: dis-stripe: success
[root@node2 ~]# gluster volume info dis-stripe
Volume Name: dis-stripe
Type: Distributed-Stripe
Volume ID: 37af4c7c-4dcc-47a6-89b7-91443343b0a0
Status: Started
Snapshot Count: 0
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: node1:/data/sdd1
Brick2: node2:/data/sdd1
Brick3: node3:/data/sdd1
Brick4: node4:/data/sdd1
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
[root@node2 ~]# gluster volume create dis-rep replica 2 node1:/data/sde1 node2:/data/sde1 node3:/data/sde1 node4:/data/sde1 force
volume create: dis-rep: success: please start the volume to access data
[root@node2 ~]# gluster volume info dis-rep
Volume Name: dis-rep
Type: Distributed-Replicate
Volume ID: 12e0a204-b09d-427e-a43d-743fd709a096
Status: Created
Snapshot Count: 0
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: node1:/data/sde1
Brick2: node2:/data/sde1
Brick3: node3:/data/sde1
Brick4: node4:/data/sde1
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
[root@node2 ~]# gluster volume start dis-rep
volume start: dis-rep: success
[root@node2 ~]# gluster volume info dis-rep
Volume Name: dis-rep
Type: Distributed-Replicate
Volume ID: 12e0a204-b09d-427e-a43d-743fd709a096
Status: Started
Snapshot Count: 0
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: node1:/data/sde1
Brick2: node2:/data/sde1
Brick3: node3:/data/sde1
Brick4: node4:/data/sde1
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
[root@localhost ~]#yum -y install glusterfs glusterfs-fuse
[root@localhost ~]# mount.glusterfs ndl:fb-volum/fb
[root@localhost ~]# mount.glusterfsndl:td-volum/td
[root@localhost ~]# mount.glusterfs ndl:fz-volum/fz
[root@localhost ~]# mount.glusterfs ndl:fd-volum/fd
ERROR:Mount point does not exist
Please specify a mount point
Usage:
man 8 /usr/sbin/mount.glusterfs
[root@localhost ~]# mount.glusterfs nd1:ft-volum/ft
[root@localhost ~]# mount.glusterfs ndl:ff-volum/ff
[root@localhost ~]# df -Th
文件系统 类型 容量 已用 可用 已用%挂载点
/dev/sda5 xfs 46G 4.5G 42G 10%/
devtmpfs devtmpfs 898M 0 898M 0%/dev
tmpfs tmpfs 912M 0 912M 0%/dev/shm
tmpfs tmpfs 912M 9.1M 903M 1%/run
tmpfs tmpfs 912M 0 912M 0%/sys/fs/cgroup
/dev/sda2 xfs 5.0G 33M 5.0G 1% /home
/dev/sr0 iso9660 4.3G 4.3G 0 100%/mnt
/dev/sdal xfs 5.0G 174M 4.9G 4%/boot
tmpfs tmpfs 183M 12K 183M 1% /run/user/42
tmpfs tmpfs 183M 0 183M 0%/run/user/0
ndl:fb-volum fuse.glusterfs 9.6G 41M 9.1G 1%/fb
ndl:td-volum fuse.glusterfs 9.6G 41M 9.1G 1/td
ndl:fz-volum fuse.glusterfs 4.8G 21M 4.6G 1%/fz
ndl:ft-volum fuse.glusterfs 20G 81M 19G 1%/ft
nd1:ff-volum fuse.glusterfs 9.6G 41M 9.1G 1%/ff xin_50344914
cd /opt
dd if=/dev/zero of=/opt/demo1.log bs=1M count=40
dd if=/dev/zero of=/opt/demo2.log bs=1M count=40
dd if=/dev/zero of=/opt/demo3.log bs=1M count=40
dd if=/dev/zero of=/opt/demo4.log bs=1M count=40
dd if=/dev/zero of=/opt/demo5.log bs=1M count=40
ls -lh /opt
cp demo* /test/dis
cp demo* /test/stripe/
cp demo* /test/rep/
cp demo* /test/dis_stripe/
cp demo* /test/dis_rep/
#查看分布式文件分布
[root@node1 ~]# ls -lh /data/sdb1 #数据没有被分片
总用量 160M
-rw-r--r-- 2 root root 40M 12月 18 14:50 demo1.log
-rw-r--r-- 2 root root 40M 12月 18 14:50 demo2.log
-rw-r--r-- 2 root root 40M 12月 18 14:50 demo3.log
-rw-r--r-- 2 root root 40M 12月 18 14:50 demo4.log
[root@node2 ~]# ll -h /data/sdb1
总用量 40M
-rw-r--r-- 2 root root 40M 12月 18 14:50 demo5.log
#查看条带卷文件分布
[root@node1 ~]# ls -lh /data/sdc1 #数据被分片50% 没副本 没冗余
总用量 101M
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo1.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo2.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo3.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo4.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo5.log
[root@node2 ~]# ll -h /data/sdc1 #数据被分片50% 没副本 没冗余
总用量 101M
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo1.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo2.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo3.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo4.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo5.log
#查看复制卷分布
[root@node3 ~]# ll -h /data/sdb1 #数据没有被分片 有副本 有冗余
总用量 201M
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo1.log
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo2.log
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo3.log
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo4.log
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo5.log
[root@node4 ~]# ll -h /data/sdb1 #数据没有被分片 有副本 有冗余
总用量 201M
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo1.log
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo2.log
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo3.log
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo4.log
-rw-r--r-- 2 root root 40M 12月 18 14:51 demo5.log
#查看分布式条带卷分布
[root@node1 ~]# ll -h /data/sdd1 #数据被分片50% 没副本 没冗余
总用量 81M
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo1.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo2.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo3.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo4.log
[root@node2 ~]# ll -h /data/sdd1
总用量 81M
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo1.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo2.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo3.log
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo4.log
[root@node3 ~]# ll -h /data/sdd1
总用量 21M
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo5.log
[root@node4 ~]# ll -h /data/sdd1
总用量 21M
-rw-r--r-- 2 root root 20M 12月 18 14:51 demo5.log
#查看分布式复制卷分布 #数据没有被分片 有副本 有冗余
[root@node1 ~]# ll -h /data/sde1
总用量 161M
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo1.log
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo2.log
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo3.log
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo4.log
[root@node2 ~]# ll -h /data/sde1
总用量 161M
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo1.log
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo2.log
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo3.log
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo4.log
[root@node3 ~]# ll -h /data/sde1
总用量 41M
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo5.log
[root@node3 ~]#
[root@node4 ~]# ll -h /data/sde1
总用量 41M
-rw-r--r-- 2 root root 40M 12月 18 14:52 demo5.log
挂起 node2 节点或者关闭glusterd服务来模拟故障
[root@node2 ~]# systemctl stop glusterd.service
在客户端上查看文件是否正常
分布式卷数据查看
[root@localhost dis]# ll #在客户上发现少了demo5.log文件,这个是在node2上的
总用量 163840
-rw-r--r-- 1 root root 41943040 12月 18 14:50 demo1.log
-rw-r--r-- 1 root root 41943040 12月 18 14:50 demo2.log
-rw-r--r-- 1 root root 41943040 12月 18 14:50 demo3.log
-rw-r--r-- 1 root root 41943040 12月 18 14:50 demo4.log
条带卷
[root@localhost text]# cd stripe/ #无法访问,条带卷不具备冗余性
[root@localhost stripe]# ll
总用量 0
分布式条带卷
[root@localhost dis_and_stripe]# ll #无法访问,分布条带卷不具备冗余性
总用量 40960
-rw-r--r-- 1 root root 41943040 12月 18 14:51 demo5.log
#挂起 node2 和 node4 节点,在客户端上查看文件是否正常
#测试复制卷是否正常
[root@localhost rep]# ls -l #在客户机上测试正常 数据有
总用量 204800
-rw-r--r-- 1 root root 41943040 12月 18 14:51 demo1.log
-rw-r--r-- 1 root root 41943040 12月 18 14:51 demo2.log
-rw-r--r-- 1 root root 41943040 12月 18 14:51 demo3.log
-rw-r--r-- 1 root root 41943040 12月 18 14:51 demo4.log
-rw-r--r-- 1 root root 41943040 12月 18 14:51 demo5.log
测试分布式条卷是否正常
[root@localhost dis_stripe]# ll #在客户机上测试正常 没有数据
总用量 0
测试分布式复制卷是否正常
[root@localhost dis_and_rep]# ll
总用量 204800
-rw-r--r-- 1 root root 41943040 12月 18 14:52 demo1.log
-rw-r--r-- 1 root root 41943040 12月 18 14:52 demo2.log
-rw-r--r-- 1 root root 41943040 12月 18 14:52 demo3.log
-rw-r--r-- 1 root root 41943040 12月 18 14:52 demo4.log
-rw-r--r-- 1 root root 41943040 12月 18 14:52 demo5.log
测试成功
本次实验步骤不复杂,一些相同的操作可以使用shell脚本来编写执行,需要注意的问题:
在加入GFS节点时:gluster peer probe node 命令,如果出现以下问题
gluster peer probe node 错误 传输端点尚未连接
可以通过检查以下三点来解决
① 确认防火墙是否关闭
② 检查hosts映射是否添加,添加有无错误
③ 网络是否正常