【Hadoop】Hadoop3基础

文章整理自尚硅谷B站视频:https://www.bilibili.com/video/BV1Qp4y1n7EN?t=7&p=39

〇、要点

  • 1.5.1 HDFS 架构概述
  • 1.5.2 YARN 架构概述
  • 1.5.3 MapReduce 架构概述
  • 2.1.1 Linux 模板虚拟机硬件配置
  • 2.1.2 Linux 模板虚拟机操作系统配置
  • 2.1.3.1 VMware 虚拟机IP配置
  • 2.1.3.2 Win10 VMnet8 IP配置
  • 2.1.3.3 Linux 修改IP
  • 2.1.3.3 Linux 修改主机名称
  • 2.1.3.3 Linux 修改主机名称映射
  • 2.1.3.3 Linux 创建新用户并修改权限
  • 2.3 Linux JDK 安装
  • 2.4 Hadoop 安装
  • 3.2 Hadoop 完全分布式集群搭建
  • 3.2.1.1 Linux scp 安全拷贝
  • 3.2.1.2 Linux rsync 远程同步
  • 3.2.1.3 集群分发脚本
  • 3.2.2 Linux SSH免密登录
  • 3.2.3.1 Hadoop 集群配置的位置
  • 3.2.3.2 Hadoop 核心文件的配置
  • 3.2.3.2 Hadoop 指定NameNode的地址
  • 3.2.3.2 Hadoop 指定hadoop数据测存放目录
  • 3.2.3.2 Hadoop 配置HDFS网页登录使用的静态用户
  • 3.2.3.2 Hadoop NameNode web端访问地址
  • 3.2.3.2 Hadoop SecondaryNameNode web端访问地址
  • 3.2.3.2 Hadoop 指定ResourceManager的地址
  • 3.2.4 浏览器访问HDFS界面
  • 3.2.4 Hadoop 集群崩溃的处理办法
  • 3.2.5 Hadoop 历史服务器的配置
  • 3.2.5 Hadoop 指定历史服务器端地址
  • 3.2.5 Hadoop 指定历史服务器web端地址
  • 3.2.6 Hadoop 配置日志的聚集
  • 3.2.6 Hadoop 开启日志聚集工鞥呢
  • 3.2.6 Hadoop 设置日志聚集服务器地址
  • 3.2.6 Hadoop 设置日志保留的时间
  • 3.2.7 Hadoop 各个组件的分别启动和停止
  • 3.2.8 Hadoop 集群常用脚本
  • 3.2.9 Hadoop 常用端口号
  • 3.2.10 Hadoop 常用配置文件
  • 问题1:错误: 找不到或无法加载主类 org.apache.hadoop.mapreduce.v2.app.MRAppMaster
  • 问题2:Win10 IP映射失败

一、概念

1.1 Hadoop是什么

hadoop是Apache的分布式系统基础架构,主要解决海量数据存储和分析计算的问题

1.2 Hadoop发展历史

1.3 Hadoop的三大发行版本

1.4 Hadoop的优势

  • 高可靠性:Hadoop底层维护多个数据版本,即使Hadoop某个计算元素或存储出现故障,也不会导致数据的的丢失
  • 高扩展性:在集群间分配任务数据,可方便地扩展数以千计的节点(动态增加,动弹删除)
  • 高效性:在MapReduce思想下,Hadoop是并行工作的,以加快任务处理速度
  • 高容错性:能够自动将失败的任务重新分配

1.5 Hadoop的组成

  • Hadoop1.x:Common(辅助工具)、HDFS(数据存储)、MapReduce(计算+资源调度)
  • Hadoop2.x:Common、HDFS、MapReduce(计算)、Yarn(资源调度)
  • Hadoop3.x:(在组成上没有变化)

1.5.1 HDFS架构概述

Hadoop Distributed File System,Hadoop分布式文件系统

  • NameNode(nn):记录每一个文件块存储的位置。存储文件的元数据(文件名、目录结构、属性)和每个文件的块列表和块所在的DataNode等
  • DataNode(dn):具体存储数据(每个服务器都是一个DataNode)。在本地文件系统存储块数据,以及块数据的校验和
  • SecondaryNameNode(2nn):辅助NameNode工作。每隔一段时间对NameNode元数据备份

1.5.2 Yarn架构概述

Yet Another Resource Negotiator,Hadoop的资源管理器

  • ResourceManager(RM):管理整个集群资源(内存、CPU等)
  • NodeManager(NM):管理单个节点的资源
  • ApplicationMaster(AM):管理单个任务运行的资源
  • Container:容器,相当于一台独立的服务器,里面封装了任务运行所需要的资源(内存、CPU、磁盘、网络等)

客户端可以有多个;集群上可以运行多个ApplicationMaster;每个NodeManager上可以有多个Container

1.5.3 MapReduce架构概述

  • Map:并行处理输入的数据
  • Reduce:对Map结果进行汇总

1.5.4 HDFS、Yarn、MapReduce三者的关系

1.6 大数据技术生态体系

1.7 推荐系统案例

二、环境准备

2.1 模板虚拟机准备

2.1.1 硬件

  • 自定义安装
  • Linux CentOS 7
  • 50G硬盘

2.1.2 操作系统

  • 设置时区
  • 最小化安装(选择前三个附加选项)
  • 安装位置:
    • /boot:1G(文件系统改为ext4)
    • swap:4G
    • /:45G
  • KDUMP:取消
  • root密码:123456(方便)

2.1.3 IP和主机名

2.1.3.1 虚拟机VMnet8
  • 子网IP:192.168.2.0
  • NAT网关IP:192.168.2.1
    虚拟机IP
2.1.3.2 Win10主机VMnet8
  • IP地址:192.168.2.3
  • 子网掩码:255.255.255.0
    Win10IP
2.1.3.3 Linux配置
  • 修改IP

  • 修改主机名称

    • vim /etc/hostname
    • 改为node100
  • 修改主机名称映射

    • vim /etc/hosts

    • 增加:

      192.168.2.100 node100

      192.168.2.101 node101

      192.168.2.102 node102

      192.168.2.103 node103

  • 重启

    • reboot
    • ifconfigip addr查看IP
    • hostname查看主机名
  • 安装软件

    • yum install -y epel-release
    • yum install -y net-tools
    • yum install -y vim
  • 防火墙关闭

    • systemctl stop firewalld
    • systemctl disable firewalld.service
  • 创建新用户并修改权限

    • useradd hadoop
    • passwd hadoop然后设置密码
    • vim /etc/sudoers
    • %wheel后增加:
      • hadoop ALL=(ALL) NOPASSWD:ALL
  • 重启并使用hadoop用户登录后:
    hadoop

2.2 克隆

  • 创建完整克隆
  • 修改IP
  • 修改主机名称

2.3 安装JDK

(这里在node102安装)

  • 解压:sudo tar -zxvf jdk-8u271-linux-x64.tar.gz -C /opt/module

  • 修改环境变量

    • 增加.sh文件:sudo vim /etc/profile.d/my_env.sh
     #JAVA_HOME
     export JAVA_HOME=/opt/module/jdk1.8.0_271
     export PATH=$PATH:$JAVA_HOME/bin
    
    • source /etc/profile使配置生效

    • java -version查看java版本

2.4 安装Hadoop

(这里在node102安装)

  • 解压:sudo tar -zxvf hadoop-3.2.1.tar.gz -C /opt/module/

  • 修改环境变量

    • sudo vim /etc/profile.d/my_env.sh
     #HADOOP_HOME
     export HADOOP_HOME=/opt/module/hadoop-3.2.1
     export PATH=$PATH:$HADOOP_HOME/bin
     export PATH=$PATH:$HADOOP_HOME/sbin
    
    • source /etc/profile使配置生效

    • hadoop version查看hadoop版本

三、Hadoop生产集群搭建

  • 存储模式
    • 本地:数据存储在Linux本地
    • 伪分布式:数据存储在HDFS
    • 完全分布式:数据存储在HDFS,多台服务器工作

3.1 本地模式

  • 新建文件vim /opt/module/hadoop-3.2.1/wcinput/word.txt,写入内容:

    hadoop
    flink
    kafka
    flink
    flume
    spark
    hadoop
    hadoop
    
  • 运行官方示例hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar wordcount wcinput/ ./wcoutput

  • 查看输出:

    输出

3.2 完全分布式集群

3.2.1 编写集群分发脚本xsync

3.2.1.1 scp 安全拷贝:
scp-r p d i r / pdir/ pdir/fname u s e r @ user@ user@host: p d i r / pdir/ pdir/fname
命令递归要拷贝的文件路径/名称目的地用户@主机:目的地路径/名称
  • 推:[hadoop@node102 module]$ scp -r jdk1.8.0_271/ hadoop@node103:/opt/module/
  • 拉:[hadoop@node103 opt]$ scp -r hadoop@node102:/opt/module/hadoop-3.2.1 ./module/
  • 转:[hadoop@node103 opt]$ scp -r hadoop@node102:/opt/module/* hadoop@node104:/opt/module/
3.2.1.2 rsync 远程同步
rsync-av p d i r / pdir/ pdir/fname u s e r @ user@ user@host: p d i r / pdir/ pdir/fname
命令归档拷贝/显示赋值过程要拷贝的文件路径/名称目的地用户@主机:目的地路径/名称
  • 同步:[hadoop@node102 ~]$ rsync -av /opt/module/hadoop-3.2.1/ hadoop@node103:/opt/module/hadoop-3.2.1/
3.2.1.3 xsync 集群分发脚本(放在了~/bin目录下)
#!/bin/bash

#1.判断参数个数
if [ $# -lt 1 ]
then 
        echo Not Enough Argument!
        exit;
fi

#2.遍历集群所有机器
for host in node100 node102 node103
do
        echo ==== $host ====
        #3.遍历所有目录,进行发送
        for file in $@
        do
                #4.判断文件是否存在
                if [ -e $file ]
                        then
                                #5.获取父目录
                                pdir=$(cd -P $(dirname $file) ; pwd)
                                #6.获取当前目录的名称
                                fname=$(basename $file)
                                ssh $host "mkdir -p $pdir"
                                rsync -av $pdir/$fname $host:$pdir
                        else
                                echo $file does not exists!
                fi
        done
done
  • 写完后直接执行(同步bin目录):xsync bin/

    直接执行

  • (同步环境变量,需要sudo):sudo ~/bin/xsync /etc/profile.d/my_env.sh

    同步环境变量

    切换到node103,同步成功:

    node103

    同步后记得source:

    source

3.2.2 SSH免密登录

  • https://blog.csdn.net/Tiezhu_Wang/article/details/113771406

  • 或者(在node102中):

    • 使用ls -al查看隐藏文件(无需此步)
    • ssh-keygen -t rsa生成秘钥
    • ssh-copy-id node103复制node102的id到node103

    完成后即可在node102中免密访问node103,在node103中同样执行此步,即可免密访问node102,同步时也无需输入密码。(node100同理)

3.2.3 集群配置

3.2.3.1 配置位置:
node102node103node100
HDFSNameNode
DataNode
DataNodeSecondaryNameNode
DataNode
YARNNodeManagerResourceManager
NodeManager
NodeManager
3.2.3.2 配置核心文件

路径:/opt/module/hadoop-3.2.1/etc/hadoop

  • core-site.xml

    <configuration>
            <!-- 指定NameNode的地址 -->
            <property>
                    <name>fs.defaultFS</name>
                    <value>hdfs://node102:8020</value>
            </property>
            <!-- 指定hadoop数据的存放目录 -->
            <property>
                    <name>hadoop.tmp.dir</name>
                    <value>/opt/module/hadoop-3.2.1/data</value>
            </property>
        	<!-- 配置HDFS网页登录使用的静态用户为hadoop -->
        	<property>
        			<name>hadoop.http.staticuser.user</name>
                	<value>hadoop</value>
        	</property>
    </configuration>
    
  • hdfs-site.xml

    <configuration>
            <!-- nn web端访问地址 -->
            <property>
                    <name>dfs.namenode.http-address</name>
                    <value>node102:9870</value>
            </property>
            <!-- 2nn web端访问地址 -->
            <property>
                    <name>dfs.namenode.secondary.http-address</name>
                    <value>node100:9868</value>
            </property>
    </configuration>
    
  • yarn-site.xml

    <configuration>
            <!-- 指定MR走shuffle -->
            <property>
                    <name>yarn.nodemanager.aux-services</name>
                    <value>mapreduce_shuffle</value>
            </property>
            <!-- 指定ResourceManager的地址 -->
            <property>
                    <name>yarn.resourcemanager.hostname</name>
                    <value>node103</value>
            </property>
    </configuration>
    
    
  • mapre-site.xml

    <configuration>
            <!-- 指定MR运行在YARN上 -->
            <property>
                    <name>mapreduce.framework.name</name>
                    <value>yarn</value>
            </property>
    </configuration>
    
  • 配置后分发

    [hadoop@node102 etc]$ xsync /opt/module/hadoop-3.2.1/etc/hadoop/
    

3.2.4 启动集群并测试

  • 配置workers:vim /opt/module/hadoop-3.2.1/etc/hadoop/workers

    node102
    node103
    node100
    

    配置后分发:xsync workers

  • 启动集群

    • 初始化(第一次启动):hdfs namenode -format

      初始化

    • 启动集群:start-dfs.sh(需要配好环境变量)

      启动

      • node102:

        node102

      • node103:

        node103

      • node100:

        node100

    • 浏览器访问192.168.2.102:9870(需要关闭节点的防火墙,hostname访问无效就试试IP访问)

      9870

  • 启动Yarn:(在 ResoureManager 运行的机器上启动,这里是node103)start-yarn.sh

    • 启动后node103运行了ResourceManager,其他节点运行NodeManager

    • 访问192.168.2.103:8088

      8088

  • 基本测试

    [hadoop@node102 ~]$ hdfs dfs -mkdir /wcinput
    [hadoop@node102 ~]$ hdfs dfs -ls /
    Found 1 items
    drwxr-xr-x   - hadoop supergroup          0 2021-04-26 21:18 /wcinput
    [hadoop@node102 ~]$ hdfs dfs -put input/word.txt /wcinput
    2021-04-26 21:20:47,395 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
    [hadoop@node102 ~]$ hdfs dfs -cat /wcinput/*
    2021-04-26 21:21:12,593 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
    hadoop
    spark
    flink
    hadoop
    flink
    hadoop
    flume
    
  • 集群崩溃的处理办法

    • 关闭所有服务
    • 删除每个集群的datalogs目录(删除历史数据)
    • 格式化hdfs namenode -format
    • 启动后即可正常使用

3.2.5 配置历史服务器

为了查看程序的历史运行情况

  • 配置mapred-site.xml

    <!-- 历史服务器端地址 -->
    <property>
    	<name>mapreduce.jobhistory.address</name>
        <value>node102:10020</value>
    </property>
    <!-- 历史服务器web端地址 -->
    <property>
    	<name>mapreduce.jobhistory.webapp.address</name>
        <value>node102:19888</value>
    </property>
    
  • 配置完分发:xsync mapred-site.xml

  • 启动hdfs(node102)、yarn(node103)后,启动历史服务器(node102):

    • mapred --daemon start historyserver
      在这里插入图片描述
  • 执行示例WC

     hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar wordcount /wcinput /wcoutput
    
  • 访问192.168.2.103:8088

    • 可以在这个位置查看历史任务

      在这里插入图片描述

    • 点击history后跳转,可查看到历史任务详情

      在这里插入图片描述

3.2.6 配置日志的聚集

应用运行完成之后,将程序运行日志信息上传到HDFS上

  • 配置yarn-site.xml

     <!-- 开启日志聚集功能 -->
     <property>
     	<name>yarn.log-aggregation-enable</name>
         <value>true</value>
     </property>
     <!-- 设置日志聚集服务器地址 -->
     <property>
     	<name>yarn.log.server.url</name>
         <value>http://node102:19888/jobhistory/logs</value>
     </property>
     <!-- 设置日志保留时间为7天 -->
     <property>
     	<name>yarn/log-aggregation.retain-seconds</name>
         <value>604800</value>
     </property>
    
  • 修改后分发

  • 关闭historyserver:mapred --daemon stop historyserver

  • 重启yarn:先stop再start

  • 启动historyserver

  • 重新运行一个任务,即可在node103:8088-history-logs查看到日志信息

    在这里插入图片描述
    日志信息:
    在这里插入图片描述

3.2.7 各个服务组件的逐一启动和停止

  • HDFS组件

    hdfs --daemon start(stop) namenode
    hdfs --daemon start(stop) datanode
    hdfs --daemon start(stop) secondarynamenode
    
  • YARN组件

    yarn --daemon start(stop) resourcemanager
    yarn --daemon start(stop) nodemanager
    

3.2.8 编写Hadoop集群常用脚本

3.2.8.1 Hadoop集群启停脚本(包括HDFS、YARN、HistoryServer):myhadoop.sh
#!/bin/bash

if [ $# -lt 1 ]
then 
	echo "No Args Input..."
	exit;
fi

case $1 in
"start")
		echo "====== 启动Hadoop集群 ======"
		
		echo "------ 启动HDFS ------"
		ssh node102 "/opt/module/hadoop-3.2.1/sbin/start-dfs.sh"
		echo "------ 启动YARN ------"
		ssh node103 "/opt/module/hadoop-3.2.1/sbin/start-yarn.sh"
		echo "------ 启动HistoryServer ------"
		ssh node102 "/opt/module/hadoop-3.2.1/bin/mapred --daemon start historyserver"
;;
"stop")
		echo "====== 关闭Hadoop集群 ======"
		
		echo "------ 关闭HistoryServer ------"
		ssh node102 "/opt/module/hadoop-3.2.1/bin/mapred --daemon stop historyserver"
		echo "------ 关闭YARN ------"
		ssh node103 "/opt/module/hadoop-3.2.1/sbin/stop-yarn.sh"
		echo "------ 关闭HDFS ------"
		ssh node102 "/opt/module/hadoop-3.2.1/sbin/stop-dfs.sh"
;;
*)
	echo "Input Args Error..."
;;
esac
  • 修改权限:chmod 777 myhadoop.sh
  • 使用:
    在这里插入图片描述
    在这里插入图片描述
3.2.8.2 查看三台服务器的Java进程脚本:jpsall
#!/bin/bash

for host in node102 node103 node100
do
        echo ====== $host ======
        ssh $host jps
done
  • 修改权限:chmod 777 jpsall
  • 使用:
    在这里插入图片描述

3.2.9 常用端口号

  • hadoop3.x

    名称端口
    HDFS NameNode 内部通讯端口8020/9000/9820
    HDFS NameNode 对用户的查询端口9870
    YARN 查看任务运行情况的端口8088
    历史服务器19888
  • hadoop2.x

    名称端口
    HDFS NameNode 内部通讯端口8020/9000
    HDFS NameNode 对用户的查询端口50070
    YARN 查看任务运行情况的端口8088
    历史服务器19888

3.2.10 常用配置文件

  • hadoop3.x
    • core-site.xml
    • hdfs-site.xml
    • yarn-site.xml
    • mapred-site.xml
    • workers
  • hadoop2.x
    • core-site.xml
    • hdfs-site.xml
    • yarn-site.xml
    • mapred-site.xml
    • slaves

3.2.11 集群时间同步

服务器能连接外网时,不需要时间同步

四、错误和解决方案

  • 运行示例MR时,错误: 找不到或无法加载主类 org.apache.hadoop.mapreduce.v2.app.MRAppMaster

     [hadoop@node102 input]$ hadoop jar /opt/module/hadoop-3.2.1/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar wordcount /wcinput /wcoutput
     2021-04-27 10:05:19,761 INFO client.RMProxy: Connecting to ResourceManager at node103/192.168.2.103:8032
     2021-04-27 10:05:21,257 INFO mapreduce.JobResourceUploader: Disabling Erasure Coding for path: /tmp/hadoop-yarn/staging/hadoop/.staging/job_1619488633583_0003
     2021-04-27 10:05:21,388 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
     2021-04-27 10:05:22,103 INFO input.FileInputFormat: Total input files to process : 1
     2021-04-27 10:05:22,156 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
     2021-04-27 10:05:22,373 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
     2021-04-27 10:05:22,537 INFO mapreduce.JobSubmitter: number of splits:1
     2021-04-27 10:05:22,679 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
     2021-04-27 10:05:22,789 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1619488633583_0003
     2021-04-27 10:05:22,789 INFO mapreduce.JobSubmitter: Executing with tokens: []
     2021-04-27 10:05:23,801 INFO conf.Configuration: resource-types.xml not found
     2021-04-27 10:05:23,801 INFO resource.ResourceUtils: Unable to find 'resource-types.xml'.
     2021-04-27 10:05:24,256 INFO impl.YarnClientImpl: Submitted application application_1619488633583_0003
     2021-04-27 10:05:25,482 INFO mapreduce.Job: The url to track the job: http://node103:8088/proxy/application_1619488633583_0003/
     2021-04-27 10:05:25,483 INFO mapreduce.Job: Running job: job_1619488633583_0003
     2021-04-27 10:05:48,327 INFO mapreduce.Job: Job job_1619488633583_0003 running in uber mode : false
     2021-04-27 10:05:48,328 INFO mapreduce.Job:  map 0% reduce 0%
     2021-04-27 10:05:51,838 INFO mapreduce.Job: Job job_1619488633583_0003 failed with state FAILED due to: Application application_1619488633583_0003 failed 2 times due to AM Container for appattempt_1619488633583_0003_000002 exited with  exitCode: 1
     Failing this attempt.Diagnostics: [2021-04-27 10:05:47.137]Exception from container-launch.
     Container id: container_1619488633583_0003_02_000001
     Exit code: 1
     
     [2021-04-27 10:05:47.189]Container exited with a non-zero exit code 1. Error file: prelaunch.err.
     Last 4096 bytes of prelaunch.err :
     Last 4096 bytes of stderr :
     错误: 找不到或无法加载主类 org.apache.hadoop.mapreduce.v2.app.MRAppMaster
     
     
     [2021-04-27 10:05:47.190]Container exited with a non-zero exit code 1. Error file: prelaunch.err.
     Last 4096 bytes of prelaunch.err :
     Last 4096 bytes of stderr :
     错误: 找不到或无法加载主类 org.apache.hadoop.mapreduce.v2.app.MRAppMaster
     
     
     For more detailed output, check the application tracking page: http://node103:8088/cluster/app/application_1619488633583_0003 Then click on links to logs of each attempt.
     . Failing the application.
     2021-04-27 10:06:26,946 INFO mapreduce.Job: Counters: 0
    
    • hadoop classpath

    • 将输出的内容添加到yarn-site.xml中,name为yarn.application.classpath

       <property>
           <name>yarn.application.classpath</name>
           <value>/opt/module/hadoop-3.2.1/etc/hadoop:/opt/module/hadoop-3.2.1/share/hadoop/common/lib/*:/opt/module/hadoop-3.2.1/share/hadoop/common/*:/opt/module/hadoop-3.2.1/share/hadoop/hdfs:/opt/module/hadoop-3.2.1/share/hadoop/hdfs/lib/*:/opt/module/hadoop-3.2.1/share/hadoop/hdfs/*:/opt/module/hadoop-3.2.1/share/hadoop/mapreduce/lib/*:/opt/module/hadoop-3.2.1/share/hadoop/mapreduce/*:/opt/module/hadoop-3.2.1/share/hadoop/yarn:/opt/module/hadoop-3.2.1/share/hadoop/yarn/lib/*:/opt/module/hadoop-3.2.1/share/hadoop/yarn/*</value>
       </property>
      
    • 重启YARN,即可成功运行MR

  • Win10 IP映射失败

    • 修改C:\Windows\System32\drivers\etc/hosts文件(管理员模式打开),增加如下内容:

      192.168.2.100	node100
      192.168.2.101	node101
      192.168.2.102	node102
      192.168.2.103	node103
      192.168.2.104	node104
      
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬金砖的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值