1.MFS简单介绍与搭建

原理部分:

分布式文件系统(Distributed File Systemm)是指文件系统管理的物理存储资源不一定直接连接在本地节点上,而是通过计算机网络与节点相连。简单来说,就是把一些分散的(分布在局域网内各个计算机上)共享文件夹,集合到一个文件夹内(虚拟共享文件夹)。对于用户来说,要访问这些共享文件夹时,只要打开这个虚拟共享文件夹,就可以看到所有链接到虚拟共享文件夹内的共享文件夹,用户感觉不到这些共享文件是分散在各个计算机上的。分布式文件系统的好处是集中访问、简化操作、数据容灾,以及提高文件的存取性能。

MFS原理:

MFS是一个具有容错性的网络分布式文件系统,它把数据分散存放在多个物理服务器上,而呈现给用户的则是一个统一的资源。

MFS文件系统的组成:

#元数据服务器(Master):在整个体系中负责管理文件系统,维护元数据。

#元数据日志服务器(MetaLogger):备份Master服务器的变化日志文件,文件类型为changelog_ml.*.mfs。当Master服务器数据丢失或者损坏时,可以从日志服务器中取得文件,进行修复。

#数据存储服务器(Chunk Server):真正存储数据的服务器。存储文件时,会把文件分块保存,在数据服务器之间进行复制。数据服务器越多,能使用的“容量”就越大,可靠性就越高,性能也就越好。

#客户端(Client):可以像挂载NFS一样挂载MFS文件系统,其操作是相同的。

MFS读取数据的处理过程:

#客户端向元数据服务器发出读请求

#元数据服务器把所需数据存放的位置(Chunk Server的IP地址和Chunk编号)告知客户端

#客户端向已知的Chunk Server请求发送数据

#Chunk Server向客户端发送数据

MFS写入数据的处理过程:

#客户端向元数据服务器发送写入请求

#元数据服务器与Chunk Server进行交互(只有当所需的分块Chunks存在的时候才进行交互),但元数据服务器只在某些服务器创建新的分块Chunks,创建成功后由Chunk Server告知元数据服务器操作成功。

#元数据服务器告知客户端,可以在哪个Chunk Server的哪些Chunks写入数据。

#客户端向指定的Chunk Server写入数据

#该Chunk Server与其他Chunk Server进行数据同步,同步成功后Chunk Server告知客户端数据写入成功

#客户端告知元数据服务器本次写入完毕

1.MFS特性

Free(GPL)

通用文件系统,不需要修改上层应用就可以使用

可以在线扩容,体系架构可伸缩性极强。

部署简单。

高可用,可设置任意的文件冗余程度

可回收在指定时间内删除的文件

提供netapp,emc,ibm等商业存储的snapshot特性

google filesystem的一个c实现。

提供web gui监控接口。

提高随机读或写的效率

提高海量小文件的读写效率

2.工作原理和设计架构

角色

角色作用

管理服务器

managing server (master)

负责各个数据存储服务器的管理,文件读写调

度,文件空间回收以及恢复.多节点拷贝

元数据日志服务器

Metalogger server(Metalogger)

负责备份master 服务器的变化日志文件,文

件类型为changelog_ml.*.mfs 以便于在

master server 出问题的时候接替其行工作

数据存储服务器

data servers (chunkservers)

负责连接管理服务器,听从管理服务器调度,

提供存储空间,并为客户提供数据传输.

chunk(单词含义:复数,意思为多个)

客户机挂载使用

client computers

通过fuse 内核接口挂接远程管理服务器上所

管理的数据存储服务器,.看起来共享的文件

系统和本地unix 文件系统使用一样的效果.

官方的网络示意图:

读示意图:

MFS的读数据过程:

client当需要一个数据时,首先向master server发起查询请求;

管理服务器检索自己的数据,获取到数据所在的可用数据服务器位置ip|port|chunkid;

管理服务器将数据服务器的地址发送给客户端;

客户端向具体的数据服务器发起数据获取请求;

数据服务器将数据发送给客户端;

写示意图:

MFS的写数据过程:

当客户端有数据写需求时,首先向管理服务器提供文件元数据信息请求存储地址(元数据信息如:文件名|大小|份数等);

管理服务器根据写文件的元数据信息,到数据服务器创建新的数据块;

数据服务器返回创建成功的消息;

管理服务器将数据服务器的地址返回给客户端(chunkIP|port|chunkid);

客户端向数据服务器写数据;

数据服务器返回给客户端写成功的消息;

客户端将此次写完成结束信号和一些信息发送到管理服务器来更新文件的长度和最后修改时间

MFS的删除文件过程:

客户端有删除操作时,首先向Master发送删除信息;

Master定位到相应元数据信息进行删除,并将chunk server上块的删除操作加入队列异步清理;

响应客户端删除成功的信号

MFS修改文件内容的过程:

客户端有修改文件内容时,首先向Master发送操作信息;

Master申请新的块给.swp文件,

客户端关闭文件后,会向Master发送关闭信息;

Master会检测内容是否有更新,若有,则申请新的块存放更改后的文件,删除原有块和.swp文件块;

若无,则直接删除.swp文件块。

MFS重命名文件的过程:

客户端重命名文件时,会向Master发送操作信息;

Master直接修改元数据信息中的文件名;返回重命名完成信息;

MFS遍历文件的过程:

遍历文件不需要访问chunk server,当有客户端遍历请求时,向Master发送操作信息;

Master返回相应元数据信息;

客户端接收到信息后显示

注:

Master记录着管理信息,比如:文件路径|大小|存储的位置(ip,port,chunkid)|份数|时间等,元数据信息存在于内存中,会定期写入metadata.mfs.back文件中,定期同步到metalogger,操作实时写入changelog.*.mfs,实时同步到metalogger中。master启动将metadata.mfs载入内存,重命名为metadata.mfs.back文件。

文件以chunk大小存储,每chunk最大为64M,小于64M的,该chunk的大小即为该文件大小(验证实际chunk文件略大于实际文件),超过64M的文件将被切分,以每一份(chunk)的大小不超过64M为原则;块的生成遵循规则:目录循环写入(00-FF 256个目录循环,step为2)、chunk文件递增生成、大文件切分目录连续。

Chunkserver上的剩余存储空间要大于1GB(Reference Guide有提到),新的数据才会被允许写入,否则,你会看到No space left on device的提示,实际中,测试发现当磁盘使用率达到95%左右的时候,就已经不行写入了,当时可用空间为1.9GB。

文件可以有多份copy,当goal为1时,文件会被随机存到一台chunkserver上,当goal的数大于1时,copy会由master调度保存到不同的chunkserver上,goal的大小不要超过chunkserver的数量,否则多出的copy,不会有chunkserver去存。

元数据的概念 :

要理解这个问题,首先要知道“元”是什么。元(meta),一般被我们翻译成“关于……的……”。事实上,这个前缀来源于希腊文,表示“在……之后”,在某样事情结束之后,就含有了“归纳”、“总结”的意思呢?因此,元,就代表着“本原”、“体系”的意思。以文学领域为例,后现代主义文学中有一种小说叫作“元小说”,也就是“关于小说的小说”。“传统小说往往关心的是人物、事件,是作品所叙述的内容;而元小说则更关心作者本人是怎样写这部小说的,小说中往往喜欢声明作者是在虚构作品,喜欢告诉读者作者是在用什么手法虚构作品,更喜欢交代作者创作小说的一切相关过程”。比如英国作家伊恩·麦克尤恩的作品《赎罪》。这本书讲述的是妹妹布里奥妮幼时因为爱上了姐姐塞西莉娅的男友罗比却被他拒绝,因报复心理作祟而陷害他入狱,长大成人之后为了弥补心中的愧疚而应征入伍来赎罪的故事。在本书中,主人公布里奥妮即是“主人公”,也是本书的“作者”。它着重于描述布里奥妮是如何写这本的书的。这就是“关心作者是怎么写这本小说”的小说。在了解了元(meta)的含义之后,我们来看元数据。元数据(meta data)——“data about data” 关于数据的数据,一般是结构化数据(如存储在数据库里的数据,规定了字段的长度、类型等)。元数据是指从信息资源中抽取出来的用于说明其特征、内容的结构化的数据(如题名,版本、出版数据、相关说明,包括检索点等),用于组织、描述、检索、保存、管理信息和知识资源。比如,关于一本书(信息资源),我们在图书馆系统中检索可以得到如下信息一个基本的元数据由元数据项目和元数据内容的构成。这里,“题名”就是它的元数据项目,“史蒂夫·乔布斯传 (美) 沃尔特·艾萨克森著 = Steve Jobs Walter Isaacson eng”就是元数据内容。再比如,“著者”、“出版者”都是元数据项目,而“艾萨克森 (Isaacson, Walter) 著”和“中信出版社”就是元数据内容。学过数据库的应该不难理解~利用元数据来描述资源后,我们就可以用来做很多的事情。比如确定资源,为资源提供检索点,在不同系统之间进行数据交换。可是,我们每个人都可以对资源进行描述,取的名字(元数据项目)和值的样子(元数据内容)会千奇百怪怎么办呢?因此,就有了元数据标准。元数据标准包括元数据结构标准(即元数据包含那些项目,都柏林核心集,MARC元素集)、元数据内容标准、元数据取值标准、元数据编码标准(用于机读记录的存储和交换,比如MARC(Machine Readable Cataloging), XML)在这里我们详细看一下MARC格式(一种元数据标准)。在传统的图书馆中,我们购买了很多的书。图书馆员们怎么能知道自己有什么书了呢?我们就需要把每本图书的信息,写在一张小卡片上(有些老图书馆还有),存放在自己的图书馆里。但是随着计算机的发展,我们认为把书目的信息存到电脑里是更好的方法。又随着网络的发展,我们觉得应该来一个图书馆大联合,把所有的图书信息都一起存起来。但是每个图书馆都有自己的一套记录方法。因此,MARC格式就应运而生了。MARC就是在计算机出现后为系统间交换书目数据和相关信息而设计的。当然啦,在传统图书馆的手工编目时期,使用的术语与现在的计算机编目不同。比如那时候我们把一本书的“元数据”写在一张张卡片上,称之为“款目(entry)”,而在计算机里,关于一本书的记录,就叫做“记录(record)”。在机读编目中,我们把要著录的项目(著录项目area)叫作“字段(field),还有等等的区别。说了这么多,MARC格式是什么样的呢?可以看一下中国使用的CN-MARC格式。(CNMARC是我国参照UNIMARC(国际图联制定UNIMARC规范各国的MARC格式)编写的中国MARC格式。)它规定了关于文献资源应该如何记录。比如说在数据字段区,它对于101字段是这么规定的:101 0 $a正文语种$b中间语种$c原作语种那么我们就要编目成:101 1 $achi $ceng (chi是中文,eng是英文)再比如它规定210字段的编目形式如下:210 $a出版、发行地$c出版、发行者名称$d出版、发行日期根据这个要求我们就要写成210 $a北京 $c机械工业出版社 $d2003接下来,互联网发展的越来越快,元数据的格式越来越多,人们对它的互操作要求也越来越高,就出现了XML!在利用XML描述一个文档的时候,我们可以自己定义标签,如”

操作部分:

系统环境:

一台MFS Master:192.168.1.10

两台MFS 节点服务器:192.168.1.12 192.168.1.16

一台客户端:192.168.1.20

一、搭建Master Server

下载编译环境

所有主机:

yum install gcc gcc-c++ zlib-devel -y

关闭防火墙

所有主机:

systemctl stop firewalld.service

setenforce 0

建立管理用户

useradd -s /sbin/nologin mfs

解压源码包

cd /usr/src/

tar zxvf mfs-1.6.27-5.tar.gz

主机的./configure配置参数不一样,需要注意:

对本台服务器进行配置,因为在进行源码包编译时,它是默认安装了所有模块的,而这台是Master所以需要禁用chunkserver和mount两个模块

cd /opt/mfs-1.6.27/

./configure \

--prefix=/usr/local/mfs \

--with-default-user=mfs \

--with-default-group=mfs \

--disable-mfschunkserver \

--disable-mfsmount

编译安装

make && make install

复制文件

cd /usr/local/mfs/etc/mfs/

cp mfsexports.cfg.dist mfsexports.cfg

cp mfsmaster.cfg.dist mfsmaster.cfg

cp mfsmetalogger.cfg.dist mfsmetalogger.cfg

cd /usr/local/mfs/var/mfs/

cp metadata.mfs.empty metadata.mfs

将该文件的属组和属主改为mfs

chown -R mfs.mfs /usr/local/mfs

本台服务器需要用到的配置文件有两个:mfsmaster.cfg(主配置文件)和mfsexports.cfg(被挂载目录及权限配置文件)。这两个文件不需要做任何修改就可以开始工作

注释:

mfsmaster.cfg文件常用参数如下:

#WORKING_USER = mfs #运行masterserver的用户

#WORKING_GROUP = mfs #运行masterserver的组

#SYSLOG_IDENT = mfsmaster #在syslog中表示是mfsmaster产生的日志

#LOCK_MEMORY = 0 #是否执行mlockall(),以避免mfsmaster进程溢出(默认为0)

#NICE_LEVEL = -19 #运行的优先级(如果可以,默认是-19;注意:进程必须用root启动)

#EXPORTS_FILENAME = /usr/local/mfs/etc/mfs/mfsexports.cfg #被挂载目录及其权限控制文件的存放位置

#TOPOLOGY_FILENAME = /usr/local/mfs/etc/mfs/mfstopology.cfg

#DATA_PATH = /usr/local/mfs/var/mfs #数据存放路径

#BACK_LOGS = 50 #metadata改变的log文件数目(默认是50)

#BACK_META_KEEP_PREVIOUS = 1

#REPLICATIONS_DELAY_INIT = 300

#REPLICATIONS_DELAY_DISCONNECT = 3600

#MATOML_LISTEN_HOST = #metalogger监听的IP地址(默认是,代表任何IP)

#MATOML_LISTEN_PORT = 9419 #metalogger监听的端口地址(默认是9419)

#MATOML_LOG_PRESERVE_SECONDS = 600

#MATOCS_LISTEN_HOST = #用于chunkserver连接的IP地址(默认是,代表任何IP)

#MATOCS_LISTEN_PORT = 9420 #用于chunkserver连接的端口地址(默认是9420)

#MATOCL_LISTEN_HOST = #用于客户端挂接连接的IP地址(默认是,代表任何IP)

#MATOCL_LISTEN_PORT = 9421 #用于客户端挂接连接的端口地址(默认是4921)

#CHUNKS_LOOP_MAX_CPS = 100000

#CHUNKS_LOOP_MIN_TIME = 300 #chunk的回环频率(默认是300秒)

#CHUNKS_SOFT_DEL_LIMIT = 10

#CHUNKS_HARD_DEL_LIMIT = 25

#CHUNKS_WRITE_REP_LIMIT = 2 #在一个循环里复制到一个chunkserver的最大chunk数

#CHUNKS_READ_REP_LIMIT = 10 #在一个循环里从一个chunkserver复制的最大chunk数

#ACCEPTABLE_DIFFERENCE = 0.1

#SESSION_SUSTAIN_TIME = 86400

#REJECT_OLD_CLIENTS = 0

#deprecated:

#CHUNKS_DEL_LIMIT - use CHUNKS_SOFT_DEL_LIMIT instead

#LOCK_FILE - lock system has been changed, and this option is used only to search for old lockfile

mfsexports.cfg文件参数格式如下:

#Allow everything but "meta".

/ rw,alldirs,maproot=0

#Allow "meta".

. rw

该文件每一个条目分为三部分

第一部分:客户端的IP地址

第二部分:被挂接的目录

第三部分:客户端拥有的权限

地址可以指定的几种表现形式:

#*——所有的IP地址

#n.n.n.n——单个IP地址

#n.n.n.n/b——IP网络地址/子网掩码

#f.f.f.f-t.t.t.t——IP段

目录部分的标识如下:

#/标识MFS根

#.表示MFSMETA文件系统

权限部分的标识如下

#ro——只读模式共享

#rw——读写的方式共享

#alldirs——允许挂载任何指定的子目录

#admin——管理员权限

#maproot——映射为root,还是指定的用户

#Password——指定客户端密码

启动Master Server

/usr/local/mfs/sbin/mfsmaster start

查看进程,如果有MFS的进程表示服务成功开启

ps -ef | grep mfs

这是关闭Master Server命令

/usr/local/mfs/sbin/mfsmaster -s

二、搭建Metalogger Server

安装编译环境

yum install gcc gcc-c++ zlib-devel -y

关闭防火墙

systemctl stop firewalld.service

setenforce 0

创建管理用户

useradd -s /sbin/nologin mfs

解压安装包

tar zxvf mfs-1.6.27-5.tar.gz

配置模块,因为本台服务器是Log服务器,所以需要禁用掉mfschunkserver和mfsmount两个模块

cd /opt/mfs-1.6.27/

./configure \

--prefix=/usr/local/mfs \

--with-default-user=mfs \

--with-default-group=mfs \

--disable-mfschunkserver \

--disable-mfsmount

编译安装

make && make install

复制文件,本台服务器只需要开启日志文件即可

cd /usr/local/mfs/etc/mfs/

cp mfsmetalogger.cfg.dist mfsmetalogger.cfg

在文件中将地址指向Master Server的地址

vim mfsmetalogger.cfg

MASTER_HOST = 192.168.1.10

将文件的属组和属主都改为mfs

chown -R mfs.mfs /usr/local/mfs/

开启MetaLog Server服务

/usr/local/mfs/sbin/mfsmetalogger start

查看进程,如果有MFS进程表示服务成功开启

ps -ef | grep mfs

关闭服务用如下命令

/usr/local/mfs/sbin/mfsmetalogger -s

三、搭建两台Chunk Server(一),两台的操作步骤完全一样

安装编译环境

yum install gcc gcc-c++ zlib-devel -y

创建管理用户

useradd -s /sbin/nologin mfs

关闭防火墙

systemctl stop firewalld.service

setenforce 0

解压安装包

tar zxvf mfs-1.6.27-5.tar.gz

配置模块,本台服务器是Chunk Server,所以需要禁用掉mfsmaster和mfsmount两个模块

cd /opt/mfs-1.6.27/

./configure \

--prefix=/usr/local/mfs \

--with-default-user=mfs \

--with-default-group=mfs \

--disable-mfsmaster \

--disable-mfsmount

编译安装

make && make install

开启mfschunkserver和mfshdd两个文件

cd /usr/local/mfs/etc/mfs/

cp mfschunkserver.cfg.dist mfschunkserver.cfg

cp mfshdd.cfg.dist mfshdd.cfg

在chunk文件下将地址指向 Master Server

vim mfschunkserver.cfg

MASTER_HOST = 192.168.1.10

在mfshdd文件下添加一行/data,在这里/data是一个给MFS的分区,生存环境最好使用独立的分区或磁盘挂载到此目录

vim mfshdd.cfg

#mount points of HDD drives

#/mnt/hd1

#/mnt/hd2

#etc.

/data

创建挂载目录

mkdir /data

chown -R mfs.mfs /data

开启服务

/usr/local/mfs/sbin/mfschunkserver start

想要关闭可以使用如下命令

/usr/local/mfs/sbin/mfschunkserver -s

查看进程,可以检测服务是否开启

ps -ef | grep mfs

四、搭建两台Chunk Server(二),两台的操作步骤完全一样

安装编译环境

yum install gcc gcc-c++ zlib-devel -y

创建管理用户

useradd -s /sbin/nologin mfs

关闭防火墙

systemctl stop firewalld.service

setenforce 0

解压安装包

tar zxvf mfs-1.6.27-5.tar.gz

配置模块,本台服务器是Chunk Server,所以需要禁用掉mfsmaster和mfsmount两个模块

cd /opt/mfs-1.6.27/

./configure \

--prefix=/usr/local/mfs \

--with-default-user=mfs \

--with-default-group=mfs \

--disable-mfsmaster \

--disable-mfsmount

编译安装

make && make install

开启mfschunkserver和mfshdd两个文件

cd /usr/local/mfs/etc/mfs/

cp mfschunkserver.cfg.dist mfschunkserver.cfg

cp mfshdd.cfg.dist mfshdd.cfg

在chunk文件下将地址指向 Master Server

vim mfschunkserver.cfg

MASTER_HOST = 192.168.1.10

在mfshdd文件下添加一行/data,在这里/data是一个给MFS的分区,生存环境最好使用独立的分区或磁盘挂载到此目录

vim mfshdd.cfg

#mount points of HDD drives

#/mnt/hd1

#/mnt/hd2

#etc.

/data

创建挂载目录

mkdir /data

chown -R mfs.mfs /data

开启服务

/usr/local/mfs/sbin/mfschunkserver start

想要关闭可以使用如下命令

/usr/local/mfs/sbin/mfschunkserver -s

查看进程,可以检测服务是否开启

ps -ef | grep mfs

五、客户端配置

安装编译环境,MFS客户端依赖于FUSE,所以需要安装fuse的安装包和开发包

yum install gcc gcc-c++ zlib-devel fuse fuse-devel -y

关闭防火墙

systemctl stop firewalld.service

setenforce 0

添加环境变量PKG_CONFIG_PATH,环境变量PKG_CONFIG_PATH是用来设置.pc文件的搜索路径的,pkg-config按照设置路径的先后顺序进行搜索,直到找到指定的.pc 文件为止

vim /etc/profile

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH

source /etc/profile

优化客户端

MFS在客户端安装完毕后,会生成/usr/local/mfs/bin目录,在这个目录下有很多命令文件,为了方便使用这些命令,可以将该路径添加到环境变量中

vim /etc/profile

export PATH=/usr/local/mfs/bin:$PATH

source /etc/profile

解压安装包:

tar zxvf fuse-2.9.2.tar.gz

cd fuse-2.9.2

./configure

make && make install

创建进程管理用户

useradd -s /sbin/nologin mfs

解压安装包

tar zxvf mfs-1.6.27-5.tar.gz -C /opt

配置模块,本台服务器是Client,所以需要禁用掉mfsmaster和mfschunkserver两个模块,同时开启mfsmount模块

cd /opt/mfs-1.6.27/

./configure \

--prefix=/usr/local/mfs \

--with-default-user=mfs \

--with-default-group=mfs \

--disable-mfsmaster \

--disable-mfschunkserver \

--enable-mfsmount

编译安装

make && make install

创建挂载点

mkdir /mnt/mfs

加载fuse模块到内核

modprobe fuse

挂载MFS

/usr/local/mfs/bin/mfsmount /opt/mfs -H 192.168.1.10

查看挂载情况

df -hT

192.168.1.10:9421 fuse.mfs 13G 0 13G 0% /opt/mfs

Mfsgetgoal命令用来查询文件被复制的份数,利用-r命令可以对整个目录进行递归,goal是指文件被复制的份数

mfsgetgoal -r /mnt/mfs

/opt/mfs:

directories with goal 1 : 1

Mfsaetgoal命令用来设置文件被复制的份数,生产环境Chunk Server节点数量应至少大于2,文件副本数小于等于Chunk Server服务器的数量

mfssetgoal -r 2 /mnt/mfs

/opt/mfs:

inodes with goal changed: 1

inodes with goal not changed: 0

inodes with permission denied: 0

创建测试文件

cd /opt/mfs

touch test

mfsgetgoal test

test: 2

MFS监听

1:在master server上启动监听服务

/usr/local/mfs/sbin/mfscgiserv

2:客户端

http://192.168.1.10:9425

MFS的维护与灾难恢复

1:MFS群集的启动顺序

启动mfsmaster

启动所有的mfschunkserver

启动mfsmetalogger

在所有的客户端挂在MFS文件系统

2:停止集群的顺序

在所有的客户端卸载MFS文件系统

用mfschunkserver –s命令停止chunkserver进程

用mfsmetalogger –s命令停止metalogger进程

用mfsmaster –s命令停止master进程

3:MFS灾难恢复

  1. 如果突然断电造成master进程无法启动可用如下命令修复

/usr/local/mfs/sbin/mfsmetarestore -a

  1. master发生故障时,从metalogger中恢复

  • 安装一台新的mfsmaster服务器

  • 将metalogger上的/usr/loal/mfs/var/mfs/目录中的所有文件复制到新的mfsmaster服务器的同样的目录中。

  • 在新的master服务器中合并元数据changlogs

/usr/local/mfs/sbin/mfsmetarestore -m metadata_ml.mfs.back -o metadata.mfs changelog_ml.*.mfs修改metalogger和chunkserver中配置文件中MASTER_HOST参数的ip地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值