思考:关于存储的解决方案

有空思考一下几种场景下的文件存储方案。

场景 1. Web 静态资源

小文件,绝大部分都是 KB 级别,简单读写,不需要元数据。
文件系统即可。

生产环境中直接配好 Web Server,用上 HTTP 缓存机制和服务器自带缓存模块即可。
如果并发大,可以考虑配上专门的 HTTP 缓存服务,或者 CDN。
干脆直接 CDN 吧,我还没有在生产环境配过 Squid,Vanish。这个云计算的时代,对于绝大多数公司来说,基础服务还是用现成的方便、省事、成本低。

著名的 PHP 模板引擎 Smarty 支持将模板渲染结果(静态 HTML 页面)存储在 Memcache 中。
服务器缓存可以充分用上,提升最大并发数。

拓展:Linux 内核 HTTP 服务器:

  • kHTTPd
  • RedHat 也以内核补丁的方式提供了一个 TUX HTTP 服务器

场景 2. 虚拟化中的卷存储,镜像存储

超大文件,需要元数据,只适合用文件系统存储。
我之前项目所做的方案基本上都是专用的存储服务器,专用的数据网络,然后走 iSCSI 或 FC 协议。

场景 3. 邮件系统中的邮件

绝大部分文件不大,大概 90% 小于 100K,99% 小于 1M,99.9% 小于 10 M。
邮件相关的元数据部分以二进制方式写在文件头部。
总的来说,也可以理解成简单读写。

我们目前使用 MongoDB(小文件)+ 自研的分布式存储方案(大文件)。
我觉得要是我的话,会尝试上对象存储。不必存些二进制数据在文件头部,丑死了!
但是,我没有很多具体实施经验,而且现在的存储方案运行良好,不存在性能瓶颈,所以我还是闭嘴好了。

场景 4. 大量图片,音频,视频(二进制)

这几种数据各有各的特点:

  1. 图片需要生成各种尺寸的缩略图。
  2. 视频需要生成快照,甚至需要抽指定帧,还可能需要视频流支持,读取数据中的指定一部分。
  3. 音频也有音频流的说法。

这几种媒体文件,都:

  1. 支持大量元数据字段,大多数情况下,网络传输中都会清掉的吧,只会保留部分信息。
    这些元数据可能包含很多用户隐私,网络传输时,只保留“安全”且必要的信息一了百了,当然,简单的存储服务,而且是用户自身的上传下载行为除外。
  2. 有审核需求。重点审查用户名单,重点审查内容名单,

可以考虑:

  1. 数据库 + 文件系统
  2. 分布式对象存储
  3. 特殊的存储服务,比如 MongoDB(GirdFS),HDFS,Cassandra

场景 5. 大量日志(文本)

日志需要检索。

基本上我所经历的线上服务,日志规模都不小。
单说现在的邮件短信发送业务,单个服务节点一天就能积累上几 G,甚至十几二十 G 的日志,整个产品线上几百台机器,总共上千 G 日志都可能有。

日志怎么写,怎么存,怎么用,另说。这里单讨论文本类型文件存储的问题。

如果不做过滤,一股脑都收集起来,也需要不少空间来做存储。
假设一天只消耗实际存储空间 100 GB,存 30 天,大概 3TB,那线上至少翻一番 —— 准备 6TB 空间。算下来,一年总要花个上几万(钱可不是大风刮来的,小公司还是节约一点吧)。

还是只能回到日志这个业务来讨论,脱离场景,感觉不知道从那里着手。

  1. 生产环境的日志必须是调试必要的信息。
  2. 正常日志保留时间不要多久,顶多一周。
  3. 异常情况就保留久一些,比如一个月。
  4. 日志必须用来分析,从中得到有用信息,定期自动报告,然后大家要重视。
    否则相当于只管存删,没有意义。

我没有使用过远程的日志服务,无一例外,都是直接写在本地机器上的日志文件中。
写在本地服务上可以减少与其他服务的依赖,系统简单可靠一些。如果需要的话,再用第三方服务来传输日志数据。