什么是大数据?多大量算大?说白了:当数据规模大到在获取、存储、管理、分析方面大大超出了单节点服务器能力范围。大数据具有海量的数据规模、快速的数据流转、多样的数据类型和价值密度低四大特征。大数据的初心是:用多台廉价的服务器并行处理,来替代昂贵的单台高性能服务器,以达到节约成本的目的。
很多外行眼里:大数据,自带AI处理能力,能分析,能预测。实则不然,大数据,只是拥有了处理海量数据的能力,那数据从哪来?怎么治理规整?怎么用?基于大规模数据,咱是要落地数仓?还是用它来训练ai模型?这些都在于使用者。它就好比一口大锅。有了锅,不代表饭做好了。蒸米饭,还是蒸馒头,取决于厨子。
大数据知识广,且深。因此咱们需要把它梳理一下:
协调工作 | zookeeper | ||
作业调度 | yarn | ||
运算引擎 | spark | hive | |
mapreduce | |||
数据库/湖 | 基于hdfs文件的数据库 hbase | 数据湖hudi | 数据湖iceberg |
底层存储 | HDFS 离线 | ||
kafka 实时,临时存储(默认存7天数据) | |||
实时运算引擎 | flink,sparkstreaming | ||
基础语言 | scala | python | |
java |
下面,咱们从hdfs说起:HDFS(Hadoop Distributed File System )是Hadoop分布式文件系统。
主要特点:两高一大
HDFS不适合的场景:低延迟数据访问;大量的小文件;多用户写入文件、修改文件。
为什么不支持随机写呢?
1:hadoop设计的初衷是大规模数据的计算和olap分析, 应用场景区别与数据库,所以在HDFS设计时候就侧重在一次写入多次读取
2: 假设现在我们在HDFS中加入了随机写.那么为了正确性我们需要保障的东西有哪些?
综上,首先hadoop初衷不是为了修改数据而是侧重查询,其次就是确实是可以实现HDFS修改,但是同时也要付出系统复杂性和性能的代价.这是一个trade-off的选择
NameNode保存着HDFS的名字空间,对于任何对文件系统元数据产生修改的操作;主要负责三个功能,分别是1)管理元数据 2)维护目录树 3)响应客户请求
DataNode将HDFS数据以文件的形式存储在本地文件系统中,它并不知道有关HDFS文件的信息。
block块:数据块是HDFS的文件存储处理单元,默认128M数据。
为什么HDFS中块(block)不能设置太大,也不能设置太小?
1. 如果块设置过大,
一方面,从磁盘传输数据的时间会明显大于寻址时间,导致程序在处理这块数据时,变得非常慢;
另一方面,mapreduce中的map任务通常一次只处理一个块中的数据,如果块过大运行速度也会很慢。
2. 如果块设置过小,
一方面存放大量小文件会占用NameNode中大量内存来存储元数据,而NameNode的内存是有限的,不可取;
另一方面文件块过小,寻址时间增大,导致程序一直在找block的开始位置。
因而,块适当设置大一些,减少寻址时间,那么传输一个由多个块组成的文件的时间主要取决于磁盘的传输速率。
HDFS中块(block)的大小为什么设置为128M?
1. HDFS中平均寻址时间大概为10ms;
2. 经过前人的大量测试发现,寻址时间为传输时间的1%时,为最佳状态;
所以最佳传输时间为10ms/0.01=1000ms=1s
3. 目前磁盘的传输速率普遍为100MB/s;
计算出最佳block大小:100MB/s x 1s = 100MB
所以我们设定block大小为128MB。
ps:实际在工业生产中,磁盘传输速率为200MB/s时,一般设定block大小为256MB
磁盘传输速率为400MB/s时,一般设定block大小为512MB
注:当用户或应用程序删除某个文件时,这个文件并没有立刻从HDFS中删除。实际上,HDFS会将这个文件重命名转移到/trash目录。文件在/trash中保存的时间是可配置的,当超过这个时间时,Namenode就会将该文件从名字空间中删除。删除文件会使得该文件相关的数据块被释放。
如果用户想恢复被删除的文件,他可以浏览/trash目录找回该文件。/trash目录仅仅保存被删除文件的最后副本。目前的默认策略是删除/trash中保留时间超过6小时的文件。将来,这个策略可以通过一个被良好定义的接口配置。当一个文件的副本系数被减小后,Namenode会选择过剩的副本删除。下次心跳检测时会将该信息传递给Datanode。Datanode遂即移除相应的数据块,集群中的空闲空间加大。
datanode需要每隔一段时间向namenode发送心跳,如果namenode长时间接收不心跳,会认为该datanode节点已经失效。
namenode的职责:响应客户端请求、管理元数据。
元数据如果存储在namenode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低。所以元数据metadata要存储在内存中!方便随机存储!因此,元数据需要存放在内存中。但如果只存在内存中,一旦断点,元数据丢失,整个集群就无法工作了!因此解决办法是元数据存储在内存中,但在磁盘中有备份,这个备份就是fsImage,存放在namenode节点对应的磁盘中。(元数据->内存;edits.log,fsImage->磁盘;但三者都在Namenode中)
新的问题:当在内存中的元数据更新时,如果同时更新fsImage,就会导致效率过低,相当于第一种;但如果不更新,就会发生一致性问题,一旦namenode节点断点,就会产生数据丢失。
解决办法:引入edits.log文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到edits.log中。这样,一旦namenode节点断电,可以通过fsImage和edits.log的合并,合成元数据。
(datanode数据改变的记录在元数据中,元数据的改变记录在edits.log中)
但是,如果长时间添加数据到edit.log中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行fsImage和edits.log的合并。
如果这个操作有namenode节点完成,又会效率过低。因此,引入一个新的节点Standby NameNode,专门用于fsImage和edits.log的合并。
合并操作发生在Standby NameNode中。
Hadoop2.0的HA 机制有两个NameNode,一个是Active状态,另一个是Standby状态。两者的状态可以切换,但同时最多只有1个是Active状态。只有Active Namenode提供对外的服务。Active NameNode和Standby NameNode之间通过JournalNode来同步数据。
QJM方式有明显的优点,一是本身就有fencing的功能,二是通过多个Journal节点增强了系统的健壮性,所以建议在生产环境中采用QJM的方式。JournalNode消耗的资源很少,不需要额外的机器专门来启动JournalNode,可以从Hadoop集群中选几台机器同时作为JournalNode。
Active NameNode和Standby NameNode可以随时切换,可以人工和自动。人工切换是通过执行HA管理命令来改变NameNode的状态,从Standby到Active,或从Active到Standby。自动切换则在Active NameNode挂掉的时候,Standby NameNode自动切换成Active状态。
主备NameNode的自动切换需要配置Zookeeper。Active NameNode和Standby NameNode把他们的状态实时记录到Zookeeper中,Zookeeper监视他们的状态变化。当Zookeeper发现Active NameNode挂掉后,会自动把Standby NameNode切换成Active NameNode。
安全模式是Hadoop的一种保护机制,用以保证集群中block块的安全性。Namenode启动后会进入一个称为安全模式的特殊状态。处于安全模式的Namenode是不会进行数据块的复制的。Namenode从所有的 Datanode接收心跳信号和块状态报告。块状态报告包括了某个Datanode所有的数据块列表。每个数据块都有一个指定的最小副本数。当Namenode检测确认某个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全的;在一定百分比(这个参数可配置)的数据块被Namenode检测确认是安全之后(加上一个额外的30秒等待时间),Namenode将退出安全模式状态。接下来它会确定还有哪些数据块的副本没有达到指定数目,并将这些数据块复制到其他Datanode上。
在安全模式状态下,文件系统只接受读数据的请求,而不接受删除、修改等请求。整个系统达到安全标准时,hdfs自动离开安全模式。
HDFS不适合存储小文件的原因:每个文件都会产生元信息,当小文件多了之后元信息也就多了,对namenode会造成压力。
解决方案参见:链接
某个datanode节点挂了,集群进入乐安全模式,手动退出安全模式导致,尽管手动退出安全模式之后hdfs还会逐步恢复副本,但是,此时用户有了删除权限,就可能误删正在恢复的块,导致块彻底丢失。
解决步骤
hdfs fsck -list-corruptfileblocks
hdfs fsck / | egrep -v '^\.+$' | grep -v eplica
方案一:hadoop会在6个小时候自动检测并修复
方案二:手工重启hdfs服务后会自动修复
方案三:手工修复(推荐使用)hdfs dfs -get而
后-put就可以解决。
若文件不重要:
# 退出安全模式 hdfs dfsadmin -safemode leave
#删除损坏(丢失)的BLOCK hdfs fsck /path -delete
若文件重要,且数据源可重新接入,或者它是程序生成的,则需要重新生成
HDFS数据并不总是均匀存储在datanode中的,如新增加一个datanode节点到集群中。当有新的数据要存储时,namenode会考虑多种因数后再选择datanode来存储数据。
因数如下:
考虑到上述因素,HDFS提供了一个分析数据块的存放和datanode数据再平衡的工具rebalancer。