Hadoop最小集群配置

前言

本篇文章配置的Hadoop集群是最简单的,同时也只是用于个人学习,并非是直接搭建在服务器上,所以采用虚拟机来实现。本人也只是一名普通的学生,刚开始接触Hadoop,很多知识都是建立在自己的理解之上,肯定存在有错误或者是不足之处,也很欢迎大家指出并修正!!!

第一次写文章,想着和大家分享一些自己学习过程中的总结和经验,也是面对和我一样的初学者,或是接触计算机不久的小白的一篇文章


一、集群规划和工具、软件的准备

1.集群规划

万事都要先做好规划,一个最简单、最小的Hadoop集群也需要做好规划,使得各个主机要有各自所扮演的角色。

主机

Zookeeper

namenode

journalnode

zkfc

datanode

rm

nm

centos1

centos2

centos3

×

×

Hadoop最核心的三个部件Zookeeper、HDFS(分别是namenode、journalnode、zkfc、datanode)、Yarn(rm表示resourcemanager、nm表示nodemanager),各个主机上安装、启动什么服务都要先做好规划,这里的规划也是为了应对真实环境可能出现的一些突发情况,如:主namenode崩溃后,备namenode能够启动来顶替等,接下来的安装和配置都会以这个表格为基准

2.工具、软件准备

软件如下:

  • 虚拟主机三台(安装了centos6系统)
  • 终端模拟软件和ftp文件传输软件
  • Zookeeper、Hadoop、java安装包

首先需要虚拟主机,这里使用vmware虚拟机,以及centos操作系统,主机的搭建这里就不详细展开了,网上会有很多教程,下载、安装(基本都是一直点下一步)

终端模拟软件,是从外部与虚拟机建立联系的软件,虽然也可以不需要,能直接通过虚拟主机的控制台操作,但为了拟真所使用,这里可以使用包括但不仅限于xshell,只要能用就行,不是只能使用某某软件

ftp文件传输软件,为了给虚拟主机传输软件包的软件,建立连接后,能直接将文件从Windows上发送到虚拟机的指定路径上,可以用xftp或者FileZilla等,只要能进行文件传输即可,没有固定软件要求

Zookeeper、Hadoop、java安装包,官网上下载好,准备传输到虚拟主机上,这里使hadoop-2.7.5.tar.gz、jdk-8u151-linux-x64.tar.gz、zookeeper-3.4.13.tar.gz这三个版本


二、事先准备

在正式开始集群部署之前,要先进行一些设置、操作,来方便后续的集群配置或是防止一些错误的出现

1.工具的使用

打开三台虚拟机,安装完操作系统后,选择其他用户(other...)登录,用户名输入root,密码则是你设置的用户密码,登录后右键桌面弹出菜单,选择open in terminal打开控制台,输入ifconfig就能查询当前机器的ip地址,这里在eth0的第二行inet addr:192.168.85.133,如果不是这种格式的,很有可能是虚拟网卡设置的问题,需要设置为NAT模式,或是你的虚拟机没连上网之类的

[root@centos1 Desktop]$ ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:0C:29:37:62:83  
          inet addr:192.168.85.133  Bcast:192.168.85.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe37:6283/64 Scope:Link
...

三台主机都这样操作,知道ip后,就能使用终端模拟软件和ftp软件进行连接(这里用xshell和FileZilla)

需要注意的是:要使用root用户(系统自带的隐藏的用户)进行登录,xshell建立连接输入ip后连接成功后,需要输入用户名,这里用户名输入root,密码和默认你设置的密码是一样的,如果你使用的是系统的控制台来操作,则需要使用root用户来操作

额外说明一下: 

[root@centos1 Desktop]$,@前面表示当前用户,@后面表示当前主机名(默认为localhost)主机名后为当前文件夹名

2.关闭安全系统

关闭安全系统,防止占用端口等原因,这里需要关闭防火墙以及Linux自带的安全子系统(我是这么理解的,因为是Linux内核中的一些东西)

service iptables stop
chkconfig iptables off

这两条指令是关闭防火墙的,接下来需要关闭安全子系统,先临时关闭,在修改它的配置文件来关闭它的开机自启动,这样达到永久关闭的效果,接下来关闭安全子系统。

setenforce 0
sed -i "s/^SELINUX\=enforcing/SELINUX\=disabled/g" /etc/selinux/config
echo never > /sys/kernel/mm/transparent_hugepage/defrag
echo never > /sys/kernel/mm/transparent_hugepage/enabled

修改limit.conf文件,在修改之前先创建一个备份(修改错了还有救w(゚Д゚)w)

cp /etc/security/limits.conf /etc/security/limits.conf.bak
echo "* soft nproc 32000" >>/etc/security/limits.conf
echo "* hard nproc 32000" >>/etc/security/limits.conf
echo "* soft nofile 65535" >>/etc/security/limits.conf
echo "* hard nofile 65535" >>/etc/security/limits.conf

3.编辑主机名

修改/etc/hosts文件,修改指令vi或者vim(表示编辑文件),vi  /etc/hosts,进入文件后按下i键可以进行修改,修改完后按esc再输入(按下):wq保存并退出

[root@centos1 core]$ vi /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.85.133 centos1
192.168.85.134 centos2
192.168.85.135 centos3

修改完后,重启虚拟机用户名就会改变,重启指令reboot

以上三个步骤是每一台主机都需要操作的!!!

4.ssh免密登录

为了方便通过主机1(centos1)连接主机2(centos2),所以需要配置ssh免密登录,这里跟第一次听到这个名词的初学者解释下,ssh免密登录可以理解为带钥匙的密码锁门,通过钥匙能直接打开门,但也可以通过输入密码来完成,免密登录就相当于给每一台主机都配三把钥匙,让他们串门的时候不需要输入密码。

实现免密登录,先生成密匙,再将所有密钥发给centos1,此时centos1拥有了所有虚拟机的密钥,再通过centos1将所有人的密钥发给每个虚拟机

// 生成密匙
ssh-keygen -t rsa

// 查看密钥,会有三个文件分别是私有、公有密钥,和已知主机
cd ~/.ssh/

// 将密钥发给centos1,在所有的虚拟机上运行一遍
ssh-copy-id centos1

// 在centos1中将所有密钥分发给其他虚拟机
scp ~/.ssh/authorized_keys centos2:~/.ssh/
scp ~/.ssh/authorized_keys centos3:~/.ssh/

通过ssh来连接其他主机,如果连接成功可以通过exit来退出返回自己的主机

ssh centos2

连接成功,那么恭喜你免密登录配置完成!!\(^o^)/~


三、Hadoop集群配置

1.环境变量配置

先创建目录,这里选择再opt下创建自己的目录bigdata,bigdata中再创建四个文件夹用来划分四个部分conf、core、data、logs,logs和data文件夹下创建zookeeper方便后续使用

cd /opt
mkdir bigdata
cd bigdata
mkdir core conf data logs
mkdir -p data/zookeeper logs/zookeeper

通过FileZilla(ftp传输软件)将jdk、hadoop、Zookeeper传入到core中进行解压,删除压缩包、重命名操作

这里代码重复,就以解压jdk为例:

// 解压
tar -zxvf jdk-8u151-linux-x64.tar.gz
// 删除
rm jdk-8u151-linux-x64.tar.gz
// 重命名
mv jdk-8u151-linux-x64.tar.gz jdk

要分别解压jdk、hadoop、zookeeper三个压缩包,指令就是将jdk的压缩包名换成另外两个压缩包

再来到conf文件夹下,创建一个新的配置文件,在里面编辑环境变量,环境变量如下:

[root@centos1 core]$ vi /opt/bigdata/conf/bigdata_env.sh

export JAVA_HOME=/opt/bigdata/core/jdk

export HADOOP_HOME=/opt/bigdata/core/hadoop

export ZOOKEEPER_HOME=/opt/bigdata/core/zookeeper

export ZOO_LOG_DIR=$ZOOKEEPER_HOME/logs/

export PATH=$PATH:$ZOOKEEPER_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$JAVA_HOME/bin

输入完成,确认没有任何输入错误的地方!!!一定要确认正确,保存并退出(:wq),再进行下一步操作

将配置文件的添加到系统的环境变量中在/root/.bashrc末尾添加

vi /root/.bashrc

// 在文件末尾添加该行
source /opt/bigdata/conf/bigdata_env.sh

再执行source /root/.bashrc指令(该指令可以理解为将.bashrc中配置的内容写入到系统配置中)

(这里为部分同学说明一下/root等同于~都表示同一个文件夹,/root/.bashrc等同于~/.bashrc,可能有的老师都是用~,其实没有什么区别的)

通过指令验证,分别输入zkServer.sh、hadoop、java,只要没有弹出command not found就表示环境变量配置成功


2.Zookeeper集群配置

配置zoo.cfg文件,该文件需要通过复制它的样本文件得到

// 来到Zookeeper的配置文件存放的文件夹中
cd /opt/bigdata/core/zookeeper/conf/
// 复制并重命名得到zoo.cfg文件
cp zoo_sample.cfg zoo.cfg
// 修改zoo.cfg的配置,没有该项就进行添加,修改内容如下:
dataDir=/opt/bigdata/data/zookeeper
dataLogDir=/opt/bigdata/logs/zookeeper
server.1=centos1:2888:3888
server.2=centos2:2888:3888
server.3=centos3:2888:3888

因为是集群配置,所以其他主机也需要进行配置,也可以将配置完的文件发给其他主机,这样就不需要再重复操作2遍了

这里就直接将bigdata的文件夹发送到另外两台主机(原本上面步骤是所有主机都需要执行)

// 分发给centos2
scp -r /opt/bigdata/ centos2:/opt/
scp -r /root/.bashrc centos2:/root/
// 分发给centos3
scp -r /opt/bigdata/ centos3:/opt/
scp -r /root/.bashrc centos3:/root/

不能忘记在各主机中source /root/.bashrc文件,否则环境变量不生效

再在各个主机中的/opt/bigdata/data/zookeeper中创建文件myid写入当前主机的id

vi /opt/bigdata/data/zookeeper/myid
// 写入数字1
1

centos1中就写入1,centos2中就写入2,centos3中就写入3

各主机启动Zookeeper服务,并验证

// 启动服务
zkServer.sh start
// 查看当前状态
zkServer.sh status

当运行模式(...Mode:)出现有follower或leader即为成功


3.HDFS集群配置

来到hadoop的配置文件目录下(/opt/bigdata/core/hadoop/etc/hadoop),这里存放的是hadoop的配置文件,我们需要修改core-site.xml和hdfs-site.xml中<configuration>中的内容

core-site.xml文件修改内容如下:

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hadoop</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/bigdata/hadoop/data</value>
    </property>
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>centos1:2181,centos2:2181,centos3:2181</value>
    </property>
    <property>
        <name>hadoop.security.authorization</name>
        <value>false</value>
    </property>
    <property>
        <name>hadoop.security.authentication</name>
        <value>simple</value>
        <description>kerberos or simple</description>
    </property>
</configuration>

hdfs-site.xml文件修改内容如下:

<property>
        <name>dfs.nameservices</name>
        <value>hadoop</value>
        <discription>这是此hdfs集群的逻辑名称</discription>
    </property>

    <property>
        <name>dfs.ha.namenodes.hadoop</name>
        <value>nn1,nn2</value>
    </property>

    <property>
        <name>dfs.namenode.rpc-address.hadoop.nn1</name>
        <value>centos1:8020</value>
    </property>

    <property>
        <name>dfs.namenode.http-address.hadoop.nn1</name>
        <value>centos1:50070</value>
    </property>

    <property>
        <name>dfs.namenode.rpc-address.hadoop.nn2</name>
        <value>centos2:8020</value>
    </property>

    <property>
        <name>dfs.namenode.http-address.hadoop.nn2</name>
        <value>centos2:50070</value>
    </property>

    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://centos1:8485;centos2:8485;centos3:8485/hadoop</value>
    </property>

    <property>
        <name>dfs.ha.automatic-failover.enabled.hadoop</name>
        <value>true</value>
    </property>

    <property>
        <name>dfs.client.failover.proxy.provider.hadoop</name>
 <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>

    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/opt/bigdata/hadoop/journal</value>
    </property>

    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
    </property>

    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/root/.ssh/id_rsa</value>
    </property>

    <property>
        <name>dfs.data.dir</name>
        <value>/data/disk1,/data/disk2</value>
    </property>
    <property>
        <name>dfs.block.size</name>
        <value>134217728</value>
        <discription>block大小可根据实际情况进行设置,此处为128M</discription>
    </property>

    <property>
        <name>dfs.datanode.handler.count</name>
        <value>20</value>
    </property>

    <property>
        <name>dfs.namenode.handler.count</name>
        <value>20</value>
    </property>

    <property>
        <name>dfs.datanode.max.xcievers</name>
        <value>131072</value>
    </property>

    <property>
        <name>dfs.datanode.socket.write.timeout</name>
        <value>0</value>
    </property>

    <property>
        <name>dfs.socket.timeout</name>
        <value>180000</value>
    </property>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>

这里的core-site.xml和hdfs-site.xml是我们课上的配置,有些设置可以不同,网上也有很多关于这两个文件的每项内容解释和说明,这里也不再展开了。

再编辑slaves文件

// 编辑slaves文件
vim /opt/bigdata/core/hadoop/etc/hadoop/slaves
//修改为下面内容:
centos1
centos2
centos3

修改完要进行分发文件,分发core-site.xml、hdfs-site.xml、slaves文件给其他主机

// 分发给centos2
scp -r /opt/bigdata/core/hadoop/etc/hadoop/core-site.xml centos2:/opt/bigdata/core/hadoop/etc/hadoop/
scp -r /opt/bigdata/core/hadoop/etc/hadoop/hdfs-site.xml centos2:/opt/bigdata/core/hadoop/etc/hadoop/
scp -r /opt/bigdata/core/hadoop/etc/hadoop/slaves centos2:/opt/bigdata/core/hadoop/etc/hadoop/
// 分发给centos3
scp -r /opt/bigdata/core/hadoop/etc/hadoop/core-site.xml centos3:/opt/bigdata/core/hadoop/etc/hadoop/
scp -r /opt/bigdata/core/hadoop/etc/hadoop/hdfs-site.xml centos3:/opt/bigdata/core/hadoop/etc/hadoop/
scp -r /opt/bigdata/core/hadoop/etc/hadoop/slaves centos3:/opt/bigdata/core/hadoop/etc/hadoop/

启动服务

验证能否启动所有的journalnode(在一台机器上执行,需要ssh免密)

hadoop-daemons.sh start journalnode

 格式化zkfc,只在第一台主机(centos1)上执行

hdfs zkfc -formatZK

进入zkfc的控制台(我是这么理解的)

zkCli.sh

再输入ls /,出现[zookeeper, hadoop-ha]为成功

主namenode启动

主节点的设置是由配置文件决定的,这里配置文件中确定centos1为主节点

// 在主节点(centos1)上执行namenode的初始化
hdfs namenode -format
// 在第一台主机上启动namenode
hadoop-daemon.sh start namenode

备用namenode启动

// 第二台主机上执行,备用节点的初始化
hdfs namenode -bootstrapStandby
// 启动namenode
hadoop-daemon.sh start namenode

启动zkfc,在有namenode的主机上操作(即第一台和第二台)

hadoop-daemon.sh start zkfc

启动所有主机的DataNode

hadoop-daemons.sh start datanode

可以通过jps来观察服务是否全部启动

[root@centos1 core]$ jps
3297 QuorumPeerMain
3446 JournalNode
3580 NameNode
3741 DataNode
3853 Jps

打开网页输入192.168.85.133:50070进行验证,这里的ip是虚拟主机的ip


4.Yarn集群配置

配置yarn-site.xml和mapred-site.xml,其中mapred-site.xml需要通过复制mapred-site.xml.template得到,都在/opt/bigdata/core/hadoop/etc/hadoop/下

cp /opt/bigdata/core/hadoop/etc/hadoop/mapred-site.xml.template /opt/bigdata/core/hadoop/etc/hadoop/mapred-site.xml  

yarn-site.xml的内容如下:

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

    <property>
        <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>

    <property>
        <name>yarn.nodemanager.local-dirs</name>
        <value>/opt/bigdata/hadoop/nmdir</value> /opt/beh/data/yarn
    </property>

    <property>
        <name>yarn.nodemanager.log-dirs</name>
        <value>/opt/bigdata/hadoop/logs</value>
    </property>

    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>

    <property>
        <description>Where to aggregate logs</description>
        <name>yarn.nodemanager.remote-app-log-dir</name>
        <value>hdfs://hadoop/var/log/hadoop-yarn/apps</value>
    </property>

    <!-- Resource Manager Configs -->
    <property>
        <name>yarn.resourcemanager.connect.retry-interval.ms</name>
        <value>2000</value>
    </property>

    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>

    <property>
        <name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>

    <property>
        <name>yarn.resourcemanager.ha.automatic-failover.embedded</name>
        <value>true</value>
    </property>

    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>hadoop</value>
    </property>

    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>

    <!--在主备两台主机上不一样,备的上面是rm2-->
    <property>
        <name>yarn.resourcemanager.ha.id</name>
        <value>rm1</value>
    </property>

    <property>
        <name>yarn.resourcemanager.scheduler.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
    </property>

    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>


    <property>
        <name>yarn.resourcemanager.store.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>

    <property>
        <name>yarn.resourcemanager.zk.state-store.address</name>
        <value>centos1:2181</value>
    </property>

    <property>
        <name>yarn.app.mapreduce.am.scheduler.connection.wait.interval-ms</name>
        <value>5000</value>
    </property>

    <!-- RM1 configs -->

    <property>
        <name>yarn.resourcemanager.address.rm1</name>
        <value>centos1:23140</value>
    </property>

    <property>
        <name>yarn.resourcemanager.scheduler.address.rm1</name>
        <value>centos1:23130</value>
    </property>

    <property>
        <name>yarn.resourcemanager.webapp.https.address.rm1</name>
        <value>centos1:23189</value>
    </property>

    <property>
        <name>yarn.resourcemanager.webapp.address.rm1</name>
        <value>centos1:23188</value>
    </property>

    <property>
        <name>yarn.resourcemanager.resource-tracker.address.rm1</name>
        <value>centos1:23125</value>
    </property>

    <property>
        <name>yarn.resourcemanager.admin.address.rm1</name>
        <value>centos1:23141</value>
    </property>

    <!-- RM2 configs -->

    <property>
        <name>yarn.resourcemanager.address.rm2</name>
        <value>centos2:23140</value>
    </property>

    <property>
        <name>yarn.resourcemanager.scheduler.address.rm2</name>
        <value>centos2:23130</value>
    </property>

    <property>
        <name>yarn.resourcemanager.webapp.https.address.rm2</name>
        <value>centos2:23189</value>
    </property>

    <property>
        <name>yarn.resourcemanager.webapp.address.rm2</name>
        <value>centos2:23188</value>
    </property>

    <property>
        <name>yarn.resourcemanager.resource-tracker.address.rm2</name>
        <value>centos2:23125</value>
    </property>

    <property>
        <name>yarn.resourcemanager.admin.address.rm2</name>
        <value>centos2:23141</value>

    </property>

    <!-- Node Manager Configs -->
    <property>
        <description>Address where the localizer IPC is.</description>
        <name>yarn.nodemanager.localizer.address</name>
        <value>0.0.0.0:23344</value>
    </property>

    <property>
        <description>NM Webapp address.</description>
        <name>yarn.nodemanager.webapp.address</name>
        <value>0.0.0.0:23999</value>
    </property>

    <property>
        <name>yarn.nodemanager.local-dirs</name>
        <value>/opt/bigdata/hadoop/nodemanager/yarn/local</value>
    </property>

    <property>
        <name>yarn.nodemanager.log-dirs</name>
        <value>/opt/bigdata/hadoop/nodemanager/yarn/log</value>
    </property>

    <property>
        <name>mapreduce.shuffle.port</name>
        <value>23080</value>
    </property>

    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>centos1:2181,centos2:2181,centos3:2181</value>
    </property>

centos2中的yarn需要额外将rm1修改为rm2,如下:

<property>
        <name>yarn.resourcemanager.ha.id</name>
        <value>rm2</value>
</property>

mapred-site.xml配置内容如下:

<property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>

    <!-- configure historyserver -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>centos2:10020</value>
    </property>

    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>centos2:19888</value>
    </property>

    <!-- configure staging directory -->
    <property>
        <name>yarn.app.mapreduce.am.staging-dir</name>
        <value>/user</value>
    </property>

    <!--optimize-->
    <property>        
        <name>mapred.child.java.opts</name>        
        <value>-Xmx256m</value>    
    </property>

    <property>        
        <name>io.sort.mb</name>        
        <value>32</value>    
    </property>

    <property>        
        <name>io.sort.factor</name>        
        <value>20</value>    
    </property>    

    <property>
        <name>mapred.job.reuse.jvm.num.tasks</name>
        <value>-1</value>
    </property>

    <property>
        <name>mapreduce.reduce.shuffle.parallelcopies</name>
        <value>2</value>
    </property>

配置完配置文件后,要记得分发文件

scp -r /opt/bigdata/core/hadoop/etc/hadoop/mapred-site.xml centos2:/opt/bigdata/core/hadoop/etc/hadoop/
scp -r /opt/bigdata/core/hadoop/etc/hadoop/yarn-site.xml centos2:/opt/bigdata/core/hadoop/etc/hadoop/

在centos1上启动所有的yarn服务

start-yarn.sh

在主机centos2上,启动resourcemanager,启动历史服务器

yarn-daemon.sh start resourcemanager
// 启动历史服务器
mr-jobhistory-daemon.sh start historyserver

输入jps观察服务是否全部都已经启动

[root@centos1 hadoop]$ jps
3297 QuorumPeerMain
3921 DFSZKFailoverController
4869 Jps
3446 JournalNode
4184 NodeManager
4523 ResourceManager
3580 NameNode
3741 DataNode

总结

Hadoop集群初步就配置完成了,总结一下就是,上传并安装hadoop的压缩包,配置环境变量,使各服务的指令生效后,再配置相关配置文件,再初始化,最后启动相关服务即可。

文章可能写的有些混乱,有些细节可能没有写出来,后续可能有时间会去重新去整理一下,也很欢迎大家指出不足之处(*^▽^*)!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值