分布式文件系统.get(V2)No.106

2018年9月28号,我估计会记得很久这一天,因为那天刚刚好是我来西厂的一周年,那天刚刚好是农历生日,刚刚好那天晚上我挖了一个大坑,跟遣怀师兄和小美姐姐一起填坑到深夜,真是难忘的一天。。。。。

过去的这一年,估计是毕业这几年来比较艰难的一年,毕竟到了新环境,新地方,附近全都是优秀的人,第一次接触互联网产品,第一次接触零售这个行业。但幸运的是我慢慢上手了,以至于很多人其实都不相信其实我仅仅来了一年。来到这里其实我第一个能说上的,就是Owner感,也不知道是为啥,从毕业开始无论做哪个项目,我都没把它们看成是工作,我都把它们看成自己的崽,都是看着它一步一个跟头成长起来的。

看着它不进步了,会想着去找人想办法帮它成长一把。

看着它踩坑了,会想着拉它一把。

看着它走路不稳,会想着怎么帮它健壮一下自己。

看着它闯祸了,会想着怎么帮它擦一下屁股。

这估计就是最大的收获吧,它的成长就是我的成长。

进入正题吧,今天给你们带来了新一版的分布式文件系统,当然这依然是一个KV形式的纯内存分布式文件系统。能做到什么能力呢?很方便的水平扩容(水平收缩现在还没做),比较基础的负载均衡,比较基础的文件检查,职责分离,能用 ls/put/delete/get 这些基础文件操作。

实现的基础论文还是 Google File System,代码都在github上,可以自己下载下来。

https://github.com/CallMeDJ/BigBananaFileSystem.git

现在聊聊怎么启动这套架构。

启动Master

Master 作为整个集群的核心管理单元,需要在第一步骤就起来,Master 承担了文件元数据的管理,ChunkServer的负载均衡,ChunkServer 垃圾回收,ChunkServer 文件检查 等核心能力,是一个一旦不提供服务,整个集群就宕机的存在,当然一般为了稳定会做主备容灾,我在这里没做。

直接跑一下 bfs.server.MasterServer ,启动后MasterServer将会启动一个路径为 rmi://127.0.0.1:8888/master 的 rmi 服务,用来提供给集群中的其他及进行通信。

跑完之后我们会看见。

嗯,看见这个我们就认为稳了,Master 已经起来了,成功了一半。

启动ChunkServer

GFS中,将每一个文件片段叫为一个 Chunk (GFS会将大文件切分为大小一致的块名为 Chunk),所以我们将存储管理这些 Chunk 的服务器叫 ChunkServer。

我们的启动类路径是 bfs.server.ChunkServer ,这个类启动有三个入参,分别是 (ip,端口,最大容量),这三个入参可以让我们非常方便地启动任意数量的 ChunkServer 进行水平扩容,当然我们项目里建议的最小服务数量是3个,不然所有的文件都会堆积在一个服务里面。

启动成功后,我们会看到,ChunkServer 的console 会提示,ChunkServer 自己提供了一个路径为 rmi://127.0.0.1:7081/chunk_server 的 rmi 服务,而且已经注册到了我们前端提供的master服务上。

这时候我们在master 的console 里面,也能看到我们的ChunkServer 成功注册到 Master 的提示。

扩展ChunkServer

为了实验效果,我们把ChunkServer 扩展到4台,端口和容量分别为 7080(50byte 容量) / 7081(75byte容量) / 7082(100byte容量) / 7083(200byte容量) 。

一个一个启动,全部启动完之后,在 master 上可以看到下面的日志,不需要做其他特别的操作,能看到这些这些代表已经启动并且扩容完成

启动 Client

Client 的入口类为 bfs.server.BFSClient ,没有特殊的参数。主要流程是请求master进行数据读取,master 获取数据所有的chunk块的元数据,然后把数据块chunk的位置及 chunkserver 的 ip 和端口给到client,由 client 直接跟 chunkserver 通信进行数据获取。

启动完之后能看到下面的操作提供,则表明client已经启动成功。

put一大批数据

我们在Client的Console敲命令行可以对文件系统进行基础的操作,比如放置文件 。put mytexstt /tmp/banana/trace2.log 等。

这时候我们可以看到 master 上也有存储成功的消息。

我们敲命令行 ls /tmp/banana ,也可以看到文件列表。

同时我们在各个ChunkServer 也能看到文件存储的md5值,完整容量以及已用容量。

PS:关于这里的负载均衡,大家可以通过对比几个 ChunkServer 的增长速度,增长基本是均衡的,不会堆积在某个机器上,最终所有机器基本都被占满,已占满的机器不会再提供存储服务,除非文件被回收。

删除数据

比如我们想删除 trace10.log,我们可以这样敲命令 。

delete /tmp/banana/trace10.log

这时候Master 会把 trace10.log 文件名变更为 trace10.log.delete ,然后通过垃圾回收机制进行回收,我们可以在 Master 上看到这么两行日志。

第一行是代表文件在逻辑层面已经被删除,第二行代表垃圾回收机制已经把文件从元数据和 ChunkServer 上都进行了物理删除。我们可以从各个 ChunkServer 上看到,被切割的文件块也都被逐一删除,并且空间已经回归。

7080机器

7081机器

7082机器

7083机器

从这里我们可以看到,文件被切割成了两个块,而且复制了三个副本,存储在四台机器上,并且 ChunkServer 对这些文件的实际内容以及组织形式完全无感知。

关于文件检查恢复

机制已经实现了,但目前还没有找到很好的测试方法。基本逻辑就是检查Master上存储的md5跟ChunkServer文件提供的md5进行对比,如果不一致那肯定是文件出现了问题,将会对ChunkServer 上的文件块进行删除,并复制其他 ChunkServer 的合法的文件,如果三份都丢失那文件就真的丢失了。

好了,关于分布式文件系统的操作介绍就都在上面了,现在我们聊聊细节。

关于注册

注册是由 ChunkServer 调用 bfs.service.IMasterService#registerChunkServer 进行服务注册的。

关于Client的命令

命令是通过命令控制中心 bfs.command.CommandCenter#execute 进行命令的解析,分发,调用,返回的,所有支持的命令都实现了bfs.command.Command 接口,并且在初始化的时候注册到控制中心中,控制中心持有了 包括 Master 和 所有 ChunkServer 的懒加载单例模式句柄,可以非常方便地访问到集群所有机器的服务。

关于put

主要实现在 bfs.service.impl.BFSMaster#put ,主要逻辑是

1、先对文件进行切分,产生 Chunk并保存文件的源数据。

2、每一个块获取N个需要的可用服务器,并且对服务器容量进行提前占用,防止文件存储过程中的耗时导致超量存储导致磁盘容量溢出。

3、 对文件进行存储,并且存储Chunk 所在的服务器。

4、对服务器占用进行解除。

这里获取可用服务器实现了针对服务器负荷进行排序,优先获取负荷比较小的机器,当然如果机器数量本来就很小,比如我们这里只有4台,基于文件复制的基础要求(文件副本不能全部存储在同一个机器上),会发现一些负荷比较高的机器也会承担文件存储服务。

关于get

get 实现比较简单,只要一个Chunk一个Chunk进行查找,查找到任何一个可用的服务器就直接拿,然后对结果进行顺序拼装即可。


好了,BFS讲解大概就到这里了BFS系统源码的阅读顺序可以参照这个,主要看一个文件的放置,一个文件的获取,一个文件的删除,这三个看完基本就理解了。

bfs.command.CommandCenter 所有操作的控制封装,是 Client 操作的媒介。

bfs.service.IMasterService Master 提供的所有能力的接口

bfs.service.IChunkServerService ChunkServer 提供的所有能力的接口。

再安利一下 https://github.com/CallMeDJ/BigBananaFileSystem.git

再PS:今天我阳历生日,祝我生日快乐。

原文发布于微信公众号 - 一名叫大蕉的程序员(DaBananaTalk)

原文发表时间:2018-10-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏idealclover的填坑日常

从零开始折腾博客(0):静态?动态?

这两天心血来潮,忽然想折腾一个属于自己的博客,也就是这一系列的缘由。而最终也总算是折腾出来了,要不你就不会看到这篇文章了

1531
来自专栏Python中文社区

一键获取免费真实的匿名代理

專 欄 ❈夏洛之枫,从销售转为程序员,Python爬虫爱好者。 github: https://github.com/ShichaoMa/proxy_fact...

2566
来自专栏码神联盟

碎片化 | 第一阶段-06-第一个小程序-视频

如清晰度低,可转PC网页观看高清版本: 第一个java程序Hello word 暂时我们先使用记事本来编写代码,不建议直接使用开发工具eclipse,那都自动生...

3778
来自专栏Python专栏

Python | 利用Python实现微博监控小姐姐动态

作者:奶权 来源:http://www.jianshu.com/p/9e7ba0a0a610

3402
来自专栏原创

五个最佳案例带你解读Node.js的前后之道

Node.js 是什么? Node.js采用C++语言编写而成,浏览器内核V8做为执行引擎;Node不是JS应用、而是一个Javascript的运行环境。Nod...

40010
来自专栏SDNLAB

SDN实战团分享(三十一):Nutanix超融合之架构设计

超融合平台 针对于超融合的概念有着不同的理解,因为组件不同(虚拟化、网络等)而理解不同。然而,核心的概念如下:天然地将两个或多个组件组合到一个独立的单元 中。在...

3967
来自专栏乐沙弥的世界

Percona XtraDB Cluster集群节点重启及故障转移

要重新启动集群节点,请关闭MySQL并重新启动它。该节点将离开集群(并且法定人数的总计数应该减少)。发布命令 systemctl restart mysql

1062
来自专栏张戈的专栏

WordPress发布文章同步到新浪微博失败的问题解决与分享

张戈博客很久之前分享过一篇 WordPress 发布文章同步到新浪微博 的文章,但经常有站长留言反馈同步失败,我一直觉得是代码部署问题。 最近很长一段时间,张戈...

3767
来自专栏tiane12

通过抓包获取ActiveX控件通信数据时的一点心得

1392
来自专栏腾讯移动品质中心TMQ的专栏

30分钟轻松搞定代码瘦身

导语 当一个新的产品想要复用一个旧的产品的逻辑的时候,是直接把全盘的代码copy过去就可以了吗?站在功能的角度当然没问题,但是这对于新产品是相当臃肿的,因为一些...

2569

扫码关注云+社区

领取腾讯云代金券