分布式文件系统.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 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

Python黑科技:利用Python实现微博监控小姐姐动态

? 0x00 前言: ? 前几个星期在写一个微博监控系统 可谓是一波三折啊 获取到微博后因为一些字符编码问题 导致心态爆炸开发中断 但是就在昨天发现了另外一个...

5005
来自专栏CSDN技术头条

RebornDB:下一代分布式Key-Value数据库

现实世界有许多的Key-Value数据库,它们都被广泛应用于很多系统。比如,我们能够用Memcached数据库存储一个MySQL查询结果集给后续相同的查询使用,...

28710
来自专栏tiane12

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

1292
来自专栏Python中文社区

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

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

2296
来自专栏乐沙弥的世界

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

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

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

30分钟轻松搞定代码瘦身

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

2319
来自专栏张戈的专栏

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

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

3617
来自专栏腾讯Bugly的专栏

Android 插件技术实战总结

前言 安卓应用开发的大量难题,其实最后都需要插件技术去解决。 现今插件技术的使用非常普遍,比如微信、QQ、淘宝、天猫、空间、携程、大众点评、手机管家等等这些大家...

3756
来自专栏程序员互动联盟

【答疑释惑 第十讲】如何在windows下学习linux?

疑惑一 现在手游的server 端,一般都用哪种语言开发? 业界主要的是c/c++ + Python/lua模式做游戏服务器。c/c++做网络通讯数据传输,py...

3555
来自专栏前端vue

Vue自定义弹窗组件(一)npm包管理

npm 为你和你的团队打开了连接整个 JavaScript 天才世界的一扇大门。它是世界上最大的软件注册表,每星期大约有 30 亿次的下载量,包含超过 6000...

2413

扫码关注云+社区