美文网首页系统设计
Netty 实战之如何设计一个大文件存储系统

Netty 实战之如何设计一个大文件存储系统

作者: 逅弈 | 来源:发表于2018-02-24 23:39 被阅读1001次

    逅弈 转载请注明原创出处,谢谢!

    我们知道随着系统的发展,以往单机的存储系统已经无法满足日益增长的文件存储需求了。急需一种可以存储大量文件、低成本、高扩展、高可用的分布式存储系统。Google的GFS就是这样的一种分布式文件系统。Google File System、Map Reduce、Big Table是Google的三大论文,他们是奠定Google伟大帝国的重要基石。今天我们主要来了解下分布式文件系统,与GFS类似的还有:HDFS、Ceph 、GridFS 、TFS等等。这些文件系统各有各的优点,适用的场景也各不相同,他们的特点不是本文要讨论的重点。今天我要来说的是,怎样设计一个简单的大文件存储系统。

    分布式、集群部署

    首先分布式系统,我想大家都不陌生。说到分布式,肯定要说下集群
    分布式是将不同的业务分布在不同的地方,简单来说就是一个业务分拆多个子业务,部署在不同的服务器上。
    集群是将同一个业务,部署在多个服务器上。
    为了保证系统的高可用性,肯定要通过集群部署;为了保证系统的可扩展性,则要通过分布式部署。

    分块存储

    为了保证一个大文件能快速的存储,可以将文件分块,通过多线程进行并发的存储。读取的时候,也可以通过多线程并发的读取文件块,快速的下载。

    基于以上两点的分析,初步可以得出一个系统的架构:

    [ node ] <--sync--> [ node ] <--sync--> [ node ]
    

    其中每一个node都是集群中的一个节点,主要有以下职责:

    [ node ]  ---store---> disk
    [ node ]  <--restore-- disk
    

    节点之间通过p2p通讯的方式进行数据的同步,保证数据的一致性。这里同步的是文件的元数据metaData。文件的实际数据不需要在每一个node中保存,为了容灾,一般对数据在不同磁盘、不同机架、不同机房保存3个副本。
    除此之外,该系统还需要有以下特点:

    • node是无状态的,每一个node都知道每个文件有多少个文件块,每个文件块存储在哪些node上
    • 当一个node接收到存储请求时,会根据自身情况,确定这些文件块是自己存储还是委托其他node存储
    • 每一个文件块都需要至少保存3个副本
    • 每一个文件的metaData会在所有node上保存
    • node之间需要同步文件块,以保证至少有3个副本
    • 每个node负责文件块的存储的读取

    有了node之后,就有了一个集群,对外一个集群肯定是一个单独的系统,是一个整体。因此,还需要有一个单独的节点来管理所有的node。所以,在系统中增加一个proxy节点。该节点对外充当整个系统的入口,对内则管理所有的node,并给node下发store和restore的指令。调整后的系统架构如下:

        +--------------[ proxy ]---------------+
        |                  |                   |
        v                  v                   v
    [ node ] <--sync--> [ node ] <--sync--> [ node ]
    

    proxy和node之间通过zk进行连接。

    系统启动的流程如下:

    • proxy通过netty开启一个http服务
    • proxy启动后监听zk的/node节点
    • node将自己的ip和port注册到/node节点下,并获知/node节点下其他的node,将其他node的信息保存在内存中
    • proxy收到node上线的通知后,通过netty与node维持一个heartbeat,当node挂掉之后,能够迅速将其移除

    存储文件的流程如下:

    • proxy接收到存储请求后,通过RandomAccessFile的方式将文件分成若干个文件块,并根据文件分成一个唯一的fid,返回给客户端
    • proxy将文件块封装成数据后转发给node,然后给node下发store指令,该过程将轮询转发到不同的node,将文件块分散存储到不同的node中去,在此过程中proxy将在metaData中纪录每个文件块存储在哪些node中
    • node存储完文件块之后,找到其他合适的两个node,将文件块同步过去,保证一个文件块有3个副本
    • node存储完文件块之后,告知proxy,该文件块是由该node自己存储的还是委托其他node存储的,如果是其他node存储的,proxy将要修改metaData
    • metaData准备完毕之后,proxy将广播给所有的node,并下发存储metaData的指令

    下载文件的流程如下:

    • proxy接收到下载文件的请求,得到文件的fid
    • proxy将请求转发给任意一个node
    • node根据fid得到文件的metaData
    • node从metaData中找到文件块存储的位置
    • node将存储文件块的所有位置返回给proxy
    • proxy根据位置到具体的node中并发的请求文件块,返回给客户端

    至此一个简单的大文件分布式存储系统设计完成了,还有许多其他需要考虑的,如:

    • 当某个节点挂了之后,该节点中存储的文件块应该要同步到其他节点中
    • 节点恢复后其他节点备份的该节点的文件块该如何处理
    • 每个节点应该要监控磁盘的容量,当容量小于某个阈值时,不能再进行写入操作

    以上是我的一点思考,肯定有不到位的地方,欢迎大家批评指正,如果您有更好的方法或建议,欢迎分享。

    更多原创好文,请关注「逅弈逐码」

    相关文章

      网友评论

        本文标题:Netty 实战之如何设计一个大文件存储系统

        本文链接:https://www.haomeiwen.com/subject/yubcxftx.html