继续分布式系统的设计图解,下半部分是基础设施,此篇是分布式文件系统。这里面典型就是 GFS,对应开源的版本就是 HDFS。
既然谈到分布式文件系统,我觉得需要从需求层面做一个简单的说明:
- 这里的文件,通常以 “大” 文件为主,越大效率越高,而不会是小文件。小文件的存储,不一定要选择这里说的分布式文件系统——功能上当然行得通,但容易造成效率低下(比如因为元数据占比高,或者是单一 chunk 容易成为请求的热点),通常它们可以存放到某一种 NoSQL 的数据库中去,并辅以其它优化。小文件如果就是要使用分布式文件系统,在存储上需要做一定的额外优化,比如在 GFS 上实现的 Bigtable(多个小文件可以共享同一个 chunk)。
- 文件的读取功能上支持随机读取,但是主要的模式还是流式读取;修改方面,支持文件随机位置的修改,但主要的模式还是追加写入。文件的读写可以在同一个块上同时进行。
- Throughput 优于 latency,优先考虑大规模数据操作的吞吐量,而并非单个文件操作对于低延迟的追求。
- 图中虚线是控制流,实线是数据流。
- Master 是单一节点,这样整个结构比较简单。Master 上存放了文件的元信息,以及文件内部的偏移量所对应的 Chunk。 Master 利用 snapshot log 的方式来记录当前状态,备用 Master 可以根据它们迅速接管并还原之前的状态 。
- 整个过程上,Master 最容易成为瓶颈,因此要尽可能地给它减负。比如:
- 读写实际的数据,Client 直接和 Chunk Server 交流;
- 给文件分割存放到不同的 chunk 中,这个分割操作由 Client 直接完成;
- Master 返回 chunk 信息的时候,可以批量返回多个 chunk 信息,而即便是一个 chunk,也可以包含一个 replica 的列表,用于客户端在第一个失败以后可以直接尝试第二个;
- Master 内存中缓存一份完整的文件元信息和 Chunk Server 的路由信息;
- Chunk Server 定期主动给 Master 发心跳,而不是由 Master 发起;
- Replica 授权给 Chunk Server 和 Client 配合来完成数据冗余的过程,而不是由 Master 直接管理。
- Chunk 大小是固定的,比如 64M,固定大小便于索引和查询过程中计算位置,无论是校验、冗余还是读写操作,都是以 chunk 为基本单元完成。
- 如果 chunk 的大小太小,就会导致元信息数量过大,加重 Master 的负担,读写操作也要更多次的连接建立等操作,效率降低;
- 如果太大,则意味着 chunk 重传等操作的代价过大,磁盘利用率低,这里面有一个平衡。
- GFS 的元数据对应条目和实际 chunk 大小的比例可达 1/1M,即 64Byte 的元数据条目可以管理 64MB 的 chunk。当然,实际在传输的过程中,并不一定要完成 64M 全部传输才校验一次,在每小块(例如 64KB)传输完毕后就可以做这一小块的校验以提早发现错误。
- 关于小文件单一 chunk 容易引发热点(hot spot)的问题:如果文件只有单一 chunk,那么读取文件的请求落到同一个 chunk 上,就容易把系统冲垮;但是大文件由于分布在多个 chunk 上,读取整个文件需要读取多个 chunk,那么相应地单一 chunk 同一时间承载的压力往往就小。小文件的一种优化方式是增加 replica,从而分散读压力。
- 图中的写入过程分为四步:
- 1、Client 向 Master 提交写文件的某一个 chunk 的请求;
- 2、Master 返回给 Client 具体的 Chunk Server 和 chunk 的位置;
- 3、Client 直接和所有 replica 的 Chunk Server 沟通,完成写入,并告知主 replica 这一情况;
- 4、主 replica 的 Chunk Server 和所有副 replica 谈话得知,所有写入确实都已完成,便告知 Master 整个 chunk 写入都已完成(这个告知一定来自 Chunk Server,而不是 Client)。
- 对于写入的过程中,Client 需要写入多个备份,这个备份信息是记录在 Chunk Server 中的。这个过程可以并行写,但是 Chunk Server 之间通信,并根据逻辑时钟来保证写入顺序的准确性,这个顺序由拿到 lease 的主 Chunk Server 来确定。
- 读的过程没有图示表示,但是大致思路还是类似的,Client 从 Master 取得相应的 Chunk Server 的位置,然后 Client 直接从 Chunk Server 去读。
- 当某一个 Chunk Server 自检发现某一个 chunk 的 checksum 匹配不上,说明数据损坏,它会询问 Master 获得其它数据备份(其它 Chunk Server)的位置,这样它就可以从其它的备份中读取过来写入恢复。备份一般存两份,一份近(primary site),一份远(disaster site)。近的一份保证恢复的过程读取速度很快;远的一份用来保证整个 site 出问题的时候还有数据备份。
文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》