强力收藏!一文说全HiveConf类(Hive3.1.2版本)

强力收藏!一文说全HiveConf类(Hive3.1.2版本)

作者:Eeeddieee

​ 工作中大部分时间都用到了Hive,虽然对Hive的架构、运行原理、调优方式有一定了解,但是很多都是在前人总结的基础上进行学习,没有自己的一套思考。比如往上很多资料都有说到Hive谓词下推,Hive引擎可以自动根据SQL语句进行优化,然后把各种谓词下推的SQL语句情况都列举出来,实际应用时只需要按照资料进行开发即可。随着对Hive使用时间的加长,对于这种被动的接收前人分析结论、经验的方式已经不能满足个人的求知欲了,再加上最近想写一个自动生成Hive SQL脚本的程序,了解了下Hive解析SQL的源码,感觉Hive源码里面也有很多东西可以去深挖的,所以就想系统的去研究下Hive源码。

​ 因为在写Hive SQL脚本时,经常会配置一些参数,这些参数大部分都是前人总结出来的,我想能够系统、全面的了解下Hive的配置参数,所以就先从HiveConf类开始研究。本文内容可以收藏作为工具,往后有需要查看HiveConf类、Hive常用配置项时,直接翻阅查找即可。

内容大纲

​ 主要有6个方面去说明HiveConf类的内容:
11

1 HiveConf类的继承关系

​ HiveConf类继承自Hadoop的Configuration类,具有该类的特性,从这个角度也能看到Hive跟Hadoop的联系是比较密切的,Hive也可以很容易的获取到Hadoop的一些配置。

11

2 HiveConf类的属性

​ HiveConf类有39个属性,主要分为以下4类:

11

  1. ConfVars相关属性:ConfVars是Hive配置项的对象,比如hive.exec.dynamic.partition这个参数就是一个Hive配置项;
  2. Properties相关属性:Properties类是java的配置项类,所有Hive参数都可以看作是Properties,Properties相关属性可以说是Hive参数的java形式,实际还是使用ConfVars作为Hive的配置对象;
  3. 环境相关属性:主要是一些System参数,比如HADOOP_HOME、Hive配置文件地址、Hive的Jar包路径等;
  4. 描述类属性:Hive配置项的别名或者集合,可以通过别名快速找到相关配置项。

2.1 ConfVars相关属性

  • 包含全部配置项的属性
序号属性名类型含义
1confVarByteArraybyte[]ConfVar的字符数组,一个ConfVar就是一个配置项
2varsHashMap<String, ConfVars>配置项的Map集合,key是配置下·名称,value是配置项对象
3reverseMapHashMap<String, ConfVars>这个集合包含2套同样的配置,包含varname一组,altName重复添加,ConfVar的value都是一样的。另外在处理这个属性时还用到reverseMapLock来保证修改时的线程安全性
  • 按功能划分的配置项集合类属性,为了方便使用,把各个配置项组合起来
序号属性名类型含义
1restrictListArrayList运行时拒绝修改的变量集合,包含hive in test、hidden list、restrictList、Internal varible、spark rsc conf list
2hiddenSetHashSet隐藏的配置列表:METASTOREPWD、HIVE_SERVER2_SSL_KEYSTORE_PASSWORD+S3 credentials相关配置
3rscListArrayListSpark远程context配置,修改的话会导致新建spark session。HIVE_SPARK_RSC_CONF_LIST
4metaVarsConfVars[]metastore相关的配置数组,当里面的配置修改时会重新建立hive cli
5metaConfVarsConfVars[]用户可以配置的metastore相关配置,包含try direct sql、ddl、partition name whitelist pattern
6dbVarsConfVars[]包含hadoop.bin.path、hive.metastore.warehouse.dir数据库存放位置、hive.exec.scratchdir运行时临时文件存放位置
7ENCODED_CONFConfVars[]加密的配置清单,目前只有queryString查询语句列表是加密的
8llapDaemonVarsSetSetllap进程相关设置,llap是long live and process的简称,是Hive 2.0新加的特性,可以让Hive程序长时间保持与Yarn的连接,达到减小启动次数、通信时间、资源复用的目的,从而提高效率。需要配置Tez引擎替换MR引擎。

2.2 Properties相关属性

序号属性名类型含义
1origPropPropertiesHiveConf下所有properties,通过遍历所有ConfVars对象获取

2.3 环境相关属性

序号属性名类型含义
1hiveJarStringjar包保存路径,读取的hadoop JobConf的job.jar路径(mapreduce.job.jar)
2ausJarsStringhive.aux.jars.path下的所有jar包用分隔符,拼接成String,主要是找hive_cli.jar
3hiveDefaultURLURLhive-default.xml位置的URL对象
4hiveSiteURLURLhive-site.xml位置的URL对象
5hivemetastoreSiteUrlURLhivemetastore-site.xml位置的URL对象
6hiveServer2SiteUrlURLhiveserver2-site.xml位置的URL对象
7loadMetastoreConfigboolean是否开启远程元数据存储Metastore
8loadHiveServer2Configboolean是否加载hiveserver2-site.xml

2.4 描述类属性

序号属性名类型含义
1LOGLogslf4j 日志对象,用于记录日志
2isSparkConfigUpdatedboolean是否spark.开头的参数有进行修改更新
3LOG_PREFIX_LENGTHint日志ID的长度,默认64位字符
4PREFIX_LLAPStringllap.字符串,用于配置项前缀
5PREFIX_HIVE_LLAPStringhive.llap.字符串,用于配置项前缀
6HIVE_LLAP_DAEMON_SERVICE_PRINCIPAL_NAMEString常量,写死hive.llap.daemon.service.principal配置项
7HIVE_SERVER2_AUTHENTICATION_LDAP_USERMEMBERSHIPKEY_NAMEString常量,写死hive.server2.authentication.ldap.userMembershipKey
8daySet、hourSet、minuteSet、secondSet、milliSet、microSet、nanoSetHive中各种时间单位对应的字符串

3 HiveConf类方法

​ 方法分4大类:构造函数、常规Get/Set、功能方法、非常规GET/SET。重点讲下功能方法,其他的可获取思维导图查看。

11

3.1 功能方法

关键的方法是:initialize方法, 他的作用是把所有配置项进行初始化。

序号方法方法功能说明
1findConfigFile找Hive配置文件的URL地址HIVE_CONF_DIR=>HIVE_HOME拼接conf=>HiveConf.class的Jar包运行位置
2checkConfigFile检查文件是否Hive配置文件,并返回URL对象
3populateLlapDaemonVarsSet往传入的集合插入LlapDaemonVarsSet相关配置
4verifyAndSet检查配置是否允许在runtime修改,如果允许则配置为输入的value值
5isHiddenConfig检查配置是否是隐藏配置,不允许自定义参数
6isEncodedPar检查配置是否加密配置HiveConf.ENCODED_CONF
7isSparkRelatedConfig检查是否sprak相关配置spark开头、yarn的spark.master
8getDefaultTimeUnit获取默认时间单位
9toTime把数值跟旧单位转换成新单位的数值
10toSizeBytes把传进来的带单位字符串转换成数值(数值*单位)
11parseNumberFollowedByUnit把带单位的字符串转换成数值+单位的数组
12unitFor根据传入字符串返回对应时间单位
13multiplierFor转换倍数,根据传入byte、kb、Mb、gb、tb,返回到byte对应的转换倍数
14stringFor根据传入的TimeUnit,返回对应单位的字符串
15isSparkDPPAny获取SPARK_DYNAMIC_PARTITION_PRUNING配置项的值
16logVars把所有配置项及值打印出来
17initialize关键方法:通过一些列步骤,初始化HiveConf类
18convertVarsToRegex把配置项转换成正则表达式,如hive.map=>hive\.map
19applyDefaultNonNullConfVars把传入的conf对象的默认值设置好
20addToRestrictList把当前内容加入到restrictList中
21stripHiddenConfigurations删除隐藏配置值,有配置值的会置空
22isWebUiEnabled判断是否开启了WEBUI
23isWebUiQueryInfoCacheEnabled判断是否开启了WEBUI查询语句缓存功能
24isSparkDPPAny判断是否开启了spark 动态分区
25isSparkDPPOnlyMapjoin判断SPARK_DYNAMIC_PARTITION_PRUNING、SPARK_DYNAMIC_PARTITION_PRUNING_MAP_JOIN_ONLY是否开启
26isLoadMetastoreConfig判断是否加载metastore配置
27generateMrDeprecationWarning生成mr引擎在未来将会弃用的警告
28verifyAndSetAll检查并配置所有参数(是否在运行时可修改)
29subtree获取传入的参数开头对应的子树值,如传入spark,spark.map==>map

4 内部类

​ HiveConf内部类有ConfVars枚举类、静态内部类StrictChecks、加解密相关类。

11

4.1 ConfVars枚举类

#### 4.1.1 类属性
序号属性名类型含义
1各种英文大写的枚举值枚举用于标识Hive的配置项,包含varname、defaultValue、Value等
2varnameString配置项名称,hive.map.xxx
3altNameString配置项别名,hive.map.xxx
4defaultExprString配置项默认正则表达式
5defaultStrVal、defaultIntVal、defaultLongVal、defaultFloatVal、defaultBoolValString配置项默认字符串、整数、长整数、浮点、布尔值
6valClassClass<?>配置项的值的类
7valTypeVarType配置项值的类型(内部枚举类VarType)
8validatorValidator
9descriptionString配置项说明
10excludedboolean是否剔除改项
11caseSensitiveboolean是否大小写敏感

各种英文大写的枚举值举例如下代码,其中大写英文为配置项名字,"hive.xxx"为varname,第二个引号为defaultStrVal等配置值,最后的比较长的英文描述为配置项的描述description:

    SCRIPTWRAPPER("hive.exec.script.wrapper", null, ""),
    PLAN("hive.exec.plan", "", ""),
    STAGINGDIR("hive.exec.stagingdir", ".hive-staging",
        "Directory name that will be created inside table locations in order to support HDFS encryption. " +
        "This is replaces ${hive.exec.scratchdir} for query results with the exception of read-only tables. " +
        "In all cases ${hive.exec.scratchdir} is still used for other temporary files, such as job plans."),
    SCRATCHDIR("hive.exec.scratchdir", "/tmp/hive",
        "HDFS root scratch dir for Hive jobs which gets created with write all (733) permission. " +
        "For each connecting user, an HDFS scratch dir: ${hive.exec.scratchdir}/<username> is created, " +
        "with ${hive.scratch.dir.permission}."),
    REPLDIR("hive.repl.rootdir","/user/hive/repl/",
        "HDFS root dir for all replication dumps."),
    REPLCMENABLED("hive.repl.cm.enabled", false,
        "Turn on ChangeManager, so delete files will go to cmrootdir.")
4.1.2 ConfVars枚举类方法

ConfVars枚举类内部也有定义一些常用方法,包含构造方法、Get/Set方法、功能类方法,主要看功能类方法可以了解到ConfVars类内部的一些操作。

序号方法方法功能说明
1validate校验传入的value是否属于validator属性对象
2validatorDescription把validator属性对象转换成描述文字
3typeString获取valType的类型字符串
4toString把varname当作var对象的string输出
5findHadoopBinary找到hadoop bin文件夹路径
6findYarnBinary找到hadoop/yarn/bin文件夹路径
7findMapRedBinary找到hadoop/mpred/bin路径
8findHadoopHome找到HADOOP_HOME、HADOOP_PREFIX路径
9getValidStringValues获取校验后的参数值集合
4.1.2 ConfVars内部的VarType枚举类

ConfVars内部的VarType枚举类主要用于定义ConfVars的值的类型,包含STRING/INT/LONG/FLOAT/BOOLEAN。不在这里定义的类型都不能作为ConfVars的value。枚举类里面建了内部枚举类,这个有点意思。

类属性

序号属性名类型含义
1STRING枚举项String类型的值
2INT枚举项Int类型的值
3LONG枚举项long类型的值
4FLOAT枚举项float类型的值
5BOOLEAN枚举项boolean类型的值

类方法

序号方法名功能
1checkType抽象方法,用于判断类型
2isType利用checkType判断配置的值是不是在5类中
3typeString枚举类的名称对应的字符串
4defaultValueString获取confVar.defaultExpr

5 静态块

HiveConf类里面包含2静态块,1个用于初始化参数,1个用于设置metaStore相关Hive配置参数。

  1. 初始化参数的静态块
static {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    if (classLoader == null) {
      classLoader = HiveConf.class.getClassLoader();
    }

    hiveDefaultURL = classLoader.getResource("hive-default.xml");

    // Look for hive-site.xml on the CLASSPATH and log its location if found.
    hiveSiteURL = findConfigFile(classLoader, "hive-site.xml", true);
    hivemetastoreSiteUrl = findConfigFile(classLoader, "hivemetastore-site.xml", false);
    hiveServer2SiteUrl = findConfigFile(classLoader, "hiveserver2-site.xml", false);

    for (ConfVars confVar : ConfVars.values()) {
      vars.put(confVar.varname, confVar);
    }

    Set<String> llapDaemonConfVarsSetLocal = new LinkedHashSet<>();
    populateLlapDaemonVarsSet(llapDaemonConfVarsSetLocal);
    llapDaemonVarsSet = Collections.unmodifiableSet(llapDaemonConfVarsSetLocal);
  }
  1. 设置metaStore配置的静态块
static {
    for (ConfVars confVar : metaConfVars) {
      metaConfs.put(confVar.varname, confVar);
    }
  }

6 对HiveConf类的思考

经过查看HiveConf类的源码,我得到了以下几个方面的思考:

  1. 常用的Hive配置有哪些?
  2. 一个配置类有哪些特性?
  3. 枚举类的使用方法参考。
  4. 源码对InputStream流的优化。

6.1 常用的Hive配置

HiveConf源码里Hive配置项可以摘取,并分以下几类:

11

6.1.1 按功能分配好的配置集合的配置项
  1. llapDaemonVarsSet:llap功能相关配置项的集合,以hive.llap开头。LLAP是hive 2.0.0版本引入的新特性,hive官方称为(Live long and process),将数据预取、缓存到基于yarn运行的守护进程中,降低和减少系统IO和与HDFS DataNode的交互。

    • keberos认证相关

      序号varname功能
      1hive.llap.task.scheduler.am.registry.principalam的注册协议,设置keberos
      2hive.llap.task.scheduler.am.registry.keytab.filekeytab文件的路径
      3hive.llap.daemon.service.principalllap后台进程的认证协议
      4hive.llap.daemon.keytab.filekeytab文件路径
    • 开启LLAP需要的配置

      序号varname功能
      1hive.llap.execution.mode查询执行模式,有auto、none、all、map、only几个选项
      2hive.llap.io.enabled是否开启llap ip功能
      3hive.execution.mode设置查询试运行在container或者llap
      5hive.llap.daemon.memory.per.instance.mb单个llap执行executor的总内存
      7hive.llap.zk.sm.connectionString连接zookeeper集群的连接串
      8hive.llap.zk.registry.namespacellap在zookeeper的路径
      9hive.llap.zk.registry.userllap登录zookeeper的用户名
    • 运行资源配置相关

      序号varname功能
      1hive.llap.daemon.yarn.container.mbllap功能在yarn的container的内存大小,默认-1-无限制
      2hive.llap.daemon.queue.namellap功能的队列名
      3hive.llap.daemon.vcpus.per.instance每一个llap实例的虚拟cpu核数
      4hive.llap.daemon.num.executors每一个llap进程的executor数,默认是4,相当于并行度设置
  2. Value隐藏加密的配置项HiddenConfig

    序号varname功能
    1javax.jdo.option.ConnectionPassword连接的密码
    2hive.server2.keystore.passwordHive Server2的密码
    3S3 credentials相关配置AWS S3认证相关的配置
  3. 加密的参数:只有ENCODE_CONF,目前只有一个hive.query.string

  4. Spark相关的配置(SparkReleatedConfig)

    序号说明功能
    1spark开头的参数Spark相关配置
    2yarn开头并且包含spark.masterSpark相关配置
    3在Spark rscList里面的配置项,请看上面的HiveConf类属性Spark相关配置
    4mapreduce.job.queuename运行的队列,默认MR引擎也有这个
  5. 元素据相关配置metaConfs

    序号varname功能
    1hive.metastore.try.direct.sql当需要读取大量分区、字段时可以开启这个减少读取时间
    2hive.metastore.try.direct.sql.ddl跳过metaStore运行语句
    3hive.metastore.client.socket.timeout超时时间,默认600s
    4hive.metastore.partition.name.whitelist.pattern分区正则白名单,匹配的的分区名称才能创建
    5hive.metastore.client.capability.check是否开启metaStore的容量检查
    6hive.metastore.disallow.incompatible.col.type.changes开启后禁止修改字段类型为另外一种不兼容的字段类型
  6. 系统相关配置集合ConfSystemProperties(主要是读取一些系统参数)

  7. RestrictList:不允许在运行时修改的配置HIVE_CONF_RESTRICTED_LIST,hive.conf.restricted.list,包含以下配置:

    "hive.security.authenticator.manager,hive.security.authorization.manager," +
    "hive.security.metastore.authorization.manager,hive.security.metastore.authenticator.manager," +
    "hive.users.in.admin.role,hive.server2.xsrf.filter.enabled,hive.security.authorization.enabled," +
    "hive.distcp.privileged.doAs," +
    "hive.server2.authentication.ldap.baseDN," +
    "hive.server2.authentication.ldap.url," +
    "hive.server2.authentication.ldap.Domain," +
    "hive.server2.authentication.ldap.groupDNPattern," +
    "hive.server2.authentication.ldap.groupFilter," +
    "hive.server2.authentication.ldap.userDNPattern," +
    "hive.server2.authentication.ldap.userFilter," +
    "hive.server2.authentication.ldap.groupMembershipKey," +
    "hive.server2.authentication.ldap.userMembershipKey," +
    "hive.server2.authentication.ldap.groupClassKey," +
    "hive.server2.authentication.ldap.customLDAPQuery," +
    "hive.privilege.synchronizer," +
    "hive.privilege.synchronizer.interval," +
    "hive.spark.client.connect.timeout," +
    "hive.spark.client.server.connect.timeout," +
    "hive.spark.client.channel.log.level," +
    "hive.spark.client.rpc.max.size," +
    "hive.spark.client.rpc.threads," +
    "hive.spark.client.secret.bits," +
    "hive.spark.client.rpc.server.address," +
    "hive.spark.client.rpc.server.port," +
    "hive.spark.client.rpc.sasl.mechanisms," +
    "bonecp.,"+
    "hive.druid.broker.address.default,"+
    "hive.druid.coordinator.address.default,"+
    "hikari.,"+
    "hadoop.bin.path,"+
    "yarn.bin.path,"+
    "spark.home",
    
  8. RSCList,Spark Remote Client配置,修改以下任一项会导致重新建立一个spark session

    序号varname功能
    1hive.spark.optimize.shuffle.serde是否进行shuffle优化
    2hive.spark.client.future.timeout连接Spark的超时断开时间
6.1.2 环境、位置相关配置项
序号配置别名说明
1hiveDefaultURLclassLoader.getResource(“hive-default.xml”)
2hiveSiteURL优先从HIVE_CONF_DIR找,没有就找HIVE_HOME/conf,还没有就找jar包的URI,再拼接/conf
3hivemetastoreSiteUrlhivemetastore-site.xml的位置
4hiveServer2SiteUrlhiveserver2-site.xml的位置
5hiveJarHIVEJAR,hive.jar.path,主要是找hive_cli.jar的位置
6auxjarsHIVEAUXJARS,hive.aux.jars.path,找Hive插件jar包的位置
*6.1.3 调优相关配置项
  1. 动态分区相关

    序号varname说明
    1hive.exec.dynamic.partition是否开启动态分区
    2hive.exec.dynamic.partition.mode有严格和非严格模式,严格模式的话必须指定确认的分区
    3hive.exec.max.dynamic.partitions最大动态分区数
  2. 本地模式相关

    序号varname说明
    1hive.exec.mode.local.auto是否自动开启local模式,默认false。本地模式就是在本地执行任务,适用于数据量少的情况下减少网络传输及硬盘IO导致的消耗。
    2hive.exec.mode.local.auto.inputbytes.max设置开启本地模式的数据大小,小于设置值时通过本地模式运行
  3. mapjoin相关

    序号varname说明
    1hive.ignore.mapjoin.hint是否忽略SQL语句里面的map join提示语法
    2hive.mapjoin.bucket.cache.size(旧)/hive.smbjoin.cache.row(新)开启smbjoin时,小于多少开启MAP JOIN
    3hive.mapjoin.optimized.hashtablemapjoin开启hashtable优化,只支持tez跟spark
    4hive.mapjoin.smalltable.filesize表大小小于多少时开启MAPJOIN,默认25Mb
    5hive.auto.convert.join是否开启自动MAP JOIN,默认true。跟smalltable.filesize设置有关
  4. 聚合相关

    序号varname说明
    1hive.transpose.aggr.joinJoin操作的同时进行聚合,默认FALSE.开启可能会对最终结果有影响
    2hive.groupby.mapaggr.checkinterval分组字段达到多少行后进行聚合,默认100000
    3hive.map.aggrgroup by查询时是否开启map端聚合,默认true
    4hive.optimize.countdistinct是否转换count distinct为2个阶段,即先group by去重然后count。默认为true
  5. 小文件相关

    序号varname说明
    1hive.merge.tezfilestez的dag后面合并小文件
    2hive.merge.sparkfiles合并spark任务的小文件
    3hive.merge.size.per.task合并小文件任务的输出尺寸,默认256Mb
    4hive.merge.smallfiles.avgsize合并小文件的平均尺寸,默认16Mb
    5hive.merge.mapfilesmap only任务后面合并小文件,默认true
    6hive.merge.mapredfiles在map reduce任务后面合并小文件,默认true
  6. 数据倾斜相关

    序号varname说明
    1hive.groupby.skewindatagroup by查询是否开启数据倾斜优化,默认false
    2hive.optimize.skewjoin是否进行数据倾斜优化,默认false。开启后当某key比较大时,会把相关数据存到hdfs然后开启另外一个mr去处理
    3hive.skewjoin.key当key大于这个值时,认为是数据倾斜了.默认10万
    4hive.optimize.skewjoin.compiletime利用元数据中的倾斜key,单独为倾斜key开启一个任务,然后其他key为第2个任务。最后2个任务结果用UNION合并起来。默认false
  7. 桶、CBO跟分片

    序号varname说明
    1mapreduce.input.fileinputformat.split.maxsize切片的最大文件大小
    2mapreduce.input.fileinputformat.split.minsize切片的最小文件大小,跟maxSize,配合计算出切片数量
    3hive.cbo.enable是否开启CBO(Cost Base Optimize)优化,默认true。
    4hive.optimize.groupby在bucket表中用bucketed group by。默认true
    5hive.optimize.bucketmapjoin是否进行bucket map join,默认false
    6hive.optimize.bucketmapjoin.sortedmerge是否开启sortedmerge map join,默认false。需要2个join表都是分桶表,且桶内有进行排序
  8. 其他

    序号varname说明
    1hive.spark.optimize.shuffle.serdespark shuffle时启用序列化,可以减少shuffle的文件大小
    2hive.query.timeout.seconds查询超过多少秒后失败

6.2 一个配置类的特性有哪些?

经过总结,主要有以下4点:

11

  1. 一个配置类必须要包含有系统必要的配置选项,否则就不能是一个配置类。

  2. 在实际编码中如何获取配置文件呢?
    11
    其中通过jar包运行位置去查找的代码如下:

    HiveConf.class.getProtectionDomain().getCodeSource().getLocation();
    jarUri = sourceUrl.getProtocol().equalsIgnoreCase("jar") ? new URI(sourceUrl.getPath()) : sourceUrl.toURI();
    
  3. 如何合理初始化配置项?
    11

  4. 如何安全的在线修改配置值?
    11

6.3 枚举类的使用参考

  1. 通过通过不同的构造函数定义不同枚举项;
  2. 使用一个枚举项作为其他枚举项的集合,value就是其他枚举项的拼接。如HIVE_SPARK_RSC_CONF_LIST,可以快速的找到相关配置项;
  3. 通过枚举类内部一个抽象方法,让枚举项都重写这个抽象方法。如VarType里面有一个checkType抽象方法, 内部的枚举项都重写了这个方法。
全文完
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值