图3(a)中显示了N个客户端的总读取速率和它的理论极限 。当两个交换机之间的1Gpbs链路饱和时,理论极限为125MB/s , 或者当客户端的网络接口达到饱和时,每个客户端的理论极限为12.5MB/s , 无论哪个都适用 。当只有一个客户端进行读取时 , 观测到的读取速率为10MB/s,或者是每个客户端极限的80% 。对于16个读操作,总速率可以达到94MB/s , 大约是125MB/s网络极限的75%,或者是每个客户端到达6MB/s的速率 。效率从80%下降到75%的原因是,当读取操作的数量增加时,多个读操可能同时的从同一个块服务器上读取数据 。
6.1.2 写操作N个客户端同时往N个不同文件进行写操作 。每个客户端以每次1MB的速率向一个新文件写入1GB的数据 。总的写入速率和理论极限显示在图3(b)中 。理论极限是67MB/s , 因为我们需要把每个字节都写入到16个块服务器中的3个,而每个块服务器的输入连接极限为12.5MB/s 。
每个客户端的写入速率为6.3MB/s , 大约是极限的一半,主要的原因是我们的网络协议栈 , 它与我们用于推送块副本的管道(pipelining)方式不太适应 。从一个副本到另一个副本传播数据的延迟降低了整个系统的写入速率 。
16个客户端的总写入速率达到35MB/s(每个客户端的速率大概是2.2MB/s),大约是理论极限的一半 。与多个客户端进行读操作的情况类似,由于进行写操作的客户端数量的增加,客户端同时向同一个块服务器写入的几率也会增加 。此外,写操作冲突的几率比读操作的要更大,因为每次写操作需要涉及三个不同的副本 。
写操作比我们想要的要慢,在实际中,这不会成为一个主要的问题,因为即使对于单个客户端它也增加了时延,但是对于含有大量客户端的系统来说,它不会对系统的写入带宽有太大影响 。
6.1.3 记录追加图3(c)显示了记录追加的性能,N个客户端同时向一个单独的文件追加数据 。性能受存储文件最后一个块的块服务器的网络带宽的限制,而不是客户端的数量 。它的速率由一个客户端的6MB/s下降到16个客户端的4.8MB/s,主要是由冲突和不同客户端的网络传输速率不同造成的 。
我们的应用倾向于同时处理多个这样的文件 。换句话说,N个客户端同时向M个共享文件追加数据,N和M在0到几百之间 。因此,在我们的经验中,块服务器网络冲突在实际中不是一个严重的问题,因为当块服务器正在忙于处理一个文件时,客户端可以进行另一个文件的写入操作 。
6.2 实际应用中的集群我们现在测试了两个Google正在使用的集群 , 它们有一定的代表性 。集群A通常用于上百个工程师进行研究和开发 。一个普通的任务被人为初始化,并运行几个小时,它读取几MB到几TB的数据,进行转换或分析数据,并将结果写回到集群中 。集群B主要用于生产数据的处理 。在很少人为干预下,这些任务运行更长的时间,持续的产生和处理几TB的数据集 。在这两个实例中,一个单独的任务由运行在很多机器上的很多进程同时读和写很多文件组成 。
6.2.1 存储

文章插图
表2:两个GFS集群的属性
如表2的前五个条目所示 , 两个集群都有上百个块服务器,支持数TB的磁盘空间 , 存储了大小合适的数据,但没有占满 。“已使用空间”包括所有的块副本 。实际上,所有的文件都有三个副本 , 因此,集群实际上存储了18TB和52TB的文件数据 。
两个集群的文件数量相近,不过B含有更大比例的死文件,死文件是指被删除或者被新版本替换的文件,但它们的存储空间还没有被回收 。它也存储了更多的块,因为它的文件较大 。
6.2.2 元数据块服务器总共存储了数10GB的元数据,大多数是用户数据64KB的block的校验和 。块服务器上其它的元数据则是4.5节讨论的块版本号 。
Master上的元数据要小很多,只有几十MB , 或者说,每个文件平均有100字节的元数据 。这符合我们对Master内存在实际中不会限制系统能力的设想 。大多数的文件元数据是以前缀压缩方式存放的文件名,其它的元数据包括文件的所有者和权限 , 文件到块的映射表,以及每个块的当前版本号 。此外,还为每个块存储了当前副本的位置信息和引用计数用来实现写时拷贝(COW) 。
每个单独的服务器,不论是块服务器还是Master,只有50-100MB的元数据 。因此恢复速度很快:在服务器能够应答请求之前,它会只花费几秒时间先从磁盘中读取元数据 。然而,主节点会持续颠簸一段时间,通常是30秒-60秒,直到它从所有的块服务器上获取到块位置信息 。
推荐阅读
- JAVA的File对象
- Codeforces 1670 E. Hemose on the Tree
- 二 沁恒CH32V003: Ubuntu20.04 MRS和Makefile开发环境配置
- 驱动开发:内核监控FileObject文件回调
- 齐博X1-栏目的调用2
- Blazor组件自做十一 : File System Access 文件系统访问 组件
- How to get the return value of the setTimeout inner function in js All In One
- System.IO.FileSystemWatcher的坑
- Docker | dockerfile构建centos镜像,以及CMD和ENTRYPOINT的区别
- prometheus监控实战