目录
1. 传统型分布式⽂件系统的缺点
现在想象⼀下这种情况:有四个⽂件 0.5TB
的
file1
,
1.2TB
的
file2
,
50GB
的
file3
, 100GB的
file4
;有
7
个服务器,每个服务器上有
10
个
1TB
的硬盘。
![](https://i-blog.csdnimg.cn/blog_migrate/48c6e410beba68008bf4ec9206035959.png)
在存储⽅式上,我们可以将这四个⽂件存储在同⼀个服务器上(当然⼤于1TB
的⽂件 需要切分),我们需要使⽤⼀个⽂件来记录这种存储的映射关系吧。⽤户是可以通过 这种映射关系来找到节点硬盘相应的⽂件的。那么缺点也就暴露了出来:
第⼀、负载不均衡。
因为⽂件⼤⼩不⼀致,势必会导致有的节点磁盘的利⽤率⾼,有的节点磁盘利⽤率低。
第⼆、⽹络瓶颈问题。
⼀个过⼤的⽂件存储在⼀个节点磁盘上,当有并⾏处理时,每个线程都需要从这个节点磁盘上读取这个⽂件的内容,那么就会出现⽹络瓶颈,不利于分布式的数据处理。
2. HDFS的块
HDFS与其他普通⽂件系统⼀样,同样引⼊了块(Block)
的概念,并且
块的⼤⼩是固定 的。但是不像普通⽂件系统那样⼩,⽽是根据实际需求可以⾃定义的。块是
HDFS
系 统当中的最⼩存储单位,在hadoop2.0
中默认⼤⼩为
128MB
(
hadoop1.x
中的块⼤ ⼩为64M
)。在
HDFS
上的⽂件会被拆分成多个块,每个块作为独⽴的单元进⾏存 储。多个块存放在不同的DataNode
上,
整个过程中
HDFS
系统会保证⼀个块存储在 ⼀个数据节点上 。但值得注意的是,如果某⽂件⼤⼩或者⽂件的最后⼀个块没有到 达128M
,
则不会占据整个块空间
。
我们来看看
HDFS
的设计思想:以下图为例,来进⾏解释。
3. HDFS的块⼤⼩
HDFS上的块⼤⼩为什么会远远⼤于传统⽂件??
1.
⽬的是为了最⼩化寻址开销时间。
在I/O 开销中,机械硬盘的寻址时间是最耗时的部分,⼀旦找到第⼀条记录,剩下 的顺序读取效率是⾮常⾼的,因此以块为单位读写数据,可以尽量减少总的磁盘寻道时 间。HDFS寻址开销不仅包括磁盘寻道开销,还包括数据块的定位开销,当客户端需要 访问⼀个⽂件时,⾸先从名称节点获取组成这个⽂件的数据块的位置列表,然后根据位置 列表获取实际存储各个数据块的数据节点的位置,最后,数据节点根据数据块信息在本地 Linux⽂件系统中找到对应的⽂件,并把数据返回给客户端,设计成⼀个⽐较⼤的块,可 以减少每个块⼉中数据的总的寻址开销,相对降低了单位数据的寻址开销磁盘的寻址时间为⼤约在5~15ms 之间,平均值为 10ms, ⽽最⼩化寻址开销时间普 遍认为占1 秒的百分之⼀是最优的,那么块⼤⼩的选择就参考 1 秒钟的传输速度,⽐如 2010年硬盘的传输速率是 100M/s ,那么就选择块⼤⼩为 128M 。
2. 为了节省内存的使⽤率
此块越⼤,集群相对存储的数据就越多。所以暴漏了 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 的数据,⼩⽂件的存储⽐起⼤⽂件占⽤更多的内存。
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. 块的存储位置
在
hdfs-site.xml
中我们配置过下⾯这个属性,这个属性的值就是块在
linux
系统上 的存储位置
<!-- 确定DFS数据节点应该将其块存储在本地⽂件系统的何处-->
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.tmp.dir}/dfs/data</value>
</property>
6. HDFS的优点
1. ⾼容错性(硬件故障是常态):数据⾃动保存多个副本,副本丢失后,会⾃动恢复2. 适合⼤数据集: GB 、 TB 、甚⾄ PB 级数据、千万规模以上的⽂件数量, 1000 以上节点规模。3. 数据访问: ⼀次性写⼊,多次读取;保证数据⼀致性 , 安全性4. 构建成本低:可以构建在廉价机器上。5. 多种软硬件平台中的可移植性6. ⾼效性: Hadoop 能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因 此处理速度⾮常快。7. ⾼可靠性: Hadoop 的存储和处理数据的能⼒值得⼈们信赖 .
7. HDFS的缺点
1. 不适合做低延迟数据访问:HDFS 的设计⽬标有⼀点是:处理⼤型数据集,⾼吞吐率。这⼀点势必要以⾼延迟 为代价的。因此HDFS 不适合处理⽤户要求的毫秒级的低延迟应⽤请求2. 不适合⼩⽂件存取:⼀个是⼤量⼩⽂件需要消耗⼤量的寻址时间,违反了 HDFS 的尽可能减少寻址时间 ⽐例的设计⽬标。第⼆个是内存有限,⼀个block 元数据⼤内存消耗⼤约为 150 个字节, 存储⼀亿个block 和存储⼀亿个⼩⽂件都会消耗 20G 内存。因此相对来说,⼤⽂件更省内 存。3. 不适合并发写⼊,⽂件随机修改:HDFS 上的⽂件只能拥有⼀个写者,仅仅⽀持 append 操作。不⽀持多⽤户对同⼀个 ⽂件的写操作,以及在⽂件任意位置进⾏修改