Hadoop+Hbase 分布式集群架构“完全篇”

1. 认识 Hadoop 和 Hbase


1.1 Hadoop 简单介绍


Hadoop 是一个使用 Java 编写的 Apache 开放源代码框架,它允许使用简单的编程模型跨大型计算机的大型数据集进行分布式处理。Hadoop 框架工作的应用程序可以在跨计算机群集提供分布式存储和计算的环境中工作。Hadoop 旨在从单一服务器扩展到数千台机器,每台机器都提供本地计算和存储。


1.2 Hadoop 架构


Hadoop 框架包括以下四个模块:


  • Hadoop Common:这些是其他 Hadoop 模块所需的 Java 库和实用程序。这些库提供文件系统和操作系统级抽象,并包含启动 Hadoop 所需的必要 Java 文件和脚本。

  • Hadoop YARN:这是作业调度和集群资源管理的框架。

  • Hadoop 分布式文件系统(HDFS):提供对应用程序数据的高吞吐量访问的分布式文件系统。

  • Hadoop MapReduce:这是基于 YARN 的大型数据集并行处理系统。


我们可以使用下图来描述 Hadoop 框架中可用的这四个组件。


640?wx_fmt=png


自 2012 年以来,术语“Hadoop”通常不仅指向上述基本模块,而且还指向可以安装在 Hadoop 之上或之外的其他软件包,例如 Apache Pig、Apache Hive、Apache HBase、Apache 火花等。

 

1.3 Hadoop 如何工作?


(1)阶段1


用户/应用程序可以通过指定以下项目向 Hadoop(Hadoop 作业客户端)提交所需的进程:


  • 分布式文件系统中输入和输出文件的位置。

  • Java类以 JAR 文件的形式包含了 Map 和 Reduce 功能的实现。

  • 通过设置作业特定的不同参数来进行作业配置。


(2)阶段2


然后,Hadoop 作业客户端将作业(JAR/可执行文件等)和配置提交给 JobTracker,JobTracker 负责将软件/配置分发到从站,调度任务和监视它们,向作业客户端提供状态和诊断信息。


(3)阶段3


不同节点上的 TaskTrackers 根据 MapReduce 实现执行任务,并将 reduce 函数的输出存储到文件系统的输出文件中。

 

1.4 Hadoop 的优点


  • Hadoop 框架允许用户快速编写和测试分布式系统。它是高效的,它自动分配数据并在机器上工作,反过来利用 CPU 核心的底层并行性。


  • Hadoop 不依赖硬件提供容错和高可用性(FTHA),而是 Hadoop 库本身被设计为检测和处理应用层的故障。


  • 服务器可以动态添加或从集群中删除,Hadoop 继续运行而不会中断。


  • Hadoop 的另一大优点是,除了是开放源码,它是所有平台兼容的,因为它是基于 Java 的。

 

1.5 HBase 介绍


Hbase 全称为 Hadoop Database,即 Hbase 是 Hadoop 的数据库,是一个分布式的存储系统。Hbase 利用 Hadoop 的 HDFS 作为其文件存储系统,利用 Hadoop 的 MapReduce 来处理 Hbase 中的海量数据。利用 ZooKeeper 作为其协调工具。 

 

1.6 HBase 体系架构


640?wx_fmt=png


Client


  • 包含访问 HBase 的接口并维护 Cache 来加快对 HBase 的访问


ZooKeeper


  • 保证任何时候,集群中只有一个 Master

  • 存贮所有 Region 的寻址入口。

  • 实时监控 Region Server 的上线和下线信息。并实时通知 Master

  • 存储 HBase 的 Schema 和 table 元数据


Master


  • 为 Region Server 分配 region

  • 负责 Region Server 的负载均衡

  • 发现失效的 Region Server 并重新分配其上的 region

  • 管理用户对 table 的增删改操作


RegionServer


  • Region Server 维护 region,处理对这些 region 的 IO 请求

  • Region Server 负责切分在运行过程中变得过大的 region 


HLog(WAL log)



  • HLog 文件就是一个普通的 Hadoop Sequence File,Sequence File  的 Key 是  HLogKey 对象,HLogKey 中记录了写入数据的归属信息,除了 table 和 region 名字外,同时还包括 Sequence Number 和 Timestamp,Timestamp 是” 写入时间”,Sequence Number 的起始值为 0,或者是最近一次存入文件系统中 Sequence Number。



  • HLog SequeceFile 的 Value 是 HBase 的 KeyValue 对象,即对应 HFile 中的  KeyValue


Region


  • HBase 自动把表水平划分成多个区域(Rregion,每个 Region 会保存一个表里面某段连续的数据;每个表一开始只有一个 Region,随着数据不断插 入表,region 不断增大,当增大到一个阀值的时候,Region 就会等分会 两个新的 Region(裂变);

  •  

  • 当 table 中的行不断增多,就会有越来越多的 Region。这样一张完整的表被保存在多个 Regionserver 上。


Memstore 与 StoreFile


  • 一个 Region 由多个 Store 组成,一个 Store 对应一个 CF(列族)


  • store 包括位于内存中的 Memstore 和位于磁盘的 StoreFile 写操作先写入 Memstore,当 MemStore 中的数据达到某个阈值,HRegionServer 会启动  FlashCache 进程写入 StoreFile,每次写入形成单独的一个 StoreFile


  • 当 StoreFile 文件的数量增长到一定阈值后,系统会进行合并(minor、 major compaction),在合并过程中会进行版本合并和删除工作 ,形成更大的  StoreFile。


  • 当一个 Region 所有 StoreFile 的大小和超过一定阈值后,会把当前的 region 分割为两个,并由 HMaster 分配到相应的 RegionServer 服务器,实现负载均衡。


  • 客户端检索数据,先在 MemStore 找,找不到再找 StoreFile。


  • HRegion 是 HBase 中分布式存储和负载均衡的最小单元。最小单元就表示不同的 HRegion 可以分布在不同的 HRegion Server上。


  • HRegion 由一个或者多个 Store 组成,每个 Store 保存一个 Columns Family。


  • 每个 Strore 又由一个 MemStore 和 0 至多个 StoreFile 组成。


2. 安装搭建 Hadoop


2.1 配置说明


本次集群搭建共三台机器,具体说明下:


主机名IP说明
hadoop01192.168.10.101DataNode、NodeManager、ResourceManager、NameNode
hadoop02192.168.10.102DataNode、NodeManager、SecondaryNameNode
hadoop03192.168.10.106DataNode、NodeManager

 

2.2 安装前准备


2.2.1 机器配置说明


640?wx_fmt=png

注:本集群内所有进程均由 CLSN 用户启动;要在集群所有服务器都进行操作。

 

2.2.2 关闭 SELinux、防火墙


640?wx_fmt=png


2.2.3 准备用户

640?wx_fmt=png

  
2.2.4 修改 Hosts 文件,域名解析


640?wx_fmt=png

  

2.2.5 同步时间


640?wx_fmt=png

  

2.2.6 SSH 互信配置


(1)生成密钥对,一直回车即可


640?wx_fmt=png


(2)保证每台服务器各自都有对方的公钥


640?wx_fmt=png

注:要在集群所有服务器都进行操作


(3)验证无秘钥认证登录


640?wx_fmt=png


2.3 配置 JDK


在三台机器上都需要操作


640?wx_fmt=png


2.4 安装 Hadoop

[root@hadoop01 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.2.0/hadoop-3.2.0.tar.gz[root@hadoop01 ~]# tar -xvf hadoop-3.2.0.tar.gz -C /usr/local/[root@hadoop01 ~]# chown along.along -R /usr/local/hadoop-3.2.0/[root@hadoop01 ~]# ln -s /usr/local/hadoop-3.2.0/  /usr/local/hadoop


3. 配置启动 Hadoop


3.1  hadoop-env.sh 配置 Hadoop 环境变量


640?wx_fmt=png


3.2 core-site.xml 配置 HDFS


640?wx_fmt=png


3.3 hdfs-site.xml 配置 NameNode


[along@hadoop01 hadoop]$ vim hdfs-site.xml<configuration>    <!-- 设置namenode的http通讯地址 -->    <property>        <name>dfs.namenode.http-address</name>        <value>hadoop01:50070</value>    </property>     <!-- 设置secondarynamenode的http通讯地址 -->    <property>        <name>dfs.namenode.secondary.http-address</name>        <value>hadoop02:50090</value>    </property>     <!-- 设置namenode存放的路径 -->    <property>        <name>dfs.namenode.name.dir</name>        <value>/data/hadoop/name</value>    </property>     <!-- 设置hdfs副本数量 -->    <property>        <name>dfs.replication</name>        <value>2</value>    </property>    <!-- 设置datanode存放的路径 -->    <property>        <name>dfs.datanode.data.dir</name>        <value>/data/hadoop/datanode</value>    </property>     <property>        <name>dfs.permissions</name>        <value>false</value>    </property></configuration>[root@hadoop01 ~]# mkdir /data/hadoop/name -p[root@hadoop01 ~]# mkdir /data/hadoop/datanode -p

 

3.4 mapred-site.xml 配置框架


640?wx_fmt=png


3.5 yarn-site.xml 配置 ResourceManager


[along@hadoop01 hadoop]$ vim yarn-site.xml<configuration>    <property>        <name>yarn.resourcemanager.hostname</name>        <value>hadoop01</value>    </property>     <property>        <description>The http address of the RM web application.</description>        <name>yarn.resourcemanager.webapp.address</name>        <value>${yarn.resourcemanager.hostname}:8088</value>    </property>     <property>        <description>The address of the applications manager interface in the RM.</description>        <name>yarn.resourcemanager.address</name>        <value>${yarn.resourcemanager.hostname}:8032</value>    </property>     <property>        <description>The address of the scheduler interface.</description>        <name>yarn.resourcemanager.scheduler.address</name>        <value>${yarn.resourcemanager.hostname}:8030</value>    </property>     <property>        <name>yarn.resourcemanager.resource-tracker.address</name>        <value>${yarn.resourcemanager.hostname}:8031</value>    </property>     <property>        <description>The address of the RM admin interface.</description>        <name>yarn.resourcemanager.admin.address</name>        <value>${yarn.resourcemanager.hostname}:8033</value>    </property></configuration>


3.6 配置 Masters & Slaves


640?wx_fmt=png


3.7 启动前准备


3.7.1 准备启动脚本


启动脚本文件全部位于 /usr/local/hadoop/sbin 文件夹下:


(1)修改 start-dfs.sh stop-dfs.sh 文件添加:


640?wx_fmt=png


(2)修改 start-yarn.sh 和 stop-yarn.sh 文件添加:


640?wx_fmt=png


3.7.2 授权

640?wx_fmt=png


3.7.3 配置 Hadoop 命令环境变量


640?wx_fmt=png

  

3.7.4 集群初始化


640?wx_fmt=png

  

3.8 启动 Hadoop 集群


3.8.1 第一次启动前需要格式化,集群所有服务器都需要

640?wx_fmt=png

  
3.8.2 启动并验证集群


(1)启动 NameNode、DataNode


640?wx_fmt=png


(2)启动 YARN


640?wx_fmt=png


3.9 集群启动成功


(1)网页访问:http://hadoop01:8088


该页面为 ResourceManager 管理界面,在上面可以看到集群中的三台 Active Nodes。


640?wx_fmt=png


(2)网页访问:http://hadoop01:50070/dfshealth.html#tab-datanode


该页面为 NameNode 管理页面


640?wx_fmt=png


到此 Hadoop 集群已经搭建完毕!


4. 安装配置 Hbase


4.1 安装 Hbase


[root@hadoop01 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/1.4.9/hbase-1.4.9-bin.tar.gz[root@hadoop01 ~]# tar -xvf hbase-1.4.9-bin.tar.gz -C /usr/local/[root@hadoop01 ~]# chown -R along.along /usr/local/hbase-1.4.9/[root@hadoop01 ~]# ln -s /usr/local/hbase-1.4.9/ /usr/local/hbase

注:当前时间 2018.03.08,Hbase-2.1 版本有问题;也可能是我配置的问题,Hbase 会启动失败;所以,我降级到了 Hbase-1.4.9 版本。

 

4.2 配置 Hbase


4.2.1 hbase-env.sh 配置 Hbase 环境变量


640?wx_fmt=png

  

4.2.2 hbase-site.xml 配置 Hbase


[root@hadoop01 conf]# vim hbase-site.xml<configuration><property>    <name>hbase.rootdir</name>    <!-- hbase存放数据目录 -->    <value>hdfs://hadoop01:9000/hbase/hbase_db</value>    <!-- 端口要和Hadoop的fs.defaultFS端口一致--></property><property>    <name>hbase.cluster.distributed</name>    <!-- 是否分布式部署 -->    <value>true</value></property><property>    <name>hbase.zookeeper.quorum</name>    <!-- zookooper 服务启动的节点,只能为奇数个 -->    <value>hadoop01,hadoop02,hadoop03</value></property><property>    <!--zookooper配置、日志等的存储位置,必须为以存在 -->    <name>hbase.zookeeper.property.dataDir</name>    <value>/data/hbase/zookeeper</value></property><property>    <!--hbase master -->    <name>hbase.master</name>    <value>hadoop01</value></property><property>    <!--hbase web 端口 -->    <name>hbase.master.info.port</name>    <value>16666</value></property></configuration>

 注:ZooKeeper 有这样一个特性:


  • 集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的。

  • 也就是说如果有 2 个 ZooKeeper,那么只要有 1 个死了 ZooKeeper 就不能用了,因为 1 没有过半,所以 2 个ZooKeeper 的死亡容忍度为 0;

  • 同理,要是有 3 个 ZooKeeper,一个死了,还剩下 2 个正常的,过半了,所以 3 个 ZooKeeper 的容忍度为 1;

  • 再多列举几个:2->0 ; 3->1 ; 4->1 ; 5->2 ; 6->2 会发现一个规律,2n 和 2n-1 的容忍度是一样的,都是 n-1,所以为了更加高效,何必增加那一个不必要的 ZooKeeper。

 

4.2.3 指定集群节点


640?wx_fmt=png


5. 启动 Hbase 集群


5.1 配置 Hbase 命令环境变量


640?wx_fmt=png


5.2 启动前准备


640?wx_fmt=png


5.3 启动 Hbase


注:只需在 Hadoop01 服务器上操作即可。


(1)启动


640?wx_fmt=png


(2)验证


640?wx_fmt=png


5.4 页面查看 Hbase 状态


网页访问 http://hadoop01:16666


640?wx_fmt=png


6. 简单操作 Hbase


6.1 Hbase Shell 基本操作命令


名称

命令表达式

创建表

create '表名称','列簇名称1','列簇名称2'.......

添加记录

put '表名称', '行名称','列簇名称:','值'

查看记录

get '表名称','行名称'

查看表中的记录总数

count '表名称'

删除记录

delete '表名',行名称','列簇名称'

删除表

①disable '表名称' ②drop '表名称'

查看所有记录

scan '表名称'

查看某个表某个列中所有数据

scan '表名称',['列簇名称:']

更新记录

即重写一遍进行覆盖

 

6.2 一般操作


(1)启动 Hbase 客户端


[along@hadoop01 ~]$ hbase shell    #需要等待一些时间SLF4J: Class path contains multiple SLF4J bindings.SLF4J: Found binding in [jar:file:/usr/local/hbase-1.4.9/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]SLF4J: Found binding in [jar:file:/usr/local/hadoop-3.2.0/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]HBase ShellUse "help" to get list of supported commands.Use "exit" to quit this interactive shell.Version 1.4.9, rd625b212e46d01cb17db9ac2e9e927fdb201afa1, Wed Dec  5 11:54:10 PST 2018 hbase(main):001:0>


(2)查询集群状态


640?wx_fmt=png


(3)查询 Hive 版本


640?wx_fmt=png


6.3 DDL 操作


(1)创建一个 demo 表,包含  ID 和 info 两个列簇


640?wx_fmt=png


(2)获得表的描述


hbase(main):002:0> listTABLE                                                                                            demo                                                                                             1 row(s) in 0.6380 seconds => ["demo"]---获取详细描述hbase(main):003:0> describe 'demo'Table demo is ENABLED                                                                            demo                                                                                             COLUMN FAMILIES DESCRIPTION                                                                      {NAME => 'id', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS =>'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                        {NAME => 'info', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                      2 row(s) in 0.3500 seconds


(3)删除一个列簇


注:任何删除操作,都需要先 disable 表


hbase(main):004:0> disable 'demo'0 row(s) in 2.5930 seconds hbase(main):006:0> alter 'demo',{NAME=>'info',METHOD=>'delete'}Updating all regions with the new schema...1/1 regions updated.Done.0 row(s) in 4.3410 seconds hbase(main):007:0> describe 'demo'Table demo is DISABLED                                                                             demo                                                                                               COLUMN FAMILIES DESCRIPTION                                                                        {NAME => 'id', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0',BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                              1 row(s) in 0.1510 seconds


(4)删除一个表


要先 disable 表,再 drop


640?wx_fmt=png


6.4 DML 操作


(1)插入数据


hbase(main):024:0> create 'demo','id','info'0 row(s) in 10.0720 seconds => Hbase::Table - demohbase(main):025:0> is_enabled 'demo'true                                                                                               0 row(s) in 0.1930 seconds hbase(main):030:0> put 'demo','example','id:name','along'0 row(s) in 0.0180 seconds hbase(main):039:0> put 'demo','example','id:sex','male'0 row(s) in 0.0860 seconds hbase(main):040:0> put 'demo','example','id:age','24'0 row(s) in 0.0120 seconds hbase(main):041:0> put 'demo','example','id:company','taobao'0 row(s) in 0.3840 seconds hbase(main):042:0> put 'demo','taobao','info:addres','china'0 row(s) in 0.1910 seconds hbase(main):043:0> put 'demo','taobao','info:company','alibaba'0 row(s) in 0.0300 seconds hbase(main):044:0> put 'demo','taobao','info:boss','mayun'0 row(s) in 0.1260 seconds


(2)获取 demo 表的数据


hbase(main):045:0> get 'demo','example'COLUMN                     CELL                                                                     id:age                    timestamp=1552030411620, value=24                                        id:company                timestamp=1552030467196, value=taobao                                    id:name                   timestamp=1552030380723, value=along                                     id:sex                    timestamp=1552030392249, value=male                                     1 row(s) in 0.8850 seconds hbase(main):046:0> get 'demo','taobao'COLUMN                     CELL                                                                     info:addres               timestamp=1552030496973, value=china                                     info:boss                 timestamp=1552030532254, value=mayun                                     info:company              timestamp=1552030520028, value=alibaba                                  1 row(s) in 0.2500 seconds hbase(main):047:0> get 'demo','example','id'COLUMN                     CELL                                                                     id:age                    timestamp=1552030411620, value=24                                        id:company                timestamp=1552030467196, value=taobao                                    id:name                   timestamp=1552030380723, value=along                                     id:sex                    timestamp=1552030392249, value=male                                     1 row(s) in 0.3150 seconds hbase(main):048:0> get 'demo','example','info'COLUMN                     CELL                                                                    0 row(s) in 0.0200 seconds hbase(main):049:0> get 'demo','taobao','id'COLUMN                     CELL                                                                    0 row(s) in 0.0410 seconds hbase(main):053:0> get 'demo','taobao','info'COLUMN                     CELL                                                                     info:addres               timestamp=1552030496973, value=china                                     info:boss                 timestamp=1552030532254, value=mayun                                     info:company              timestamp=1552030520028, value=alibaba                                  1 row(s) in 0.0240 seconds hbase(main):055:0> get 'demo','taobao','info:boss'COLUMN                     CELL                                                                     info:boss                 timestamp=1552030532254, value=mayun                                    1 row(s) in 0.1810 seconds


(3)更新一条记录


640?wx_fmt=png


(4)获取时间戳数据


大家应该看到 Timestamp 这个标记


640?wx_fmt=png


(5)全表显示


640?wx_fmt=png


(6)删除 ID 为 example 的 'id:age' 字段


640?wx_fmt=png


(7)删除整行


640?wx_fmt=png


(8)给 example 这个 id 增加 'id:age' 字段,并使用 counter 实现递增


640?wx_fmt=png


(9)清空整个表


640?wx_fmt=png


可以看出 Hbase 是先 disable 掉该表,然后 drop,最后重新 create 该表来实现清空该表。

来源:http://www.cnblogs.com/along21/p/10496468.html

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。


-END-640?wx_fmt=jpeg


架构文摘

ID:ArchDigest

互联网应用架构丨架构技术丨大型网站丨大数据丨机器学习

640?wx_fmt=jpeg

更多精彩文章,请点击下方:阅读原文

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值