分布式技术,在保障高可用和容错或弹性时,一般常用这两种手段:
复制
分区
对应英语一个是replication, 一个是partition。
复制,是把每次写入的数据多保存 N 份,这样在出故障的时候可以用来恢复,同时也可以进行读写分离,缓解读的压力。分区则是在数据超越了单台存储能力的时候,按一定规则分多台存储。分区的数据其实也是有复制的存在来保障这一个partition的数据不丢失。
复制了就可以高枕无忧了?
这都是理想情况,实际上每天都会出现机房故障,硬盘损坏,失误断电等等问题。
比如咱们自己把手机上的照片、文件等等备份到网盘,手机一清理, 欣喜腾出不少空间。某天去看的时候,网盘里一部分数据找不到了,客服告诉你某天机房备份文件的硬盘坏了,再也找不回来,你啥感觉?
你肯定愤怒的问客服为啥不再多存几份。可如果是整个硬盘所在机架都挂了呢?
和咱们搭应用的服务一样,为了应对问题,保证高可用,除了不出现单点,还得考虑实例部署在不同的机房,这样就算某个机房都出问题的时候,另一个机房也还能扛着。
对应到数据的复制和备份上,聪明的脑袋们想出了类似的思路,将备份存在不同的硬盘,不同的机架,甚至不同的机房上,像兔子一样,做到
「狡兔三窟」。 :-)
咱们一般使用网盘,云服务厂商提供的各类存储,背后都有一个分布式的存储服务,来保证应用的高可用,弹性容错等等,像咱们之前分享的神书 DDIA 里许多技术都在这些服务里有使用。
HDFS 做为Hadoop的核心存储实现,内部也支持这种更安全的多地存储备份实现。在 HDFS 中,这一技术称为 Rack Awareness。
Rack 就是机架,是在机房或者数据中心里存储着一堆的物理机,通过网络的技术来管理。
在 Hadoop 里为了在一个集群里提升网络读写 HDFS 文件的速度,管理MetaData信息的 NameNode 会根据 Rack 就近选取 DataNode去
读写。毕竟 NameNode存放着 rack id 和 DataNode 的对应信息,我们的备份数据真正写到了 DataNode里。rack id 相当于代号。
NameNode 根据 Rack id 选择一个更近的 DataNode 的过程,称之为 Rack Awareness。
默认的 Hadoop 按照所有的DataNode 属于同一个 Rack。这样就容易出问题,而打开 Awareness之后,效果类似下面这个图,
我们保存文件的时候,文件会被分成以128M为大小的 Block,之然通过NameNode来获得具体保存数据的DataNode 地址,默认是3 个备份,遵循的原则是「每个block,两个备份存在同一个 rack,第三个备份存在另一个不同的rack上」。这一规则也称为 Replica Placement Policy。
具体存放时如何确定放到哪个rack上?我们前面提到是通过 rack id 来判断的, HDFS 内部是可以通过执行一个外部脚本或者是在配置文件中指定一个 Java类来获得。
以下是官方文档给出的一个python 的例子
为什么需要 Rack Awareness?
可以保证数据的高可用和可依赖性
提升集群的性能
在整个 Rack 出现故障时避免数据丢失
相关阅读
更多常见问题,请关注公众号,在菜单「常见问题」中查看。
源码|实战|成长|职场
这里是「Tomcat那些事儿」
请留下你的足迹
我们一起「终身成长」