这是《漫谈分布式系统》系列的第 4 篇,预计会写 30 篇左右。每篇文末有为懒人准备的 TL;DR,还有给勤奋者的关联阅读。扫描文末二维码,关注公众号,听我娓娓道来。也欢迎转发朋友圈分享给更多人。
上一篇 漫谈分布式系统(3) -- 再也不怕存不下,我们以 HDFS 为例,讲了分布式存储系统怎么解决数据存不下的问题。
但是光存得下还不够,还要存的好。
因为海量数据带来的就是海量成本。存得不好,就是糟蹋钱。
1
删数据这个办法,乍一听很无厘头,但其实简单粗暴有效。很多情况下,很多数据其实都是可以删的,比如:
5 年前的旧数据,已经没有时效性了,可能再也不会用了。
临时数据、中间结果等,用完忘了删。
同样的数据,不同业务甚至不同人都各自维护了一份,冗余而不自知。
类似这样的数据,就静静躺在那里,消耗着无谓的成本。
当然,要做到能删而敢删,就需要我们对数据的使用情况、血缘关系有足够的掌握了,配套的程序和数据支持得跟上。
这个办法乍一听也很无厘头。本来就是为了高可用才弄多副本,减少副本,不就降低可用性了吗?
这话没错,所以减副本这个办法不应该大面积使用。像我所在的公司,就用在 temp 库上。这个库的顾名思义就是存放临时数据的,没有那么多的使用限制。也正因为限制少,所以很容易变成垃圾场,并且越堆越大。
所以我们把这个 temp 库的副本数设置成 2,直接就节省了几百万的成本。
我们敢这么做,一方面是因为这个数据就算真丢了也没多大影响;另一方面,是考虑到当集群规模足够大,网络带宽也足够大后,个别机器宕机,能够在很短时间内就从其他机器上补齐丢失的副本。
当然,只是风险小,不是没风险,所以慎用。
另外,HDFS RAID 也是可以考虑的方式,本质上也是降副本。像 Facebook、腾讯等大厂已经自己实现并应用在生产了,Hadoop 3.0 也会通过纠删码的方式提供支持。
大家都知道,压缩是节省空间最重要也是最常规的方式。
在海量数据的场景下,压缩的效果和节省的成本会更加可观。当然,也有几个方面需要重点关注:
压缩/解压速度和压缩比的平衡。典型的效果和效率的 trade-off,所以很多场景下会选择 snappy 这种比较平衡的压缩算法。
splittable,也就是可切分。在 MapReduce 这样的计算模型下,如果一个文件过大又不可切分,那就只能被一个任务处理,而没法分配给多个任务并行处理,自然会拖慢整体性能。不是所有压缩格式都支持切分的,这又是一个要取舍的点。
文件格式的选择。最常见的 TextFile 其实效率不好,而类似 Avro、ORC 和 Parquet 这样的格式通常会有更好的效率。尤其列式存储的格式,由于同样列的数据往往接近,存在一起后通常会有更好的压缩效果。
谁都想更快的访问数据,但速度快带来的就是成本高,所以只能按需选择不同的存储介质。像我们熟知的内存和硬盘。更广义的,这类介质可以叫做异构存储(heterogeneous storage)。
分层存储的思想,就是根据数据的冷热来选择不同的存储介质。最热的数据放在内存,次热的放在 SSD,温的放在 SATA 等等。除了像 HDFS 原生支持的层次,还可以考虑结合 Alluxio 等方案。
访问多和访问性能要求高的数据,就放在热存储上,通常数据量级比较小。访问少和访问性能要求低的数据,就放在冷存储上,通常数据量级比较大。
存储层级越多,在平衡性能和成本的时候,就能有更多的选择和更精细的控制。
和删数据一样,需要对数据的访问情况有足够的掌握。这样才能划分出数据的冷热, 然后把不同冷热的数据存放到不同的介质上,保障性能的同时,也节省成本。
2
大家一定听说过数据本地性(data locality),也知道数据本地性对提升性能非常重要。我们平时用的数据处理框架,比如 MapReduce、Spark 等等,都针对数据本地性做了优化。
数据本地性,或者换个说法,存储和计算耦合(aggregated),初衷很好理解,尽可能减少网络 IO,性能自然能提升了。
存储和计算耦合的做法也很简单,比起把数据传输给代码,把代码传输给数据,显然代价要小得多。
然而,随着网络设备性能的大幅提升,网络 IO 已经不在是性能瓶颈了。万兆网卡基本是标配,再加上网卡绑定等扩展功能,服务器的网络性能有了 1-2 个数量级的提升。同样,交换机性能也得到了数量级的提升。
而与此同时,磁盘 IO 性能却仅仅提升了 1-2 倍。CPU 的性能提升,也逐渐难以跟上摩尔定律的步伐。
这就导致了数据处理的瓶颈,从网络 IO 变成了磁盘 IO 或 CPU。也就使得存储和计算耦合失去了必要性。
而另一方面,耦合的存储和计算,一直以来都有无法回避的弊端:
资源管理和协调复杂。CPU 和内存相对好管理,网络 IO 就复杂多变了,要么不考虑,要么就很复杂。
存储和计算资源扩缩容互相拖累。存储资源不够需要扩容,会导致计算资源被动扩容浪费;计算资源多余需要下线,又可能带来数据的被动迁移甚至丢失。
云服务兼容性不佳。目前主流的通用云服务,默认磁盘就在远端,所谓的数据本地性已经没有意义,反倒成了限制。
这样,存储和计算分离(disaggregated)的架构也就成了自然的选择。
而存储和计算的分离,也就为节省成本扫清了障碍。
存储资源不足,只用买些大硬盘小 CPU 内存机器就好,不用付出额外的计算资源硬件成本。
计算资源不足,只用买些小硬盘大 CPU 内存机器就好,不用付出额外的存储资源硬件成本。
海量数据带来的就是海量成本。需要尽可能调整数据存储方式,以节省成本。
很旧的、临时的数据,考虑直接删掉。
删不掉但又不重要的数据,考虑降低副本。
压缩是最通用的节省空间的办法,需要平衡压缩率和速度,考虑文件可切分,善用列式存储。
按数据冷热做分层存储,能有效节省成本。
数据本地性不再那么重要,存储和计算分离带来灵活性,也能大幅节省成本。
数据访问记录和血缘关系很重要,是调整存储策略的直接依据。
最近两篇,我们聊了分布式存储的基本内容,解决了存不下和存不好的问题。下面两篇,我们一起看看,怎样解决算的慢的问题。
关联阅读
原创不易
关注/分享/赞赏
给我坚持的动力
点在看,给大家好看