Hadoop详细入门知识

这篇具有很好参考价值的文章主要介绍了Hadoop详细入门知识。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Hadoop

第一章 大数据的概述

1.1 大数据的概念

最近几年,IT行业最火的名词中,少不了"大数据"、“人工智能”、“云计算”、“物联网”、"区块链"等等这些名词。针对于**“大数据”**这个名词,现在更是全国老百姓,老少皆知的一个词语。但是什么是大数据,除了IT行业的专业人士外,其他人乃至其他行业的人,除了能说出"数据量大"之外,好像真的不能再更深层次的解释了。那么我们来看看下面几个权威机构给出的解释。

**维基百科 **给出的定义:

数据规模巨大到无法通过人工在合理的时间内达到截取,管理,处理并整理成为人类所解读的信息。

**麦肯锡全球研究所 **给出的定义:

一种规模大到在获取、存储、管理、分析方面都大大超出了传统数据库软件工具能力范围的数据集合。

**研究机构 **高德纳(Gartner)给出的定义:

"大数据"是需要新的处理模式才能具有更强的决策力、洞察发现力和流程优化能力来适应海量、高增长率和多样化的信息资产

概念总结:

海量数据,具有高增长率、数据类型多样化、一定时间内无法使用常规软件工具进行捕捉、管理和处理的数据集合。 

1.2 大数据的特征

早在1980年,著名未来学家托夫勒在其所著的《第三次浪潮》中就热情地将“大数据”称颂为“第三次浪潮的华彩乐章”。《自然》杂志在2008年9月推出了名为“大数据”的封面专栏。从2009年开始“大数据”才成为互联网技术行业中的热门词汇。最早应用“大数据”的是世界著名的管理咨询公司麦肯锡公司,它看到了各种网络平台记录的个人海量信息具备潜在的商业价值,于是投入大量人力物力进行调研, 对“大数据”进行收集和分析的设想,在2011年6月发布了关于“大数据”的报告,该报告对“大数据”的影响、关键技术和应用领域等都进行了详尽的分析。麦肯锡的报告得到了金融界的高度重视,而后逐渐受到了各行各业关注。 那么大数据到底有什么特征呢?我们怎么去理解大数据呢?有专业人士总结了4V说法,也有相关机构总结了5V说法,甚至6V说法。不管哪种说法,下面四个特征,是大家普遍认可的。

  • Volume : 巨大的数据量
  • Variety : 数据类型多样化
    • 结构化的数据 : 即具有固定格式和有限长度的数据
    • 半结构化的数据 : 是一些xml或者html格式的数据
    • 非结构化的数据 : 现在非结构化的数据越来越多,就是不定长、无固定格式的数据,例如网页、语音、视频等
  • Velocity : 数据增长速度快
  • Value : 价值密度低,商业价值高

1.3 大数据的应用场景

有不了解大数据的人会问:**大数据能做啥?**问的好。

大数据本身是一个抽象的概念, 对当前无论是企业还是政府、或是高校等单位来说,是一个面临着数据无法存储、无法计算的状态的形容词。

那么大数据可以做什么呢?

在海量的各种各样类型的价值密度低的数据中,我们要进行的是:数据采集,数据存储,数据清洗,数据分析,数据可视化。

简单一句话,就是大数据让数据产生各种"价值"。可以说,大数据的核心作用就是"数据价值化",这个过程就是大数据要做的主要事情。那么就可以概括成:

- 记录已经发生的一切
- 描述正在发生的一切
- 预测将要发生的一切

大数据技术的战略意义不在于掌握庞大的数据信息,而在于对这些含有意义的数据进行专业化处理

现在已经应用"大数据"的案例有:

- 预测犯罪
- 预测流感的爆发
- 预测选举
- 根据手机定位和交通数据,规划城市
- 根据库存和需求,实时调价
- 推动医疗信息化发展,远程医疗

1.4 大数据的发展前景

大数据技术目前正处在落地应用的初期,从大数据自身发展和行业发展的趋势来看,大数据未来的前景还是不错的,具体原因有以下几点:

- 大数据本身的价值体现,
	本身的数据价值化就会开辟出很大的市场空间。目前在互联网领域,大数据技术已经得到了较为广泛的应用。 大数据造就了新兴行业
	
- 大数据推动了科技领域的发展
	不仅体现在互联网领域,还体现在金融、教育、医疗等诸多领域,尤其是现在的人工智能。
	
- 大数据产业链的形成
	经过近些年的发展,大数据已经初步形成了一个较为完整的产业链,包括数据采集、整理、传输、存储、分析、呈现和应用,众多企业开始参与到大数据产业链中,并形成了一定的产业规模,相信随着大数据的不断发展,相
	关产业规模会进一步扩大。
	
- 国家大力扶持大数据行业的发展

第二章 Hadoop概述

2.1 为什么要用hadoop

现在的我们,生活在数据大爆炸的年代。2020年,全球的数据总量达到44ZB,经过单位换算后,至少在440亿TB以上,也就是说,全球每人一块1TB的硬盘都存储不下。

扩展: 数据大小单位,从小到大分别是: byte、kb、mb、Gb、Tb、PB、EB、ZB、DB、NB...
单位之间的转换都是满足1024

一些数据集的大小更远远超过了1TB,也就是说,数据的存储是一个要解决的问题。同时,硬盘技术也面临一个技术瓶颈,就是硬盘的传输速度(读数据的速度)的提升远远低于硬盘容量的提升。我们看下面这个表格:

Hadoop详细入门知识

可以看到,容量提升了将近1000倍,而传输速度才提升了20倍,读完一个硬盘的所需要的时间相对来说,更长更久了(已经违反了数据价值的即时性)。读数据都花了这么长时间,更不用说写数据了。

对于如何提高读取数据的效率,我们已经想到解决的方法了,那就是将一个数据集存储到多个硬盘里,然后并行读取。比如1T的数据,我们平均100份存储到100个1TB硬盘上,同时读取,那么读取完整个数据集的时间用不上两分钟。至于硬盘剩下的99%的容量,我们可以用来存储其他的数据集,这样就不会产生浪费。解决读取效率问题的同时,我们也解决了大数据的存储问题。

但是,我们同时对多个硬盘进行读/写操作时,又有了新的问题需要解决:

1、硬件故障问题。一旦使用多个硬件,相对来说,个别硬件产生故障的几率就高,为了避免数据丢失,最常见的做法就是复制(replication):文件系统保存数据的多个复本,一旦发生故障,就可以使用另外的复本。

2、读取数据的正确性问题。大数据时代的一个分析任务,就需要结合大部分数据来共同完成分析,因此从一个硬盘上读取的数据要与从其他99个硬盘上读取的数据结合起来使用。那么,在读取过程中,如何保证数据的正确性,就是一个很大的挑战。

针对于上述几个问题,Hadoop为我们提供了一个可靠的且可扩展的存储和分析平台,此外,由于Hadoop运行在商用硬件上且是开源的,因此Hadoop的使用成本是比较低了,在用户的承受范围内。

2.2 Hadoop的简要介绍

Hadoop是Apache基金会旗下一个开源的分布式存储和分析计算平台,使用java语言开发,具有很好的跨平台性,可以运行在商用(廉价)硬件上,用户无需了解分布式底层细节,就可以开发分布式程序,充分使用集群的高速计算和存储

Apache lucene是一个应用广泛的文本搜索系统库。该项目的创始人道格·卡丁在2002年带领团队开发该项目中的子项目Apache Nutch,想要从头打造一个网络搜索引擎系统,在开发的过程中,发现了两个问题,一个是硬件的高额资金投入,另一个是存储问题。

2003年和2004年Google先后发表的《GFS》和《MapReduce》论文,给这个团队提供了灵感,并进行了实现,于是NDFS(Nutch分布式文件系统)和MapReduce相继问世。2006年2月份,开发人员将NDFS和MapReduce移出Nutch形成一个独立的子项目,命名为Hadoop(该名字据Doug Cutting所说,是借用了他的孩子给毛绒玩具取得名字)。

2.3 谷歌的三篇论文

- 2003年发表的《GFS》
	基于硬盘不够大、数据存储单份的安全隐患问题,提出的分布式文件系统用于存储的理论思想。
	· 解决了如何存储大数据集的问题

- 2004年发表的《MapReduce》
 	基于分布式文件系统的计算分析的编程框架模型。移动计算而非移动数据,分而治之。
	· 解决了如何快速分析大数据集的问题

- 2006年发表的《BigTable》
	针对于传统型关系数据库不适合存储非结构化数据的缺点,提出了另一种适合存储大数据集的解决方案

2.4 Hadoop的发展历史

Hadoop详细入门知识

2.5 Hadoop的组成部分

hadoop2.0以后的四个模块:
    - Hadoop Common:Hadoop模块的通用组件
    - Hadoop Distributed File System:分布式文件系统
    - Hadoop YARN:作业调度和资源管理框架
    - Hadoop MapReduce:基于YARN的大型数据集并行计算处理框架

hadoop3.0新扩展的两个模块:
    - Hadoop Ozone:Hadoop的对象存储机制 
    - Hadoop Submarine:Hadoop的机器学习引擎

2.6. Hadoop的生态系统

Hadoop详细入门知识

Hadoop详细入门知识
Hadoop详细入门知识

第三章 Hadoop集群安装

3.1 集群规划

集群规划 规划
操作系统 Mac、Windows
虚拟软件 Parallels Desktop(Mac)、VMWare(Windows)
虚拟机 主机名: qianfeng01, IP地址: 192.168.10.101
主机名: qianfeng02, IP地址: 192.168.10.102
主机名: qianfeng03, IP地址: 192.168.10.103
软件包上传路径 /root/softwares
软件包安装路径 /usr/local
JDK Jdk-8u221-linux-x64.tar.gz
Hadoop hadoop-2.7.6.tar.gz
用户 root
3.1.1 服务器规划

因为搭建一个服务器集群需要至少一主两从,一共三台服务器,而且这三台服务器上很多配置和环境变量是重复的,所以我们可以配置好一些文件,省去我们后期的操作,主要包括下面的配置和环境:

  • 安装对应的jdk和hadoop(hadoop有1x、2x、3x),并且分别配置jdk和hadoop的环境变量,并且使其环境变量生效
  • 关闭防火墙,并关闭防火墙的自启动
  • 确保/etc/hosts文件配置了IP和hosts的映射关系
  • 确保三台机器的网络配置通畅(NAT模式、静态IP、主机名的配置),我们克隆服务器的时候,mac地址会重复,因此我们需要重新生成一下mac地址,这里要关闭DHCP(动态主机配置协议)
  • 确保配置了三台机器的免密登录认证,生成自己的公钥和私钥
  • 确保所有的机器时间同步,虚拟机关机的时候,时间会静止
  • 新的centos虚拟机上只有vi,没有vim,介意的可以安装vim,vim用户体验更好一点。centos安装:yum -y install vim*;ubuntu安装:sudo apt-get install vim-gtk
3.1.2 安装三台虚拟机

使用VMware安装三台centos,其中第一台需要手动创建,二三台直接复制第一台即可(右键虚拟机- - -管理- - -克隆),然后需要更改网络配置,随机生成新的mac地址,使用桥接模式配置网络

  • 需要保证可以相互ping通,在同一子网段下
    Hadoop详细入门知识
    使用ssh工具连接三台服务器,这里使用FinalShell
    Hadoop详细入门知识

3.2 安装JDK

3.2.1 检查一下是否已经安装过或者系统内置JDK,如果有内置的,将其卸载
[root@qianfeng01 ~]# rpm -qa | grep jdk     				# 如果有,请卸载
[root@qianfeng01 ~]# rpm -e xxxxxxxx --nodeps      	# 将查询到的内置jdk强制卸载
3.2.2 上传jdk1.8和hadoop2.6.7
将jdk-8u221-linux-x64.tar.gz上传到/root目录中
3.2.3 解压jdk和hadoop到/usr/local/下
[root@qianfeng01 ~]# tar -zxvf jdk-8u221-linux-x64.tar.gz -C /usr/local
3.2.4 更名jdk和hadoop
[root@qianfeng01 ~]# cd /usr/local
[root@qianfeng01 local]# mv jdk1.8.0_221/  jdk
3.2.5 配置Jdk的环境变量:/etc/profile
[root@qianfeng01 local]# vi /etc/profile
.........省略...........
#jdk environment
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
3.2.6 使当前窗口生效
[root@qianfeng01 local]# source /etc/profile
3.2.7 验证jdk环境
[root@qianfeng01 local]# java -version
[root@qianfeng01 local]# javac	

Hadoop详细入门知识

3.3. 完全分布式环境需求及安装

1. 三台机器的防火墙必须是关闭的
2. 确保三台机器的网络配置通常(NAT模式、静态IP、主机名的配置)
3. 确保/etc/hosts文件配置了IP和hosts的映射关系
4. 确保配置了三台机器的免密登录认证
5. 确保所有的机器时间同步
6. JDK和Hadoop的环境变量配置
3.3.1 关闭防火墙
systemctl stop firewalld #关闭防火墙
systemctl disable firewalld
systemctl stop NetworkManager
systemctl disable NetworkManager
systemctl disable firewalld.service #关闭防火墙自启动

#最好也把selinux关闭掉,这是linux系统的一个安全机制,进入文件中将SELINUX设置为disabled
[root@qianfeng01 ~]# vi /etc/selinux/config
.........
SELINUX=disabled			
.........
3.3.2 静态IP和主机名配置
--1. 配置静态IP(确保NAT模式)
[root@qianfeng01 ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33
............
BOOTPROTO=static			    # 将dhcp改为static,固定主机ip和主机名的映射
............
ONBOOT=yes								# 将no改为yes
IPADDR=192.168.10.101			# 添加IPADDR属性和ip地址
PREFIX=24									# 添加NETMASK=255.255.255.0或者PREFIX=24	
GATEWAY=192.168.10.2			# 添加网关GATEWAY
DNS1=114.114.114.114            # 添加DNS1和备份DNS
DNS2=8.8.8.8

--2. 重启网络服务
[root@qianfeng01 ~]# systemctl restart network
或者
[root@qianfeng01 ~]# service network restart

--3. 修改主机名(如果修改过,请略过这一步)
[root@localhost ~]# hostnamectl set-hostname qianfeng01
或者
[root@localhost ~]# vi /etc/hostname
qianfeng01
3.3.3 配置/etc/hosts文件
[root@qianfeng01 ~]#  vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.10.101 qianfeng01  #添加本机的静态IP和本机的主机名之间的映射关系 
192.168.10.102 qianfeng02
192.168.10.103 qianfeng03
3.3.4 免密登录认证
-1. 使用rsa加密技术,生成公钥和私钥。一路回车即可
[root@qianfeng01 ~]# cd ~
[root@qianfeng01 ~]# ssh-keygen -t rsa	

-2. 进入~/.ssh目录下,使用ssh-copy-id命令
[root@qianfeng01 ~]# cd ~/.ssh			
[root@qianfeng01 .ssh]# ssh-copy-id  root@qianfeng01

-3. 进行验证	
[hadoop@qianfeng01 .ssh]# ssh qianfeng01
#下面的第一次执行时输入yes后,不提示输入密码就对了
[hadoop@qianfeng01 .ssh]# ssh localhost
[hadoop@qianfeng01 .ssh]# ssh 0.0.0.0

注意:三台机器提前安装好的情况下,需要同步公钥文件。如果使用克隆技术。那么使用同一套密钥对就方便多了。

Hadoop详细入门知识

3.3.5 时间同步
# 1 选择集群中的某一台机器作为时间服务器,例如qianfeng01
# 2 保证这台服务器安装了ntp.x86_64。
# 3 保证ntpd 服务运行......
[root@qianfeng01 ~]# sudo service ntpd start
# 	开机自启动:
[root@qianfeng01 ~]# chkconfig ntpd on
	
# 4 配置相应文件:
[root@qianfeng01 ~]# vi /etc/ntp.conf
	
	# Hosts on local network are less restricted.
	# restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
  # 添加集群中的网络段位
	restrict 192.168.10.0 mask 255.255.255.0 nomodify notrap

	# Use public servers from the pool.ntp.org project.
	# Please consider joining the pool (http://www.pool.ntp.org/join.html).
	# server 0.centos.pool.ntp.org iburst    注释掉
	# server 1.centos.pool.ntp.org iburst	   注释掉
	# server 2.centos.pool.ntp.org iburst    注释掉
	# server 3.centos.pool.ntp.org iburst    注释掉
	server 127.127.1.0     -master作为服务器
# 5 其他机器要保证安装ntpdate.x86_64

# 6 其他机器要使用root定义定时器
*/1 * * * * /usr/sbin/ntpdate -u qianfeng01 
3.3.6 Hadoop安装与环境变量配置
# 1. 上传和解压两个软件包
[root@qianfeng01 ~]# tar -zxvf jdk-8u221-linux-x64.tar.gz -C /usr/local/
[root@qianfeng01 ~]# tar -zxvf hadoop-2.7.6.tar.gz -C /usr/local/

# 2. 进入local里,给两个软件更名
[root@qianfeng01 ~]# cd /usr/local/
[root@qianfeng01 local]# mv 1.8.0_221/  jdk
[root@qianfeng01 local]# mv hadoop-2.7.6/ hadoop

# 3. 配置环境变量
[hadoop@qianfeng01 local]# vi /etc/profile

.....省略...........

#java environment
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH

#hadoop environment
export HADOOP_HOME=/usr/local/hadoop
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

3.4. Hadoop的配置文件

3.4.1. 概述
我们需要通过配置若干配置文件,来实现Hadoop集群的配置信息
(这里Hadoop2.x和3.x配置信息略有不同,本文主要以2.x为主)。需要配置的文件有:

hadoop-env.sh
yarn-env.sh
core-site.xml
hdfs-site.xml
mapred-site.xml
yarn-site.xml

在Hadoop安装完成后,会在$HADOOP_HOME/share路径下,有若干个*-default.xml文件,
这些文件中记录了默认的配置信息。同时,在代码中,我们也可以设置Hadoop的配置信息。
这些位置配置的Hadoop,优先级为: 代码设置 > *-site.xml > *-default.xml
集群规划:
+--------------+---------------------+
|     Node     | Applications        |
+--------------+---------------------+
|  qianfeng01  | NameNode            |
|              | DataNode            |
|              | ResourceManager     |
|              | NodeManagere        |
+--------------+---------------------+
|  qianfeng02  | SecondaryNameNode   |
|              | DataNode            |
|              | NodeManager         |
+--------------+---------------------+
|  qianfeng03  | DataNode            |
|              | NodeManager         |
+--------------+---------------------+
3.4.2. core-site.xml
[root@qianfeng01 ~]# cd $HADOOP_HOME/etc/hadoop
[root@qianfeng01 hadoop]# vi core-site.xml
<configuration>
    <!-- hdfs的地址名称:schame,ip,port-->
    <!-- 在Hadoop1.x的版本中,默认使用的端口是9000。
    在Hadoop2.x的版本中,默认使用端口是8020 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://qianfeng01:8020</value>
    </property>
    <!-- hdfs的基础路径,被其他属性所依赖的一个基础路径 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/usr/local/hadoop/tmp</value>
    </property>
</configuration>
3.4.3. hdfs-site.xml
[root@qianfeng01 hadoop]# vi hdfs-site.xml
<configuration>
    <!-- namenode守护进程管理的元数据文件fsimage存储的位置-->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file://${hadoop.tmp.dir}/dfs/name</value>
    </property>
    <!-- 确定DFS数据节点应该将其块存储在本地文件系统的何处-->
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file://${hadoop.tmp.dir}/dfs/data</value>
    </property>
    <!-- 块的副本数-->
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <!-- 块的大小(128M),下面的单位是字节-->
    <property>
        <name>dfs.blocksize</name>
        <value>134217728</value>
    </property>
    <!-- secondarynamenode守护进程的http地址:主机名和端口号。参考守护进程布局-->
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>qianfeng02:50090</value>
    </property>
  	<!-- namenode守护进程的http地址:主机名和端口号。参考守护进程布局-->
	<property>
  	  <name>dfs.namenode.http-address</name>
  	  <value>qianfeng01:50070</value>
	</property>  
</configuration>
3.4.4. mapred-site.xml
[root@qianfeng01 hadoop]# cp mapred-site.xml.template  mapred-site.xml
[root@qianfeng01 hadoop]# vi mapred-site.xml
<configuration>
    <!-- 指定mapreduce使用yarn资源管理器-->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <!-- 配置作业历史服务器的地址-->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>qianfeng01:10020</value>
    </property>
    <!-- 配置作业历史服务器的http地址-->
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>qianfeng01:19888</value>
    </property>
</configuration>
3.4.5 yarn-site.xml
[root@qianfeng01 hadoop]# vi yarn-site.xml
<configuration>
    <!-- 指定yarn的shuffle技术-->
    <property>
        <name>yarn.nodemanager.aux-services</name>
       <value>mapreduce_shuffle</value>
    </property>
    <!-- 指定resourcemanager的主机名-->
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>qianfeng01</value>
    </property> 
    <!--下面的可选-->
    <!--指定shuffle对应的类 -->
	<property> 
	<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
     <value>org.apache.hadoop.mapred.ShuffleHandler</value> 
	</property>

	<!--配置resourcemanager的内部通讯地址-->
	<property>
	<name>yarn.resourcemanager.address</name>
	<value>qianfeng01:8032</value>
	</property>

	<!--配置resourcemanager的scheduler的内部通讯地址-->
	<property>
	<name>yarn.resourcemanager.scheduler.address</name>
	<value>qianfeng01:8030</value>
	</property>

	<!--配置resoucemanager的资源调度的内部通讯地址-->
	<property>
	<name>yarn.resourcemanager.resource-tracker.address</name>
	<value>qianfeng01:8031</value>
	</property>

	<!--配置resourcemanager的管理员的内部通讯地址-->
	<property>
	<name>yarn.resourcemanager.admin.address</name>
	<value>qianfeng01:8033</value>
	</property>

	<!--配置resourcemanager的web ui 的监控页面-->
	<property>
	<name>yarn.resourcemanager.webapp.address</name>
	<value>qianfeng01:8088</value>
	</property>
</configuration>
3.4.6 hadoop-env.sh
[root@qianfeng01 hadoop]# vi hadoop-env.sh
# The java implementation to use.
export JAVA_HOME=/usr/local/jdk
3.4.7 yarn-env.sh
[root@qianfeng01 hadoop]# vi yarn-env.sh
# some Java parameters
export JAVA_HOME=/usr/local/jdk
if [ "$JAVA_HOME" != "" ]; then
  #echo "run java in $JAVA_HOME"
  JAVA_HOME=$JAVA_HOME
fi
3.4.8 slaves

此文件用于指定datanode守护进程所在的机器节点主机名 ,3.x中是workers,配置不一样

[root@qianfeng01 hadoop]# vi slaves
qianfeng01
qianfeng02
qianfeng03

Hadoop详细入门知识

3.4.9 分发到另外两台节点
# 同步Hadoop到另外两台节点
[root@qianfeng01 ~]# cd /usr/local
[root@qianfeng02 local]# scp -r hadoop qianfeng02:$PWD
[root@qianfeng02 local]# scp -r hadoop qianfeng03:$PWD

# 同步profile到另外两台节点
[root@qianfeng01 ~]# scp /etc/profile qianfeng02:/etc
[root@qianfeng01 ~]# scp /etc/profile qianfeng03:/etc

# 检查slave节点上的jdk是否已安装
# 检查是否同步了/etc/hosts文件

3.5 格式化与启动

3.5.1 格式化集群

**1)**在qianfeng01机器上运行命令

[root@qianfeng01 ~]# hdfs namenode -format

**2)**格式化的相关信息解读

--1. 生成一个集群唯一标识符:clusterid
--2. 生成一个块池唯一标识符:blockPoolId
--3. 生成namenode进程管理内容(fsimage)的存储路径:
	默认配置文件属性hadoop.tmp.dir指定的路径下生成dfs/name目录
--4. 生成镜像文件fsimage,记录分布式文件系统根路径的元数据

--5. 其他信息都可以查看一下,比如块的副本数,集群的fsOwner等。

参考图片:

Hadoop详细入门知识

3) 目录里的内容查看

Hadoop详细入门知识

3.5.2 启动集群

1) 启动脚本和关闭脚本介绍

1. 启动脚本
	-- start-dfs.sh			:用于启动hdfs集群的脚本
	-- start-yarn.sh		:用于启动yarn守护进程
	-- start-all.sh			:用于启动hdfs和yarn
2. 关闭脚本
	-- stop-dfs.sh			:用于关闭hdfs集群的脚本
	-- stop-yarn.sh			:用于关闭yarn守护进程
	-- stop-all.sh			:用于关闭hdfs和yarn
3. 单个守护进程脚本
	-- hadoop-daemons.sh	:用于单独启动或关闭hdfs的某一个守护进程的脚本
	-- hadoop-daemon.sh		:用于单独启动或关闭hdfs的某一个守护进程的脚本
	reg:
		hadoop-daemon.sh [start|stop] [namenode|datanode|secondarynamenode]
	
	-- yarn-daemons.sh	:用于单独启动或关闭hdfs的某一个守护进程的脚本
	-- yarn-daemon.sh		:用于单独启动或关闭hdfs的某一个守护进程的脚本
	reg:
		yarn-daemon.sh [start|stop] [resourcemanager|nodemanager]

**2) ** 启动HDFS

使用start-dfs.sh,启动 hdfs。参考图片

Hadoop详细入门知识

启动过程解析:

- 启动集群中的各个机器节点上的分布式文件系统的守护进程
  一个namenode和resourcemanager以及secondarynamenode
  多个datanode和nodemanager
- 在namenode守护进程管理内容的目录下生成edit日志文件
- 在每个datanode所在节点下生成${hadoop.tmp.dir}/dfs/data目录,参考下图:

Hadoop详细入门知识

注意!
如果哪台机器的相关守护进程没有开启,那么,就查看哪台机器上的守护进程对应的日志log文件,
注意,启动脚本运行时提醒的日志后缀是*.out,而我们查看的是*.log文件。
此文件的位置:${HADOOP_HOME}/logs/里

3) jps查看进程

--1. 在qianfeng01上运行jps指令,会有如下进程
	namenode
	datanode
--2. 在qianfeng02上运行jps指令,会有如下进程
	secondarynamenode
	datanode
--3. 在qianfeng03上运行jps指令,会有如下进程
	datanode   

**4) **启动yarn

使用start-yarn.sh脚本,参考图片

Hadoop详细入门知识

jps查看

--1. 在qianfeng01上运行jps指令,会多出有如下进程
	resoucemanager
	nodemanager
--2. 在qianfeng02上运行jps指令,会多出有如下进程
	nodemanager
--3. 在qianfeng03上运行jps指令,会多出有如下进程
	nodemanager 

5) webui查看

HDFS: http://192.168.10.101:50070
YARN: http://192.168.10.101:8088

Hadoop详细入门知识
Hadoop详细入门知识
Hadoop详细入门知识

第四章 HDFS的Shell命令

Hadoop详细入门知识

Hadoop详细入门知识

HDFS其实就是一个分布式的文件系统,我们可以使用一些命令来操作这个分布式文件系统上的文件。
- 访问HDFS的命令:
  hadoop dfs --- 已过时
  hdfs dfs
  
- 小技巧
  1. 在命令行中输入hdfs,回车后,就会提示hdfs后可以使用哪些命令,其中有一个是dfs。
  2. 在命令行中输入hdfs dfs,回车后,就会提示dfs后可以添加的一些常用shell命令。
  
- 注意事项
  分布式文件系统的路径在命令行中,要从/开始写,即绝对路径。

4.1 创建目录

[-mkdir [-p] <path> ...]	#在分布式文件系统上创建目录  -p,多层级创建

调用格式: hdfs dfs -mkdir (-p)  /目录
例如: 
    - hdfs dfs -mkdir /data
    - hdfs dfs -mkdir -p /data/a/b/c

4.2 上传指令

[-put [-f] [-p] [-l] <localsrc> ... <dst>]   #将本地文件系统的文件上传到分布式文件系统

调用格式:hdfs dfs -put /本地文件  /分布式文件系统路径
注意: 直接写/是省略了文件系统的名称hdfs://ip:port。
例如:
    - hdfs dfs -put /root/a.txt /data/
    - hdfs dfs -put /root/logs/* /data/

其他指令:
    [-moveFromLocal <localsrc> ... <dst>]	#将本地文件系统的文件上传到分布式文件系统
    [-copyFromLocal [-f] [-p] [-l] <localsrc> ... <dst>]

4.3 创建空文件

hdfs dfs [generic options] -touchz <path> ...   
调用格式:hdfs dfs touchz  /hadooptest.txt

4.4 向分布式文件系统中的文件里追加内容

[-appendToFile <localsrc> ... <dst>]
调用格式:hdfs dfs -appendToFile  本地文件     hdfs上的文件
注意:不支持在中间随意增删改操作

4.5 查看指令

[-ls [-d] [-h] [-R] [<path> ...]]		#查看分布式文件系统的目录里内容
调用格式:hdfs dfs -ls /

[-cat [-ignoreCrc] <src> ...]	    	#查看分布式文件系统的文件内容	
调用格式:hdfs dfs -cat /xxx.txt

[-tail [-f] <file>]						#查看分布式文件系统的文件内容	
调用格式:hdfs dfs -tail /xxx.txt
注意:默认最多查看1000行

4.6 下载指令

[-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
注意:本地路径的文件夹可以不存在

[-moveToLocal <src> <localdst>]
注意:从hdfs的某个路径将数据剪切到本地,已经被遗弃了

[-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]	
调用格式:同copyToLocal

4.7 合并下载

hdfs dfs [generic options] -getmerge [-nl] <src> <localdst>
调用格式:hdfs dfs -getmerge  hdfs上面的路径   本地的路径    
实例:hdfs dfs -getmerge /hadoopdata/*.xml /root/test.test

4.8 移动hdfs中的文件(更名)

hdfs dfds [generic options] -mv <src> ... <dst>   
调用格式:hdfs dfs -mv /hdfs的路径1  /hdfs的另一个路径2    
实例:hfds dfs -mv /aaa   /bbb  这里是将aaa整体移动到bbb中

4.9 复制hdfs中的文件到hdfs的另一个目录

hdfs dfs [generic options] -cp [-f] [-p | -p[topax]] <src> ... <dst>
调用格式:hdfs dfs -cp /hdfs路径_1  /hdfs路径_2

4.10 删除命令

[-rm [-f] [-r|-R] [-skipTrash] <src> ...]
注意:如果删除文件夹需要加-r

[-rmdir [--ignore-fail-on-non-empty] <dir> ...]
注意:必须是空文件夹,如果非空必须使用rm删除

4.11 查看磁盘利用率和文件大小

[-df [-h] [<path> ...]] 查看分布式系统的磁盘使用情况
[-du [-s] [-h] <path> ...]	#查看分布式系统上当前路径下文件的情况	-h:human 以人类可读的方式显示

4.12 修改权限的

跟本地的操作一致,-R是让子目录或文件也进行相应的修改
[-chgrp [-R] GROUP PATH...]
[-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
[-chown [-R] [OWNER][:[GROUP]] PATH...]

4.13 修改文件的副本数

[-setrep [-R] [-w] <rep> <path> ...]
调用格式:hadoop fs -setrep  3 /   将hdfs根目录及子目录下的内容设置成3个副本
注意:当设置的副本数量与初始化时默认的副本数量不一致时,集群会作出反应,比原来多了会自动进行复制.

4.14 查看文件的状态

hdfs dfs [generic options] -stat [format] <path> ...
命令的作用:当向hdfs上写文件时,可以通过dfs.blocksize配置项来设置文件的block的大小。这就导致了hdfs上的不同的文件block的大小是不相同的。有时候想知道hdfs上某个文件的block大小,可以预先估算一下计算的task的个数。stat的意义:可以查看文件的一些属性。
调用格式:hdfs dfs -stat [format] 文件路径
format的形式:
%b:打印文件的大小(目录大小为0)
%n:打印文件名
%o:打印block的size
%r:打印副本数
%y:utc时间 yyyy-MM-dd HH:mm:ss
%Y:打印自1970年1月1日以来的utc的微秒数
%F:目录打印directory,文件打印regular file

注意:
1)当使用-stat命令但不指定format时,只打印创建时间,相当于%y
2)-stat 后面只跟目录,%r,%o等打印的都是0,只有文件才有副本和大小

4.15 测试

hdfs dfs [generic options] -test -[defsz] <path>    
参数说明: -e:文件是否存在  存在返回0    -z:文件是否为空  为空返回0   -d:是否是路径(目录) ,是返回0
调用格式:hdfs dfs -test -d 文件 
实例:hdfs dfs -test -d /shelldata/111.txt  && echo "OK"  || echo "no"
解释:测试当前的内容是否是文件夹 ,如果是返回ok,如果不是返回no

第五章 HDFS的块的概念

5.1 传统型分布式文件系统的缺点

现在想象一下这种情况:有四个文件 0.5TB的file1,1.2TB的file2,50GB的file3,100GB的file4;有7个服务器,每个服务器上有10个1TB的硬盘。

Hadoop详细入门知识

在存储方式上,我们可以将这四个文件存储在同一个服务器上(当然大于1TB的文件需要切分)。那么缺点也就暴露了出来:

第一、负载不均衡。

因为文件大小不一致,势必会导致有的节点磁盘的利用率高,有的节点磁盘利用率低。

第二、网络瓶颈问题。

一个过大的文件存储在一个节点磁盘上,当有并行处理时,每个线程都需要从这个节点磁盘上读取这个文件的内容,那么就会出现网络瓶颈,不利于分布式的数据处理。

5.2 HDFS的块

HDFS与其他普通文件系统一样,同样引入了块(Block)的概念,并且块的大小是固定的。但是不像普通文件系统那样小,而是根据实际需求可以自定义的。块是HDFS系统当中的最小存储单位,在hadoop2.0中默认大小为128MB(hadoop1.x中的块大小为64M)。在HDFS上的文件会被拆分成多个块,每个块作为独立的单元进行存储。多个块存放在不同的DataNode上,整个过程中 HDFS系统会保证一个块存储在一个数据节点上 。但值得注意的是,如果某文件大小或者文件的最后一个块没有到达128M,则不会占据整个块空间

我们来看看HDFS的设计思想:以下图为例,来进行解释。

Hadoop详细入门知识

5.3 HDFS的块大小

HDFS上的块大小为什么会远远大于传统文件?

1. 目的是为了最小化寻址开销时间。
	 在I/O开销中,机械硬盘的寻址时间是最耗时的部分,一旦找到第一条记录,剩下的顺序读取效率是非常高的,因此以块为单位读写数据,可以尽量减少总的磁盘寻道时间。  
	 HDFS寻址开销不仅包括磁盘寻道开销,还包括数据块的定位开销,当客户端需要访问一个文件时,首先从名称节点获取组成这个文件的数据块的位置列表,然后根据位置列表获取实际存储各个数据块的数据节点的位置,最后,数据节点根据数据块信息在本地Linux文件系统中找到对应的文件,并把数据返回给客户端,设计成一个比较大的块,可以减少每个块儿中数据的总的寻址开销,相对降低了单位数据的寻址开销
	 磁盘的寻址时间为大约在5~15ms之间,平均值为10ms,而最小化寻址开销时间普遍认为占1秒的百分之一是最优的,那么块大小的选择就参考1秒钟的传输速度,比如2010年硬盘的传输速率是100M/s,那么就选择块大小为128M。

2. 为了节省内存的使用率
	 一个块的元数据大约150个字节。1亿个块,不论大小,都会占用20G左右的内存。因此块越大,集群相对存储的数据就越多。所以暴漏了HDFS的一个缺点,不适合存储小文件。
不适合存储小文件解释:
1. 从存储能力出发(固定内存)
   因为HDFS的文件是以块为单位存储的,且如果文件大小不到128M的时候,是不会占用整个块的空间的。但是,这个块依然会在内存中占用150个字节的元数据。因此,同样的内存占用的情况下,大量的小文件会导致集群的存储能力不足。
   例如: 同样是128G的内存,最多可存储9.2亿个块。如果都是小文件,例如1M,则集群存储的数据大小为9.2亿*1M = 877TB的数据。但是如果存储的都是128M的文件,则集群存储的数据大小为109.6PB的数据。存储能力大不相同。
   
2. 从内存占用出发(固定存储能力)
   同样假设存储1M和128M的文件对比,同样存储1PB的数据,如果是1M的小文件存储,占用的内存空间为1PB/1Mb*150Byte = 150G的内存。如果存储的是128M的文件存储,占用的内存空间为1PB/128M*150Byte = 1.17G的内存占用。可以看到,同样存储1PB的数据,小文件的存储比起大文件占用更多的内存。

5.4 块的相关参数设置

当然块大小在默认配置文件hdfs-default.xml中有相关配置,我们可以在hdfs-site.xml中进行重置
<property>
    <name>dfs.blocksize</name>
    <value>134217728</value>
    <description>默认块大小,以字节为单位。可以使用以下后缀(不区分大小写):k,m,g,t,p,e以重新指定大小(例如128k, 512m, 1g等)</description>
</property>

<property>
    <name>dfs.namenode.fs-limits.min-block-size</name>
    <value>1048576</value>
    <description>以字节为单位的最小块大小,由Namenode在创建时强制执行时间。这可以防止意外创建带有小块的文件降低性能。</description>
</property>

<property>
    <name>dfs.namenode.fs-limits.max-blocks-per-file</name>
    <value>1048576</value>
    <description>每个文件的最大块数,由写入时的Namenode执行。这可以防止创建降低性能的超大文件</description>
</property>

5.5 块的存储位置

hdfs-site.xml中我们配置过下面这个属性,这个属性的值就是块在linux系统上的存储位置

<!-- 确定DFS数据节点应该将其块存储在本地文件系统的何处-->
<property>
    <name>dfs.datanode.data.dir</name>
    <value>file://${hadoop.tmp.dir}/dfs/data</value>
</property>

Hadoop详细入门知识

5.6 HDFS的优点

1. 高容错性(硬件故障是常态):数据自动保存多个副本,副本丢失后,会自动恢复
2. 适合大数据集:GB、TB、甚至PB级数据、千万规模以上的文件数量,1000以上节点规模。
3. 数据访问: 一次性写入,多次读取;保证数据一致性,安全性
4. 构建成本低:可以构建在廉价机器上。
5. 多种软硬件平台中的可移植性 
6. 高效性:Hadoop能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因此处理速度非常快。
7. 高可靠性:Hadoop的存储和处理数据的能力值得人们信赖.

5.7 HDFS的缺点

1. 不适合做低延迟数据访问:
	 HDFS的设计目标有一点是:处理大型数据集,高吞吐率。这一点势必要以高延迟为代价的。因此HDFS不适合处理用户要求的毫秒级的低延迟应用请求
2. 不适合小文件存取:
	 一个是大量小文件需要消耗大量的寻址时间,违反了HDFS的尽可能减少寻址时间比例的设计目标。第二个是内存有限,一个block元数据大内存消耗大约为150个字节,存储一亿个block和存储一亿个小文件都会消耗20G内存。因此相对来说,大文件更省内存。
3. 不适合并发写入,文件随机修改:
	 HDFS上的文件只能拥有一个写者,仅仅支持append操作。不支持多用户对同一个文件的写操作,以及在文件任意位置进行修改

第六章 HDFS的体系结构

6.1 体系结构解析

HDFS采用的是master/slaves这种主从的结构模型来管理数据,这种结构模型主要由四个部分组成,分别是Client(客户端)、Namenode(名称节点)、Datanode(数据节点)和SecondaryNameNode。

真正的一个HDFS集群包括一个Namenode和若干数目的Datanode。

Namenode是一个中心服务器,负责管理文件系统的命名空间 (Namespace),它在内存中维护着命名空间的最新状态,同时并持久性文件(fsimage和edit)进行备份,防止宕机后,数据丢失。namenode还负责管理客户端对文件的访问,比如权限验证等。

集群中的Datanode一般是一个节点运行一个Datanode进程,真正负责管理客户端的读写请求,在Namenode的统一调度下进行数据块的创建、删除和复制等操作。数据块实际上都是保存在Datanode本地的Linux文件系统中的。每个Datanode会定期的向Namenode发送数据,报告自己的状态(我们称之为心跳机制)。没有按时发送心跳信息的Datanode会被Namenode标记为“宕机”,不会再给他分配任何I/O请求。 

用户在使用Client进行I/O操作时,仍然可以像使用普通文件系统那样,使用文件名去存储和访问文件,只不过,在HDFS内部,一个文件会被切分成若干个数据块,然后被分布存储在若干个Datanode上。

比如,用户在Client上需要访问一个文件时,HDFS的实际工作流程如此:客户端先把文件名发送给Namenode,Namenode根据文件名找到对应的数据块信息及其每个数据块所在的Datanode位置,然后把这些信息发送给客户端。之后,客户端就直接与这些Datanode进行通信,来获取数据(这个过程,Namenode并不参与数据块的传输)。这种设计方式,实现了并发访问,大大提高了数据的访问速度。

HDFS集群中只有唯一的一个Namenode,负责所有元数据的管理工作。这种方式保证了Datanode不会脱离Namenode的控制,同时,用户数据也永远不会经过Namenode,大大减轻了Namenode的工作负担,使之更方便管理工作。通常在部署集群中,我们要选择一台性能较好的机器来作为Namenode。当然,一台机器上也可以运行多个Datanode,甚至Namenode和Datanode也可以在一台机器上,只不过实际部署中,通常不会这么做的

Hadoop详细入门知识

6.2 开机启动HDFS的过程

6.2.1 非第一次启动集群

我们应该知道,在启动namenode之前,内存里是没有任何有关于元数据的信息的。那么启动集群的过程是怎样的呢?下面来叙述一下:

第一步:
Namenode在启动时,会先加载name目录下最近的fsimage文件.
将fsimage里保存的元数据加载到内存当中,这样内存里就有了之前检查点里存储的所有元数据。但是还少了从最近一次检查时间点到关闭系统时的部分数据,也就是edit日志文件里存储的数据。

第二步:
加载剩下的edit日志文件
将从最近一次检查点到目前为止的所有的日志文件加载到内存里,重演一次客户端的操作,这样,内存里就是最新的文件系统的所有元数据了。

第三步:
进行检查点设置(满足条件会进行)
namenode会终止之前正在使用的edit文件,创建一个空的edit日志文件。然后将所有的未合并过的edit日志文件和fsimage文件进行合并,产生一个新的fsimage.

第四步:
处于安全模式下,等待datanode节点的心跳反馈,当收到99.9%的块的至少一个副本后,退出安全模式,开始转为正常状态。

Hadoop详细入门知识

6.2.2 第一次启动集群

Hadoop详细入门知识

6.3 SecondaryNameNode的工作机制

SecondaryNamenode,是HDFS集群中的重要组成部分,它可以辅助Namenode进行fsimage和editlog的合并工作,减小editlog文件大小,以便缩短下次Namenode的重启时间,能尽快退出安全模式。

两个文件的合并周期,称之为检查点机制(checkpoint),是可以通过hdfs-default.xml配置文件进行修改的:

<property>
    <name>dfs.namenode.checkpoint.period</name>
    <value>3600</value>
    <description>两次检查点间隔的秒数,默认是1个小时</description>
</property>		 
<property>
    <name>dfs.namenode.checkpoint.txns</name>
    <value>1000000</value>
    <description>txid执行的次数达到100w次,也执行checkpoint</description>
</property>		 
<property>
    <name>dfs.namenode.checkpoint.check.period</name>
    <value>60</value>
    <description>60秒一检查txid的执行次数</description>
</property>

Hadoop详细入门知识

通过上图,可以总结如下:

1. SecondaryNamenode请求Namenode停止使用正在编辑的editlog文件,Namenode会创建新的editlog文件(小了吧),同时更新seed_txid文件。
2. SecondaryNamenode通过HTTP协议获取Namenode上的fsimage和editlog文件。
3. SecondaryNamenode将fsimage读进内存当中,并逐步分析editlog文件里的数据,进行合并操作,然后写入新文件fsimage_x.ckpt文件中。
4. SecondaryNamenode将新文件fsimage_x.ckpt通过HTTP协议发送回Namenode。
5. Namenode再进行更名操作。

第七章 HDFS的读写流程

7.1 读流程详解

读操作:  
	- hdfs dfs -get /file02 ./file02
	- hdfs  dfs -copyToLocal  /file02 ./file02
	- FSDataInputStream fsis = fs.open("/input/a.txt");
	- fsis.read(byte[] a)
	- fs.copyToLocal(path1,path2)	

Hadoop详细入门知识

1. 客户端通过调用FileSystem对象的open()方法来打开希望读取的文件,对于HDFS来说,这个对象是DistributedFileSystem,它通过使用远程过程调用(RPC)来调用namenode,以确定文件起始块的位置

2. 对于每一个块,NameNode返回存有该块副本的DataNode地址,并根据距离客户端的远近来排序。

3. DistributedFileSystem实例会返回一个FSDataInputStream对象(支持文件定位功能)给客户端以便读取数据,接着客户端对这个输入流调用read()方法

4. FSDataInputStream随即连接距离最近的文件中第一个块所在的DataNode,通过对数据流反复调用read()方法,可以将数据从DataNode传输到客户端

5. 当读取到块的末端时,FSInputStream关闭与该DataNode的连接,然后寻找下一个块的最佳DataNode

6. 客户端从流中读取数据时,块是按照打开FSInputStream与DataNode的新建连接的顺序读取的。它也会根据需要询问NameNode来检索下一批数据块的DataNode的位置。一旦客户端完成读取,就对FSInputStream调用close方法

注意:在读取数据的时候,如果FSInputStream与DataNode通信时遇到错误,会尝试从这个块的最近的DataNode读取数据,并且记住那个故障的DataNode,保证后续不会反复读取该节点上后续的块。FInputStream也会通过校验和确认从DataNode发来的数据是否完整。如果发现有损坏的块,FSInputStream会从其他的块读取副本,并且将损坏的块通知给NameNode

7.2 写流程的详解

写操作: 
	- hdfs dfs -put ./file02 /file02
	- hdfs  dfs -copyFromLocal  ./file02 /file02
	- FSDataOutputStream fsout = fs.create(path);fsout.write(byte[])
	- fs.copyFromLocal(path1,path2)

Hadoop详细入门知识

1. 客户端通过对DistributedFileSystem对象调用create()方法来新建文件

2. DistributedFileSystem对namenode创建一个RPC调用,在文件系统的命名空间中新建一个文件,此时该文件中还没有相应的数据块

3. namenode执行各种不同的检查,以确保这个文件不存在以及客户端有新建该文件的权限。如果检查通过,namenode就会为创建新文件记录一条事务记录(否则,文件创建失败并向客户端抛出一个IOException异常)。DistributedFileSystem向客户端返回一个FSDataOuputStream对象,由此客户端可以开始写入数据,

4. 在客户端写入数据时,FSOutputStream将它分成一个个的数据包(packet),并写入一个内部队列,这个队列称为“数据队列”(data queue)。DataStreamer线程负责处理数据队列,它的责任是挑选出合适存储数据复本的一组datanode,并以此来要求namenode分配新的数据块。这一组datanode将构成一个管道,以默认复本3个为例,所以该管道中有3个节点.DataStreamer将数据包流式传输到管道中第一个datanode,该datanode存储数据包并将它发送到管道中的第2个datanode,同样,第2个datanode存储该数据包并且发送给管道中的第三个datanode。DataStreamer在将一个个packet流式传输到第一个Datanode节点后,还会将此packet从数据队列移动到另一个队列确认队列(ack queue)中。

5. datanode写入数据成功之后,会为ResponseProcessor线程发送一个写入成功的信息回执,当收到管道中所有的datanode确认信息后,ResponseProcessoer线程会将该数据包从确认队列中删除。

如果任何datanode在写入数据期间发生故障,则执行以下操作:

1. 首先关闭管道,把确认队列中的所有数据包都添加回数据队列的最前端,以确保故障节点下游的datanode不会漏掉任何一个数据包
2. 为存储在另一正常datanode的当前数据块制定一个新标识,并将该标识传送给namenode,以便故障datanode在恢复后可以删除存储的部分数据块
3. 从管道中删除故障datanode,基于两个正常datanode构建一条新管道,余下数据块写入管道中正常的datanode
4. namenode注意到块复本不足时,会在一个新的Datanode节点上创建一个新的复本。

注意:在一个块被写入期间可能会有多个datanode同时发生故障,但概率非常低。只要写入了dfs.namenode.replication.min的复本数(默认1),写操作就会成功,并且这个块可以在集群中异步复制,直到达到其目标复本数dfs.replication的数量(默认3)

第八章 Zookeeper的概述

8.1 Zookeeper是什么

1. zookeeper是一个为分布式应用程序提供的一个分布式开源协调服务框架。是Google的Chubby的一个开源实现,是Hadoop和Hbase的重要组件。主要用于解决分布式集群中应用系统的一致性问题。
2. 提供了基于类似Unix系统的目录节点树方式的数据存储。
3. 可用于维护和监控存储的数据的状态的变化,通过监控这些数据状态的变化,从而达到基于数据的集群管理
4. 提供了一组原语(机器指令),提供了java和c语言的接口

8.2 Zookeeper的特点

1. 也是一个分布式集群,一个领导者(leader),多个跟随者(follower).
2. 集群中只要有半数以上的节点存活,Zookeeper集群就能正常服务。
3. 全局数据一致性:每个server保存一份相同的数据副本,client无论连接到哪个server,数据都是一致的。
4. 更新请求按顺序进行:来自同一个client的更新请求按其发送顺序依次执行
5. 数据更新的原子性:一次数据的更新要么成功,要么失败
6. 数据的实时性:在一定时间范围内,client能读到最新数据。

Hadoop详细入门知识

8.3 Zookeeper的数据模型

Zookeeper的数据模型采用的与Unix文件系统类似的层次化的树形结构。我们可以将其理解为一个具有高可用特征的文件系统。这个文件系统中没有文件和目录,而是统一使用"节点"(node)的概念,称之为znode。znode既可以作为保存数据的容器(如同文件),也可以作为保存其他znode的容器(如同目录)。所有的znode构成了一个层次化的命名空间。

Hadoop详细入门知识

- Zookeeper 被设计用来实现协调服务(这类服务通常使用小数据文件),而不是用于大容量数据存储,因此一个znode能存储的数据被限制在1MB以内,
- 每个znode都可以通过其路径唯一标识。

8.4 Zookeeper的应用场景

1. 统一配置管理
2. 统一集群管理
3. 服务器节点动态上下线感知
4. 软负载均衡等
5. 分布式锁
6. 分布式队列

第九章 Zookeeper的安装

9.1. 安装与环境变量的配置

1. 将zookeeper-3.4.10.tar.gz上传到/root中
2. 解压
   [root@qianfeng01 ~]# tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/apps/
3. 更名zookeeper
   [root@qianfeng01 ~]# cd /opt/apps/
   [root@qianfeng01 local]# mv zookeeper-3.4.10 zookeeper
4. 配置环境变量
   [root@qianfeng01 local]# vi  /etc/profile
   .........省略......
   export ZOOKEEPER_HOME=/opt/apps/zookeeper
   export PATH=$ZOOKEEPER_HOME/bin:$PATH
5. 使当前会话生效
   [root@qianfeng01 local]# source /etc/profile
6. 检查如下:
如果只检查环境变量是否配置成功,只需要使用tab键进行补全zk,是否zookeeper的相关脚本提示即可。

9.2. 集群模式的配置

9.2.1 Zookeeper的服务进程布局
qianfeng01		QuorumPeerMain
qianfeng02		QuorumPeerMain
qianfeng03		QuorumPeerMain
9.2.2 修改zoo.cfg文件
[root@qianfeng01 local]# cd ./zookeeper/conf/               
[root@qianfeng01 conf]# cp  zoo_sample.cfg  zoo.cfg   #复制出zoo.cfg文件
[root@qianfeng01 conf]# vi zoo.cfg
tickTime=2000				# 定义的时间单元(单位毫秒),下面的两个值都是tickTime的倍数。
initLimit=10				# follower连接并同步leader的初始化连接时间。
syncLimit=5					# 心跳机制的时间(正常情况下的请求和应答的时间)
dataDir=/usr/local/zookeeper/zkData       # 修改zookeeper的存储路径,zkData目录一会要创建出来
clientPort=2181							 							# 客户端连接服务器的port
server.1=qianfeng01:2888:3888    			 		# 添加三个服务器节点
server.2=qianfeng02:2888:3888
server.3=qianfeng03:2888:3888

解析Server.id=ip:port1:port2
id:		服务器的id号,对应zkData/myid文件内的数字
ip: 	服务器的ip地址
port1:	follower与leader交互的port
port2:	选举期间使用的port

注意:此配置文件中,不支持汉字注释
9.2.3 添加myid
# 在$ZOOKEEPER_HOME/zkData目录下添加myid文件,内容为server的id号
[root@qianfeng01 conf]# cd ..
[root@qianfeng01 zookeeper]# mkdir zkData
[root@qianfeng01 zookeeper]# cd zkData
[root@qianfeng01 zkData]# echo "1" >> myid
9.2.4 搭建其他两个server节点的环境

**1)**使用scp命令将zookeeper环境 复制到qianfeng02和qianfeng03中

[root@qianfeng01 zkData]# cd /usr/local
[root@qianfeng01 apps]# scp -r zookeeper qianfeng02:/usr/local
[root@qianfeng01 apps# scp -r zookeeper qianfeng03:/usr/local

2) 使用scp命令拷贝/etc/profile到两台机器上(别忘记source一下)

[root@qianfeng01 apps]# scp /etc/profile qianfeng02:/etc/ 	
[root@qianfeng01 apps]# scp /etc/profile qianfeng03:/etc/

3) 修改qianfeng02的myid文件的内容为2

[root@qianfeng01 ~]# ssh qianfeng02
[root@qianfeng02 ~]# echo "2" > /opt/apps/zookeeper/zkData/myid

4) 修改qianfeng03的myid文件的内容为3

[root@qianfeng02 ~]# ssh qianfeng03
[root@qianfeng03 ~]# echo "3" > /opt/apps/zookeeper/zkData/myid
9.2.5 启动zookeeper

**1)**三台机器上都启动zookeeper的服务 (注意保证防火墙是关闭的)

[root@qianfeng01 ~]# zkServer.sh start
再查看一下状态
[root@qianfeng01 ~]# zkServer.sh status

2) 启动客户端的操作:

zkCli.sh [-server] [ ip:port]

reg:
[root@qianfeng01 ~]# zkCli.sh								#启动客户端,连接本地服务进程 
[root@qianfeng01 ~]# zkCli.sh -server qianfeng02:2181			#启动客户端,连接qianfeng02上的服务进程 

第十章 Zookeeper的Shell操作

命令 描述 示例
ls 查看某个目录包含的所有文件 ls /
ls2 查看某个目录包含的所有文件,与ls不同的是它查看到time、version等信息 ls2 /
create 创建znode,并需要设置初始内容 create /test “test”
create -e /test “test”
get 获取znode的数据 get /test
set 修改znode的内容 set /test “test2”
delete 删除znode delete /test
quit 退出客户端
help 帮助命令

第十一章 YARN的概述

为克服Hadoop 1.0中HDFS和MapReduce存在的各种问题而提出的,针对Hadoop 1.0中的MapReduce在扩展性和多框架支持方面的不足,提出了全新的资源管理框架YARN.

Apache YARN(Yet another Resource Negotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于一个分布式的操作系统平台,而MapReduce等计算程序则相当于运行于操作系统之上的应用程序。

yarn被引入Hadoop2,最初是为了改善MapReduce的实现,但是因为具有足够的通用性,同样可以支持其他的分布式计算模式,比如Spark,Tez等计算框架。

Hadoop详细入门知识

第十二章 YARN的架构及组件

12.1. MapReduce 1.x的简介

第一代Hadoop,由分布式存储系统HDFS和分布式计算框架MapReduce组成,其中,HDFS由一个NameNode和多个DataNode组成,MapReduce由一个JobTracker和多个TaskTracker组成,对应Hadoop版本为Hadoop 1.x和0.21.X,0.22.x。

1) MapReduce1的角色

-1.Client	:作业提交发起者。
-2.JobTracker	:初始化作业,分配作业,与TaskTracker通信,协调整个作业。
-3.TaskTracker :保持JobTracker通信,在分配的数据片段上执行MapReduce任务。

Hadoop详细入门知识

2) MapReduce执行流程

Hadoop详细入门知识

**步骤1)**提交作业

编写MapReduce程序代码,创建job对象,并进行配置,比如输入和输出路径,压缩格式等,然后通过JobClinet来提交作业。

**步骤2)**作业的初始化

客户端提交完成后,JobTracker会将作业加入队列,然后进行调度,默认的调度方法是FIFO调试方式。

**步骤3)**任务的分配

TaskTracker和JobTracker之间的通信与任务的分配是通过心跳机制完成的。

TaskTracker会主动向JobTracker询问是否有作业要做,如果自己可以做,那么就会申请到作业任务,这个任务可以是MapTask也可能是ReduceTask。

**步骤4)**任务的执行

申请到任务后,TaskTracker会做如下事情:

-1. 拷贝代码到本地
-2. 拷贝任务的信息到本地
-3. 启动JVM运行任务

**步骤5)**状态与任务的更新

任务在运行过程中,首先会将自己的状态汇报给TaskTracker,然后由TaskTracker汇总告之JobTracker。任务进度是通过计数器来实现的。

步骤6) 作业的完成

JobTracker是在接受到最后一个任务运行完成后,才会将任务标记为成功。此时会做删除中间结果等善后处理工作。

12.2. YARN的设计思想

yarn的基本思想是将资源管理和作业调度/监视功能划分为单独的守护进程。其思想是拥有一个全局ResourceManager (RM),以及每个应用程序拥有一个ApplicationMaster (AM)。应用程序可以是单个作业,也可以是一组作业

Hadoop详细入门知识

一个ResourceManager和多个NodeManager构成了yarn资源管理框架。他们是yarn启动后长期运行的守护进程,来提供核心服务。

ResourceManager,是在系统中的所有应用程序之间仲裁资源的最终权威,即管理整个集群上的所有资源分配,内部含有一个Scheduler(资源调度器)

NodeManager,是每台机器的资源管理器,也就是单个节点的管理者,负责启动和监视容器(container)资源使用情况,并向ResourceManager及其 Scheduler报告使用情况

container:即集群上的可使用资源,包含cpu、内存、磁盘、网络等

ApplicationMaster(简称AM)实际上是框架的特定的库,每启动一个应用程序,都会启动一个AM,它的任务是与ResourceManager协商资源,并与NodeManager一起执行和监视任务

**扩展)**YARN与MapReduce1的比较

Hadoop详细入门知识

12.3. YARN的配置

yarn属于hadoop的一个组件,不需要再单独安装程序,hadoop中已经存在配置文件的设置,本身就是一个集群,有主节点和从节点。

注意<value></value>之间的值不能有空格

在mapred-site.xml中的配置如下:

<!--用于执行MapReduce作业的运行时框架-->
<property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
</property>

<!--历史任务的内部通讯地址-->
<property>
    <name>MapReduce.jobhistory.address</name>
    <value>qianfeng01:10020</value>
</property>

<!--历史任务的外部监听页面-->
<property>
    <name>MapReduce.jobhistory.webapp.address</name>
    <value>qianfeng01:19888</value>
</property>

在yarn-site.xml中的配置如下:

<!--配置resourcemanager的主机-->
<property>
    <name>yarn.resourcemanager.hostname</name>
    <value>qianfeng01</value>
</property>

<!--配置yarn的shuffle服务-->
<property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value> 
</property> 

<!--指定shuffle对应的类 -->
<property> 
    <name>yarn.nodemanager.aux-services.MapReduce_shuffle.class</name>
    <value>org.apache.hadoop.mapred.ShuffleHandler</value> 
</property>

<!--配置resourcemanager的scheduler的内部通讯地址-->
<property>
	<name>yarn.resourcemanager.scheduler.address</name>
	<value>qianfeng01:8030</value>
</property>

<!--配置resoucemanager的资源调度的内部通讯地址-->
<property>
	<name>yarn.resourcemanager.resource-tracker.address</name>
	<value>qianfeng01:8031</value>
</property>

<!--配置resourcemanager的内部通讯地址-->
<property>
	<name>yarn.resourcemanager.address</name>
	<value>qianfeng01:8032</value>
</property>

<!--配置resourcemanager的管理员的内部通讯地址-->
<property>
	<name>yarn.resourcemanager.admin.address</name>
	<value>qianfeng01:8033</value>
</property>

<!--配置resourcemanager的web ui 的监控页面-->
<property>
	<name>yarn.resourcemanager.webapp.address</name>
	<value>qianfeng01:8088</value>
</property>

1) 日志位置

jps:当启动进程时出错了解决步骤:可以查看日志

如果是hdfs上的问题,则查看对应的日志
less 或 tail -1000 $HADOOP_HOME/logs/hadoop-{user.name}-{jobname}-{hostname}.log
如果是yarn,则查看
less 或 tail -1000 $HADOOP_HOME/logs/yarn-{user.name}-{jobname}-{hostname}.log

2) 历史服务

如果需要查看YARN的作业历史,需要打开历史服务:

1. 停止当前的YARN进程
stop-yarn.sh

2. 在yarn-site.xml中添加配置
<!-- 开启日志聚集功能 -->
<property>
    <name>yarn.log-aggregation-enable</name>
    <value>true</value>
</property>
<!-- 日志信息保存在文件系统上的最长时间,单位为秒-->
<property>
    <name>yarn.log-aggregation.retain-seconds</name>
    <value>640800</value>
</property>

3. 分发到其他节点

4. 启动YARN进程
start-yarn.sh

5. 开启历史服务
mr-jobhistory-server.sh start historyserver

第十三章 YARN的执行原理

在MR程序运行时,有五个独立的进程:

-  YarnRunner:用于提交作业的客户端程序
-  ResourceManager:yarn资源管理器,负责协调集群上计算机资源的分配
-  NodeManager:yarn节点管理器,负责启动和监视集群中机器上的计算容器(container)
-  Application Master:负责协调运行MapReduce作业的任务,他和任务都在容器中运行,这些容器由资源管理器分配并由节点管理器进行管理。
-  HDFS:用于共享作业所需文件。

整个过程如下图描述:

Hadoop详细入门知识

1. 调用waitForCompletion方法每秒轮询作业的进度,内部封装了submit()方法,用于创建JobCommiter实例,并且调用其的submitJobInternal方法。提交成功后,如果有状态改变,就会把进度报告到控制台。错误也会报告到
控制台
2. JobCommiter实例会向ResourceManager申请一个新应用ID,用于MapReduce作业ID。这期间JobCommiter也会进行检查输出路径的情况,以及计算输入分片。
3. 如果成功申请到ID,就会将运行作业所需要的资源(包括作业jar文件,配置文件和计算所得的输入分片元数据文件)上传到一个用ID命名的目录下的HDFS上。此时副本个数默认是10.
4. 准备工作已经做好,再通知ResourceManager调用submitApplication方法提交作业。
5. ResourceManager调用submitApplication方法后,会通知Yarn调度器(Scheduler),调度器分配一个容器,在节点管理器的管理下在容器中启动 application master进程。
6. application master的主类是MRAppMaster,其主要作用是初始化任务,并接受来自任务的进度和完成报告。
7. 然后从HDFS上接受资源,主要是split。然后为每一个split创建MapTask以及参数指定的ReduceTask,任务ID在此时分配
8. 然后Application Master会向资源管理器请求容器,首先为MapTask申请容器,然后再为ReduceTask申请容器。(5%)
9. 一旦ResourceManager中的调度器(Scheduler),为Task分配了一个特定节点上的容器,Application Master就会与NodeManager进行通信来启动容器。
10. 运行任务是由YarnChild来执行的,运行任务前,先将资源本地化(jar文件,配置文件,缓存文件)
11. 然后开始运行MapTask或ReduceTask。
12. 当收到最后一个任务已经完成的通知后,application master会把作业状态设置为success。然后Job轮询时,知道成功完成,就会通知客户端,并把统计信息输出到控制台

第十四章 YARN的案例测试

MapReduce:

[root@qianfeng01 mapreduce]# hadoop jar hadoop-mapreduce-examples-2.7.6.jar wordcount /input /output
INFO client.RMProxy: Connecting to ResourceManager at qianfeng01/192.168.10.101:8032
INFO input.FileInputFormat: Total input paths to process : 1
INFO mapreduce.JobSubmitter: number of splits:1
INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1617775349214_0003
INFO impl.YarnClientImpl: Submitted application application_1617775349214_0003
INFO mapreduce.Job: The url to track the job: http://qianfeng01:8088/proxy/application_1617775349214_0003/
INFO mapreduce.Job: Running job: job_1617775349214_0003
INFO mapreduce.Job: Job job_1617775349214_0003 running in uber mode : false
INFO mapreduce.Job:  map 0% reduce 0%
INFO mapreduce.Job:  map 100% reduce 0%
INFO mapreduce.Job:  map 100% reduce 100%
INFO mapreduce.Job: Job job_1617775349214_0003 completed successfully
INFO mapreduce.Job: Counters: 49
	File System Counters
		FILE: Number of bytes read=111
		FILE: Number of bytes written=245331
		FILE: Number of read operations=0
		FILE: Number of large read operations=0
		FILE: Number of write operations=0
		HDFS: Number of bytes read=218
		HDFS: Number of bytes written=69
		HDFS: Number of read operations=6
		HDFS: Number of large read operations=0
		HDFS: Number of write operations=2
	Job Counters 
		Launched map tasks=1
		Launched reduce tasks=1
		Data-local map tasks=1
		Total time spent by all maps in occupied slots (ms)=3359
		Total time spent by all reduces in occupied slots (ms)=3347
		Total time spent by all map tasks (ms)=3359
		Total time spent by all reduce tasks (ms)=3347
		Total vcore-milliseconds taken by all map tasks=3359
		Total vcore-milliseconds taken by all reduce tasks=3347
		Total megabyte-milliseconds taken by all map tasks=3439616
		Total megabyte-milliseconds taken by all reduce tasks=3427328
	Map-Reduce Framework
		Map input records=3
		Map output records=21
		Map output bytes=203
		Map output materialized bytes=111
		Input split bytes=99
		Combine input records=21
		Combine output records=9
		Reduce input groups=9
		Reduce shuffle bytes=111
		Reduce input records=9
		Reduce output records=9
		Spilled Records=18
		Shuffled Maps =1
		Failed Shuffles=0
		Merged Map outputs=1
		GC time elapsed (ms)=126
		CPU time spent (ms)=1250
		Physical memory (bytes) snapshot=451137536
		Virtual memory (bytes) snapshot=4204822528
		Total committed heap usage (bytes)=282591232
	Shuffle Errors
		BAD_ID=0
		CONNECTION=0
		IO_ERROR=0
		WRONG_LENGTH=0
		WRONG_MAP=0
		WRONG_REDUCE=0
	File Input Format Counters 
		Bytes Read=119
	File Output Format Counters 
		Bytes Written=69

第十五章 YARN的Web UI查看

使用8088端口,可以查看YARN任务的WebUI

Hadoop详细入门知识文章来源地址https://www.toymoban.com/news/detail-471334.html

到了这里,关于Hadoop详细入门知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 电脑键盘功能基础知识,快速入门,抓住这份详细教程

    在互联网生活发达的今天,电脑已经成为了学习工作的必备工具。而用来操作电脑的关键,就是我们经常使用的键盘和鼠标。最近有不少的小伙伴来私信小编,希望小编做一个电脑键盘功能基础知识介绍的详细教程。这不,小编应大家要求,跟大家分享一下电脑键盘各个按键

    2024年02月09日
    浏览(55)
  • QT入门看这一篇就够了——超详细讲解(40000多字详细讲解,涵盖qt大量知识)

    目录 一、Qt概述 1.1 什么是Qt 1.2 Qt的发展史 1.3 Qt的优势 1.4 Qt版本 1.5 成功案例 二、创建Qt项目 2.1 使用向导创建 2.2 一个最简单的Qt应用程序 2.2.1 main函数中 2.2.2 类头文件 2.3 .pro文件 2.4 命名规范  2.5 QtCreator常用快捷键 三、Qt按钮小程序 3.1按钮的创建和父子关系 3.2 Qt窗口坐标

    2024年02月09日
    浏览(50)
  • Java入门高频考查基础知识2(超详细28题2.5万字答案)

    Java 是一种广泛使用的面向对象编程语言,在软件开发领域有着重要的地位。Java 提供了丰富的库和强大的特性,适用于多种应用场景,包括企业应用、移动应用、嵌入式系统等。          以下是 Java 基础知识的一个概览:     1. 语法和基本概念: Java 的语法类似于 C++

    2024年01月19日
    浏览(42)
  • LaTeX详细安装教程|LaTeX 基础知识|LaTeX 常用语法|LaTeX 快速入门

    LaTeX 是一种专业的排版系统,主要用于科技文献、学术论文、书籍等的排版。与传统的文字处理软件相比,LaTeX 可以更好地管理大型文字项目,并提供了丰富的数学公式和符号支持。本篇博客将介绍 LaTeX 的基础知识、常用语法以及安装教程。 LaTeX 具有如下特点: 专业的排版

    2024年02月05日
    浏览(92)
  • 详解爬虫基本知识及入门案列(爬取豆瓣电影《热辣滚烫》的短评 详细讲解代码实现)

    目录 前言什么是爬虫? 爬虫与反爬虫基础知识 一、网页基础知识  二、网络传输协议 HTTP(HyperText Transfer Protocol)和HTTPS(HTTP Secure)请求过程的原理? 三、Session和Cookies Session Cookies Session与Cookies的区别与联系  四、Web服务器Nginx 五、代理IP 1、代理IP的原理 2. 分类 3. 获取途

    2024年04月29日
    浏览(65)
  • 数据库入门-----SQL基础知识

    目录 📖前言: 📑SQL概述通用语法:  🐳DDL: 🐻操作数据库: 🐞数据类型:  🦉操作表: 🦦DML: 语法规则: 案例演示: 🦏DQL: 语法规则: 案例演示: # 基础查询:  # 条件查询:  #聚合函数:  # 分组查询:  #排序查询:  #分页查询:  执行顺序: 🫎DCL: 语法规则:

    2024年04月10日
    浏览(57)
  • 【JavaScript_1】入门知识、数据类型、运算符

    1、var变量赋值不需要强制转换,可以直接进行赋值。 var a=1; a=“hello”; 2、JavaScript的工作方式:先解析代码,获取所有被声明的变量,然后再一行一行地运行。 因此导致所有的变量声明语句都会被提升到代码的头部,这就叫做变量提升。 eg: console.log(a); var a=1;-----------var a;

    2024年02月12日
    浏览(52)
  • 数据库的基本知识---入门前必读

    目录 一.认识数据库 二.数据库的分类 三.SQL介绍 3.1SQL是什么 3.2.SQL语言使用方式 总结 😽个人主页:tq02的博客_CSDN博客-C语言,Java,Java数据结构领域博主  🌈梦的目标:努力学习,打败数据库,拼搏一切,让自己的未来不会有遗憾。  🎁欢迎各位→ 点赞 👍 + 收藏 ⭐ + 评论

    2024年02月09日
    浏览(37)
  • MySQL实战基础知识入门(13):数据类型

    MySQL实战基础知识入门(1):登录数据库命令行 MySQL实战基础知识入门(2):统计一天24小时数据默认补0的sql语句 MySQL实战基础知识入门(3):近7日销量合计php后端mysql语句如果当日为空则自动补0的解决方案 MySQL实战基础知识入门(4):MySQL高级函数CASE WHEN END MySQL实战基础知识入门

    2024年02月07日
    浏览(68)
  • Java入门高频考查算法逻辑基础知识3-编程篇(超详细18题1.8万字参考编程实现)

    准备这些面试题时,请考虑如下准备步骤: 理解问题并澄清任何可能的疑点。确保你了解了面试官的期望,包括问题限制条件和期望的解决方案。 如果可能且适用的话,尝试先给出一个简单的解决方案,比如暴力法,然后再逐步优化它。 在优化之前,先分析暴力解法的效率

    2024年01月18日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包