大数据技术原理与应用-大数据处理架构Hadoop



1 概述

1.1 Hadoop简介

Hadoop的标志

  • Hadoop是Apache软件基金会旗下的一个开源分布式计算平台,为用户提供了系统底层细节透明的分布式基础架构
  • Hadoop是基于Java语言开发的,具有很好的跨平台特性,并且可以部署在廉价的计算机集群中
  • Hadoop的核心是分布式文件系统HDFS(Hadoop Distributed File System)和MapReduce
  • Hadoop被公认为行业大数据标准开源软件,在分布式环境下提供了海量数据的处理能力
  • 几乎所有主流厂商都围绕Hadoop提供开发工具、开源软件、商业化工具和技术服务,如谷歌、雅虎、微软、思科、淘宝等,都支持Hadoop

1.2 Hadoop发展简史

  • Hadoop最初是由Apache Lucene项目的创始人Doug Cutting开发的文本搜索库。Hadoop源自始于2002年的Apache Nutch项目——一个开源的网络搜索引擎并且也是Lucene项目的一部分
  • 在2004年,Nutch项目也模仿GFS开发了自己的分布式文件系统NDFS(Nutch Distributed File System),也就是HDFS的前身
  • 2004年,谷歌公司又发表了另一篇具有深远影响的论文,阐述了MapReduce分布式编程思想
  • 2005年,Nutch开源实现了谷歌的MapReduce
  • 到了2006年2月,Nutch中的NDFS和MapReduce开始独立出来,成为Lucene项目的一个子项目,称为Hadoop,同时,Doug Cutting加盟雅虎
  • 2008年1月,Hadoop正式成为Apache顶级项目,Hadoop也逐渐开始被雅虎之外的其他公司使用
  • 2008年4月,Hadoop打破世界纪录,成为最快排序1TB数据的系统,它采用一个由910个节点构成的集群进行运算,排序时间只用了209秒
  • 在2009年5月,Hadoop更是把1TB数据排序时间缩短到62秒。Hadoop从此名声大震,迅速发展成为大数据时代最具影响力的开源分布式开发平台,并成为事实上的大数据处理标准

1.3 Hadoop的特性

Hadoop是一个能够对大量数据进行分布式处理的软件框架,并且是以一种可靠、高效、可伸缩的方式进行处理的,它具有以下几个方面的特性:

  • 高可靠性
  • 高效性
  • 高可扩展性
  • 高容错性
  • 成本低
  • 运行在Linux平台上
  • 支持多种编程语言

1.4 Hadoop的应用现状

  • Hadoop凭借其突出的优势,已经在各个领域得到了广泛的应用,而互联网领域是其应用的主阵地
  • 2007年,雅虎在Sunnyvale总部建立了M45——一个包含了4000个处理器和1.5PB容量的Hadoop集群系统
  • Facebook作为全球知名的社交网站,Hadoop是非常理想的选择,Facebook主要将Hadoop平台用于日志处理、推荐系统和数据仓库等方面
  • 国内采用Hadoop的公司主要有百度、淘宝、网易、华为、中国移动等,其中,淘宝的Hadoop集群比较大

Hadoop在企业中的应用架构

1.5 Apache Hadoop版本演变

  • Apache Hadoop版本分为两代,我们将第一代Hadoop称为Hadoop 1.0,第二代Hadoop称为Hadoop 2.0
  • 第一代Hadoop包含三个大版本,分别是0.20.x,0.21.x和0.22.x,其中,0.20.x最后演化成1.0.x,变成了稳定版,而0.21.x和0.22.x则增加了NameNode HA等新的重大特性
  • 第二代Hadoop包含两个版本,分别是0.23.x和2.x,它们完全不同于Hadoop 1.0,是一套全新的架构,均包含HDFS Federation和YARN两个系统,相比于0.23.x,2.x增加了NameNode HA和Wire-compatibility两个重大特性

在这里插入图片描述

1.6 Hadoop各种版本

选择 Hadoop版本的考虑因素:

  • 是否开源(即是否免费)
  • 是否有稳定版
  • 是否经实践检验
  • 是否有强大的社区支持

在这里插入图片描述


2 Hadoop项目结构

Hadoop的项目结构不断丰富发展,已经形成一个丰富的Hadoop生态系统。

在这里插入图片描述

组件功能
HDFS分布式文件系统
MapReduce分布式并行编程模型
YARN资源管理和调度器
Tez运行在YARN之上的下一代Hadoop查询处理框架
HiveHadoop上的数据仓库
HBaseHadoop上的非关系型的分布式数据库
Pig一个基于Hadoop的大规模数据分析平台,提供类似SQL的查询语言Pig Latin
Sqoop用于在Hadoop与传统数据库之间进行数据传递
OozieHadoop上的工作流管理系统
Zookeeper提供分布式协调一致性服务
Storm流计算框架
Flume一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统
AmbariHadoop快速部署工具,支持Apache Hadoop集群的供应、管理和监控
Kafka一种高吞吐量的分布式发布订阅消息系统,可以处理消费者规模的网站中的所有动作流数据
Spark类似于Hadoop MapReduce的通用并行框架



3 Hadoop的安装与使用

3.1 准备工作

  • 系统环境选择CentOS 6.4 64位
  • 安装Java8环境

3.2 创建hadoop用户

root用户登陆后,执行命令创建新用户hadoop并修改密码,按提示输入两次密码,可简单的设为 “hadoop”(密码随意指定,若提示“无效的密码,过于简单”则再次输入确认就行)。

useradd -m hadoop -s /bin/bash   # 创建新用户hadoop
passwd hadoop   # 修改密码

如下图:

创建hadoop用户
可为 hadoop 用户增加管理员权限,方便部署,执行:

viduso

如下图,找到 root ALL=(ALL) ALL 这行(应该在第98行,可以先按一下键盘上的 ESC 键,然后输入:98,可以直接跳到第98行),然后在这行下面增加一行内容hadoop ALL=(ALL) ALL,如下图所示:

在这里插入图片描述
添加上一行内容后,先按一下键盘上的 ESC 键,然后输入 :wq,再按回车键保存退出就可以了。最后注销当前用户,使用刚创建的 hadoop 用户进行登陆。

3.3 SSH登录权限设置

SSH是什么?
SSH 为 Secure Shell 的缩写,是建立在应用层和传输层基础上的安全协议。SSH 是目前较可靠、专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。SSH最初是UNIX系统上的一个程序,后来又迅速扩展到其他操作平台。 SSH是由客户端和服务端的软件组成,服务端是一个守护进程(daemon),它在后台运行并响应来自客户端的连接请求,客户端包含ssh程序以及像scp(远程拷贝)、slogin(远程登陆)、sftp(安全文件传输)等其他的应用程序。

配置SSH的原因:
Hadoop名称节点(NameNode)需要启动集群中所有机器的Hadoop守护进程,这个过程需要通过SSH登录来实现。Hadoop并没有提供SSH输入密码登录的形式,因此,为了能够顺利登录每台机器,需要将所有机器配置为名称节点可以无密码登录它们。

配置SSH无密码登陆
首先执行如下命令测试一下 SSH 是否可用:

ssh localhost

按提示输入密码即可登陆到本机了,如下图:

在这里插入图片描述
输入 exit 退出刚才的 ssh,然后利用 ssh-keygen 生成密钥,并将密钥加入到授权中:

exit                           # 退出刚才的 ssh localhost
cd ~/.ssh/                     # 若没有该目录,请先执行一次ssh localhost
ssh-keygen -t rsa              # 会有提示,都按回车就可以
cat id_rsa.pub >> authorized_keys  # 加入授权
chmod 600 ./authorized_keys    # 修改文件权限

此时再用 ssh localhost 命令,无需输入密码就可以直接登陆了。

3.4 安装Hadoop

去官网下载最新版hadoop-3.1.2.tar.gz,选择安装至/usr/local/ 中:

wget http://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.1.2/hadoop-3.1.2.tar.gz    # 下载hadoop安装包
sudo tar -zxf hadoop-3.1.2.tar.gz -C /usr/local    # 解压到/usr/local中
cd /usr/local/
sudo chown -R hadoop:hadoop ./hadoop-3.1.2    # 修改文件权限

Hadoop 解压后即可使用。输入如下命令来检查 Hadoop 是否可用,成功则会显示 Hadoop 版本信息:

cd /usr/local/hadoop-3.1.2
./bin/hadoop version

打印版本信息命令报错:ERROR: JAVA_HOME is not set and could not be found.
需修改hadoop-3.1.2/etc/hadoop目录下hadoop-env.sh文件,添加或修改 export JAVA_HOME=/usr/java/jdk1.8.0_161


3.5 Hadoop单机模式测试

Hadoop 默认模式为非分布式模式,无需进行其他配置即可运行。非分布式即单 Java 进程,方便进行调试。

现在我们可以执行例子来感受下 Hadoop 的运行。Hadoop 附带了丰富的例子(运行 ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.2.jar 可以看到所有例子),包括 wordcount、terasort、join、grep 等。

在此我们选择运行 grep 例子,我们将 input 文件夹中的所有文件作为输入,筛选当中符合正则表达式 dfs[a-z.]+ 的单词并统计出现的次数,最后输出结果到 output 文件夹中。

cd /usr/local/hadoop
mkdir ./test_input
cp ./etc/hadoop/*.xml ./test_input    # 将配置文件作为输入文件
./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.2.jar grep ./test_input ./test_output 'dfs[a-z.]+'
cat ./output/*    # 查看运行结果

执行成功的话会输出很多作业的相关信息,最后的输出信息如下图所示。作业的结果会输出在指定的 test_output 文件夹中,通过命令 cat ./output/* 查看结果,符合正则的单词 dfsadmin 出现了1次:

在这里插入图片描述
注意,Hadoop 默认不会覆盖结果文件,因此再次运行上面实例会提示出错,需要先执行 rm -r ./test_output 将 ./test_output 删除。

3.6 Hadoop伪分布式配置

Hadoop 可以在单节点上以伪分布式的方式运行,Hadoop 进程以分离的 Java 进程来运行,节点既作为 NameNode 也作为 DataNode,同时,读取的是 HDFS 中的文件。

Hadoop 的配置文件位于 /usr/local/hadoop/etc/hadoop/ 中,伪分布式需要修改2个配置文件 core-site.xml 和 hdfs-site.xml 。Hadoop的配置文件是 xml 格式,每个配置以声明 property 的 name 和 value 的方式来实现。

3.6.1 修改配置文件 core-site.xml

<configuration>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>file:/usr/local/hadoop-3.1.2/tmp</value>
        <description>Abase for other temporary directories.</description>
    </property>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
    </property>
</configuration>
  • hadoop.tmp.dir表示存放临时数据的目录,即包括NameNode的数据,也包括DataNode的数据。该路径任意指定,只要实际存在该文件夹即可
  • name为fs.defaultFS的值,表示hdfs路径的逻辑名称

3.6.2 修改配置文件 hdfs-site.xml

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/usr/local/hadoop-3.1.2/tmp/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/usr/local/hadoop-3.1.2/tmp/dfs/data</value>
    </property>
</configuration>
  • dfs.replication表示副本的数量,伪分布式要设置为1
  • dfs.namenode.name.dir表示本地磁盘目录,是存储fsimage文件的地方
  • dfs.datanode.data.dir表示本地磁盘目录,HDFS数据存放block的地方

3.6.3 执行 NameNode 的格式化

./bin/hdfs namenode -format

3.6.4 开启 NameNode 和 DataNode 守护进程

./sbin/start-dfs.sh

启动完成后,可以通过命令 jps 来判断是否成功启动,若成功启动则会列出如下进程: “NameNode”、”DataNode”和“SecondaryNameNode”。

在这里插入图片描述
成功启动后,可以访问Web 界面 http://ip:9870 查看 NameNode 和 DataNode 信息,还可以在线查看 HDFS 中的文件。

在这里插入图片描述

若启动失败可以去 /usr/local/hadoop-3.1.2/logs 文件夹下查看对应的日志文件。
笔者在启动Hadoop时发现DameNode启动失败,是由于多次格式化NameNode导致。在配置文件中保存的是第一次格式化时保存的NameNode的ID,因此就会造成DataNode与NameNode之间的id不一致。删除tmp文件夹,重新格式化NameNode即可。
注:Hadoop3 hdfs web默认端口改为了9870


3.7 运行Hadoop伪分布式实例

上面的单机模式,grep 例子读取的是本地数据,伪分布式读取的则是 HDFS 上的数据。要使用 HDFS,首先需要在 HDFS 中创建用户目录:

./bin/hdfs dfs -mkdir -p /user/hadoop

接着将 ./etc/hadoop 中的 xml 文件作为输入文件复制到分布式文件系统中,即将 /usr/local/hadoop/etc/hadoop 复制到分布式文件系统中的 /user/hadoop/input 中。我们使用的是 hadoop 用户,并且已创建相应的用户目录 /user/hadoop ,因此在命令中就可以使用相对路径如 input,其对应的绝对路径就是 /user/hadoop/input:

./bin/hdfs dfs -mkdir input
./bin/hdfs dfs -put ./etc/hadoop/*.xml input

复制完成后,可以通过如下命令查看 HDFS 中的文件列表:

./bin/hdfs dfs -ls input

伪分布式运行 MapReduce 作业的方式跟单机模式相同,区别在于伪分布式读取的是HDFS中的文件。

./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.2.jar grep input output 'dfs[a-z.]+'

查看运行结果的命令(查看的是位于 HDFS 中的输出结果):

./bin/hdfs dfs -cat output/*

Hadoop 运行程序时,输出目录不能存在,否则会提示错误 org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://localhost:9000/user/hadoop/output already exists,因此若要再次执行,需要执行如下命令删除 output 文件夹:

./bin/hdfs dfs -rm -r output

若要关闭 Hadoop,则运行

./sbin/stop-dfs.sh

下次启动 hadoop 时,无需进行 NameNode 的初始化,只需要运行 ./sbin/start-dfs.sh 即可。

3.8 启动YARN

YARN(Yet Another Resource Negotiator)是从 MapReduce 中分离出来的,负责资源管理与任务调度。YARN 运行于 MapReduce 之上,提供了高可用性、高扩展性。

伪分布式不启动 YARN 也可以,一般不会影响程序执行。

上述通过 ./sbin/start-dfs.sh 启动 Hadoop,仅仅是启动了 MapReduce 环境,我们可以启动 YARN ,让 YARN 来负责资源管理与任务调度。

首先修改配置文件 mapred-site.xml,

<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
  		<name>yarn.app.mapreduce.am.env</name>
  		<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
	</property>
	<property>
	 	<name>mapreduce.map.env</name>
	 	<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
	</property>
	<property>
	 	<name>mapreduce.reduce.env</name>
	 	<value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
	</property>
</configuration>

接着修改配置文件 yarn-site.xml,

<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
        </property>
</configuration>

然后就可以启动 YARN 了(需要先执行过 ./sbin/start-dfs.sh):

./sbin/start-yarn.sh    # 启动YARN
./sbin/mr-jobhistory-daemon.sh start historyserver    # 开启历史服务器,才能在Web中查看任务运行情况

开启后通过 jps 查看,可以看到多了 JobHistoryServer、NodeManager 和 ResourceManager 三个后台进程。

启动 YARN 之后,运行实例的方法还是一样的,仅仅是资源管理方式、任务调度不同。观察日志信息可以发现,不启用 YARN 时,是 “mapred.LocalJobRunner” 在跑任务,启用 YARN 之后,是 “mapred.YARNRunner” 在跑任务。启动 YARN 有个好处是可以通过 Web 界面查看任务的运行情况:http://ip:8088/cluster ,如下图所示。
在这里插入图片描述
但 YARN 主要是为集群提供更好的资源管理与任务调度,然而这在单机上体现不出价值,反而会使程序跑得稍慢些。因此在单机上是否开启 YARN 就看实际情况了。

同样的,关闭 YARN 的脚本如下:

./sbin/stop-yarn.sh
./sbin/mr-jobhistory-daemon.sh stop historyserver

3.9 附:配置PATH环境变量

这里额外讲一下 PATH 这个环境变量(可执行 echo $PATH 查看,当中包含了多个目录)。例如我们在主文件夹 ~ 中执行 ls 这个命令时,实际执行的是 /bin/ls 这个程序,而不是 ~/ls 这个程序。系统是根据 PATH 这个环境变量中包含的目录位置,逐一进行查找,直至在这些目录位置下找到匹配的程序(若没有匹配的则提示该命令不存在)。

之前我们都是先进入到 /usr/local/hadoop 目录中,再执行 sbin/hadoop,实际上等同于运行 /usr/local/hadoop/sbin/hadoop。我们可以将 Hadoop 命令的相关目录加入到 PATH 环境变量中,这样就可以直接通过 start-dfs.sh 开启 Hadoop,也可以直接通过 hdfs 访问 HDFS 的内容,方便平时的操作。

我们选择在 ~/.bashrc 中进行设置,执行 vim ~/.bashrc,在文件最前面加入如下单独一行:

export PATH=$PATH:/usr/local/hadoop-3.1.2/sbin:/usr/local/hadoop-3.1.2/bin

添加后执行 source ~/.bashrc 使设置生效,生效后,在任意目录中,都可以直接使用 hdfs 等命令了,可以执行 hdfs dfs -ls input 查看 HDFS 文件以做测试。


4 Hadoop集群的部署与使用

4.1 集群节点类型

Hadoop框架中最核心的设计是为海量数据提供存储的HDFS和对数据进行计算的MapReduce。MapReduce的作业主要包括:(1)从磁盘或从网络读取数据,即IO密集工作;(2)计算数据,即CPU密集工作。

Hadoop集群的整体性能取决于CPU、内存、网络以及存储之间的性能平衡,因此在选择机器配置时要针对不同的工作节点选择合适硬件类型。

一个基本的Hadoop集群中的节点主要有

  • NameNode:负责协调集群中的数据存储
  • DataNode:存储被拆分的数据块
  • JobTracker:协调数据计算任务
  • TaskTracker:负责执行由JobTracker指派的任务
  • SecondaryNameNode:帮助NameNode收集文件系统运行的状态信息

4.2 集群规模

  • Hadoop集群规模可大可小,初始时,可以从一个较小规模的集群开始,比如包含10个节点,然后,规模随着存储器和计算需求的扩大而扩大
  • 如果数据每周增大1TB,并且有三个HDFS副本,然后每周需要一个额外的3TB作为原始数据存储。要允许一些中间文件和日志(假定30%)的空间,由此,可以算出每周大约需要增加一台新机器。存储两年数据的集群,大约需要100台机器
  • 对于一个小的集群,名称节点(NameNode)和JobTracker运行在单个节点上,通常是可以接受的。但是,随着集群和存储在HDFS中的文件数量的增加,名称节点需要更多的主存,这时,名称节点和JobTracker就需要运行在不同的节点上
  • 第二名称节点(SecondaryNameNode)会和名称节点可以运行在相同的机器上,但是,由于第二名称节点和名称节点几乎具有相同的主存需求,因此,二者最好运行在不同节点上

4.3 集群硬件配置

在集群中,大部分的机器设备是作为DataNode和TaskTracker工作的。DataNode/TaskTracker的硬件规格可以采用以下方案:

  • 4个磁盘驱动器(单盘1-2T),支持JBOD(Just a Bunch Of Disks,磁盘簇)
  • 2个4核CPU,至少2-2.5GHz
  • 16-24GB内存
  • 千兆以太网

NameNode提供整个HDFS文件系统的NameSpace(命名空间)管理、块管理等所有服务,因此需要更多的RAM,与集群中的数据块数量相对应,并且需要优化RAM的内存通道带宽,采用双通道或三通道以上内存。硬件规格可以采用以下方案:

  • 8-12个磁盘驱动器(单盘1-2T)
  • 2个4核/8核CPU
  • 16-72GB内存
  • 千兆/万兆以太网

SecondaryNameNode在小型集群中可以和NameNode共用一台机器,较大的群集可以采用与NameNode相同的硬件。

4.4 集群网络拓扑

  • 普通的Hadoop集群结构由一个两阶网络构成
  • 每个机架(Rack)有30-40个服务器,配置一个1GB的交换机,并向上传输到一个核心交换机或者路由器(1GB或以上)
  • 在相同的机架中的节点间的带宽的总和,要大于不同机架间的节点间的带宽总和
    在这里插入图片描述

4.5 集群的建立与安装

采购好相关的硬件设备后,就可以把硬件装入机架,安装并运行Hadoop
安装Hadoop有多种方法:

  • 手动安装
  • 自动化安装
    • 为了缓解安装和维护每个节点上相同的软件的负担,可以使用一个自动化方法实现完全自动化安装,比如Red Hat Linux’ Kickstart、Debian或者Docker
    • 自动化安装部署工具,会通过记录在安装过程中对于各个选项的回答来完成自动化安装过程。

4.6 集群基准测试

基准测试用以判断一个Hadoop集群是否已经正确安装。Hadoop自带有一些基准测试程序,被打包在测试程序JAR文件中。

  • 用TestDFSIO基准测试,来测试HDFS的IO性能
  • 用排序测试MapReduce:Hadoop自带一个部分排序的程序,这个测试过程的整个数据集都会通过洗牌(Shuffle)传输至Reducer,可以充分测试MapReduce的性能

4.7 在云计算环境中使用Hadoop

  • Hadoop不仅可以运行在企业内部的集群中,也可以运行在云计算环境中
  • 可以在Amazon EC2中运行Hadoop。EC2是一个计算服务,允许客户租用计算机(实例),来运行自己的应用。客户可以按需运行或终止实例,并且按照实际使用情况来付费
  • Hadoop自带有一套脚本,用于在EC2上面运行Hadoop
  • 在EC2上运行Hadoop尤其适用于一些工作流。例如,在Amazon S3中存储数据,在EC2上运行集群,在集群中运行MapReduce作业,读取存储在S3中的数据,最后,在关闭集群之前将输出写回S3中;如果长期使用集群,复制S3数据到运行在EC2上的HDFS中,则可以使得数据处理更加高效,因为,HDFS可以充分利用数据的位置,S3则做不到,因为,S3与EC2的存储不在同一个节点上


5 小结

  • Hadoop被视为事实上的大数据处理标准,本文介绍了Hadoop的发展历程,并阐述了Hadoop的高可靠性、高效性、高可扩展性、高容错性、成本低、运行在Linux平台上、支持多种编程语言等特性
  • Hadoop目前已经在各个领域得到了广泛的应用,雅虎、Facebook、百度、淘宝、网易等公司都建立了自己的Hadoop集群
  • 经过多年发展,Hadoop项目已经变得非常成熟和完善,包括Common、Avro、Zookeeper、HDFS、MapReduce、HBase、Hive、Chukwa、Pig等子项目,其中,HDFS和MapReduce是Hadoop的两大核心组件
  • 本文最后介绍了如何在Linux系统下完成Hadoop的安装和配置

学习自厦门大学林子雨老师的《大数据技术原理与应用》:http://www.icourse163.org/course/XMU-1002335004

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值