专栏首页林德熙的博客大文件的存储和备份

大文件的存储和备份

今天我和大家讲一个算法,这个算法用于大量的文件存储和高速读取、备份。

大概这个算法是现在世界上最好的存储算法之一,原因是他的论文发在 SCI 上,现在还没有人写出一个比他好的算法。

SCI 是国际论文最顶级的发布地,所以质量还是可以相信。这个算法是理论上最好,实际使用可能需要修改好多。

因为我们公司遇到一个存储上的困难,做的产品好像是 PPT 一样的,但是要把所有的数据存放到自己的服务器,那么如何存在服务器可以让大量的用户存放不会出现明显的卡顿和已经存放了大量的数据,如何快速读取用户想要的数据。这就是我看到的问题。

因为我不是负责这一块,但我听说我师兄之前讲个的这个算法,于是拿过来用,至于是不是一个好的算法,我也不知道。

在实验室,可以不知道产品是怎样,设计出一个算法,并且说这是一个好的算法。但是在实际的开发,必须知道产品的需求,于是就不能直接使用算法,需要对算法进行修改。

看过 Hadoop 的算法,原来的 Hadoop 是不建议人们对传上去的文件修改。但实际上,可能是存在经常修改的文件。对于 Hadoop ,难以做历史记录,后来我问过另一个师兄,他说是可以做到的,不过渣渣不懂师兄说的如何做。

于是我想做的是一个支持修改的存储,可以无限历史还原,可以快速读取的系统。于是参见了惠普使用的方法,和之前听说的方法。这个方法没有实际去试,所以好不好,我也不敢说。

惠普的方法,主要是文件分块,其它的是如何存储。文件分块是为了:方便存储,第二是方便修改后的存储。这里需要说一些,对于一个很大的文件,需要把他分为多个小文件存储,不能自己存放大的文件。原因是当修改一个很大的文件一小点,如果不把一个大文件分块,就需要上传整个文件。一旦把文件分块,那么可以上传修改的块就好,至于修改上传的块之后如何去更新,这个在下面会说到。文件的分块不是可以随意分的,需要考虑分块的大小和分块之后是不是一次修改刚好会修改在多个块而不是在一个块。

那么我的文件分块是不是最难的,其实相反,文件分块是最简单的,刚好产品是PPT差不多的样子,一个页就可以分一块。

那么来说下算法是如何做:第一步,按照文件页,把文件分为多块。注意,这里的分块和存储的分块不是一样的,文件存储分块的层和他不在同一层。第二步,生成每个页的 ID ,生成的方法可以使用 sha 或 MD5加上作者和文件信息。注意,生成的 ID 是在全局要求极低的重复率。

那么存储的文件是什么,其实是一些 ID 。

如果要获取文件,那么首先需要存储的是文件的 ID ,然后系统提供输入 文件的 ID 返回文件内容块 ID 的 API 。于是文件 ID 就可以获取文件块 ID 。系统还有一个 API ,输入文件块 ID 就可以获得文件块内容,于是可以用这个方法来获得文件。需要说的是,第一个 API ,返回文件块 ID 的那个 API 和第二个 API 其实是相同的。只是第一个 API 把文件块 ID 存储为内容,第二个 API 是把文件内容存储为内容。

这么做的好处:

  • 用户经常的修改只有修改某些页,而且很多的文件都使用复制粘贴页,所以存在页的重复比较多,存储可以复用比较多。实际使用,我是推荐去挖掘一下一个用户存放的 文件 相同最多是什么,和所有用户存放的文件相同最多的是什么,这样来分块会比较好。

文件知道他的内容 ID ,不知道他的实际内容,于是多个文件存在相同的页面就会在系统只存在一个块,一个块提供多个文件引用。

  • 对于用户修改某些页,可以通过上传用户更新的页,然后修改文件ID包含文件块ID的顺序等来更新文件。

如果用户文件ID包含了历史记录的属性,那么只需要把历史记录设为前一个版本的ID就好了,因为前一个版本的ID就记录了他的文件内容ID,这样可以只需要更新版本ID和更新内容ID就好了。

实际上因为和业务需求不同,所以这个算法是没有效率的。所有的文件都是小文件,假如有1k,里面重复最大的页只有 200b ,但是一个 ID ,其它的页,最小的只有 10b 于是,存 ID 的数据就比存数据的,有时候要大得多,所以这个方法最后不使用。

参见:

惠普使用的方法:http://www.hpl.hp.com/techreports/2005/HPL-2005-30R1.html

https://www.computer.org/csdl/trans/tc/2011/06/ttc2011060824-abs.html


本文会经常更新,请阅读原文: https://lindexi.gitee.io/lindexi/post/%E5%A4%A7%E6%96%87%E4%BB%B6%E7%9A%84%E5%AD%98%E5%82%A8%E5%92%8C%E5%A4%87%E4%BB%BD.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://lindexi.gitee.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • jsonp总结

    由于浏览器有同略策略,但是<script>标签的src可以跨域,利用这个"漏洞"搞事,具体做法是: 服务端地址(比如 http://api.xxx.com/j...

    mafeifan
  • 关于数据结构的一点唠叨

    现在大部分高级编程语言的标准库都会提供几种常用的数据结构,诸如线性表、链表、栈、队列、哈希表等等,可以满足日常开发中的大部分需求,开发人员只要调用接口就行了。这...

    Sheepy
  • 开源项目——『看知乎』iOS 版

    前段时间无意中发现了看知乎,一个知乎答案和用户的精选站。网站开发者是知乎用户苏莉安,他写了个爬虫从知乎抓取数据,而且还提供了 API 文档。我大致看了下文档,感...

    Sheepy
  • react学习系列3 使用koa-router模拟后台接口

    当用create-react-app创建好项目,启动后会自动打开 localhost:3000。 我们希望当访问 localhost:3000/api/tod...

    mafeifan
  • Laravel Vue 前后端分离 使用token认证

    在做前后台分离的项目中,认证是必须的,由于http是无状态的。前台用户登录成功后,后台给前台返回token。之后前台给后台发请求每次携带token。

    mafeifan
  • GraphQL 分享 理论篇

    目前项目开发比较流行的是前台后分离模式,后台提供接口,前台调用接口,接口书写遵循流行的RESTful API规范

    mafeifan
  • Swift API 设计指南(上)

    本文翻译自苹果官方文档:Swift API Design Guidelines,如有错漏,欢迎指出。

    Sheepy
  • 记一次通过c#运用GraphQL调用Github api

      最近在折腾使用Github api做个微信小程序练练手,本篇文章就是在这个过程中记录。

    Zachary_ZF
  • Java核心API需要掌握的程度

    最近总结,发现自己没啥提升,准备开始练级,记下这个,给自己一个目标。Java的核心API是非常庞大的,这给开发者来说带来了很大的方便,经常人有评论,java让程...

    Allen Cheng
  • 一个比较扯淡的跨域问题

    2018-08-27更新: 使用cookie前强烈建议先看下MDN的这篇基础文章 创建cookie可以配置的选项 Expires,Secure,HttpOn...

    mafeifan

扫码关注云+社区

领取腾讯云代金券