20

漫谈分布式系统(四):存的下,还要存的好

 4 years ago
source link: https://mp.weixin.qq.com/s/4shPDRfxg2jhlP8yc3RqpQ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

这是《漫谈分布式系统》系列的第 4 篇,预计会写 30 篇左右。每篇文末有为懒人准备的 TL;DR,还有给勤奋者的关联阅读。扫描文末二维码,关注公众号,听我娓娓道来。也欢迎转发朋友圈分享给更多人。   

上一篇 漫谈分布式系统(3) -- 再也不怕存不下 ,我们以 HDFS 为例,讲了分布式存储系统怎么解决数据存不下的问题。

但是光存得下还不够,还要存的好。

因为海量数据带来的就是海量成本。存得不好,就是糟蹋钱。

其实之前已经单独写过一篇文章说这个话 题了,第 1 节就整理下要点,第 2 节再补充另一个重要的点。

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 内存机器就好,不用付出额外的存储资源硬件成本。

TL;DR

海量数据带来的就是海量成本。需要尽可能调整数据存储方式,以节省成本。

  • 很旧的、临时的数据,考虑直接删掉。

  • 删不掉但又不重要的数据,考虑降低副本。

  • 压缩是最通用的节省空间的办法,需要平衡压缩率和速度,考虑文件可切分,善用列式存储。

  • 按数据冷热做分层存储,能有效节省成本。

  • 数据本地性不再那么重要,存储和计算分离带来灵活性,也能大幅节省成本。

  • 数据访问记录和血缘关系很重要,是调整存储策略的直接依据。

最近两篇,我们聊了分布式存储的基本内容,解决了存不下和存不好的问题。下面两篇,我们一起看看,怎样解决算的慢的问题。

原创不易

关注/分享/赞赏

给我坚持的动力

yEfMje3.jpg!web

点在看,给大家好看


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK