这几周主要都在推进 DRDS 的产品化这件事,比较忙,现在终于有点时间来更新 blog 了。。看目录决定要写些什么的时候发现,虽然从顺序上应该去深入介绍 MVCC 和锁的实现,但看了之前写的博客的内容,很多想介绍的核心原理核心思想都有提及,所以就不知道应该怎么接续的深入写下去了。或许等以后,把所有的文章的结构重新梳理一下,就可以针对一些之前没深入下去的部分做一些扩展了 ~
本周,我将正式的进入我比较擅长的部分 ~ 分布式存储领域,我在阿里做了这么几年,基本都在做这块的事情。各位能耐着性子看我之前的博客,相信对于我讲解分布式存储的期待也是重要的一个理由吧 ~~ 笑
从我个人来看,分布式存储和单机存储在设计目标上而言,并无明显不同,都是为了让用户能够以更快的速度,更方便的方式将数据存储或读取出来而设计的。
然而,为何分布式存储会越来越受到重视呢?我想原因非常简单:需求驱动。
20 年前,计算机还只是个辅助工具,他处理的主要场景是: 企业内几千人需要无纸化办公、图书馆里有几十万本书需要管理和查询等等场景,数据量不过几百 GB ,应用人数最多也就几千人。
然而,随着互联网时代的到来,计算机要管理的数据量成指数级别的飞速上涨,从几百 GB 到几千 GB ,甚至几个 TB 的数据,而需要计算机系统所支持的用户数也从几千人突然变成了几百万甚至几亿人了。
面对这么大的数据量,这么多的用户数,原来的单机体系结构中天生存在着的扩展天花板,对于新的需求来说就越来越力不从心了。
这时候,分布式系统就自然而然的进入了人们的视野:使用标准的兼容机 Server ,可以按照需要动态增加或减少机器,无论有多少用户,无论有多少数据,代码都不用做调整就可以完美处理。 这样的系统如果再能满足原有单机系统的各类功能,那看起来是真的非常完美啊~ 这世界上未来就一定都是分布式系统了。
且慢,分布式系统的各类理论研究,在上世纪 70 年代的时候就已经非常完备了,那么经过了近半个世纪的实践,为何至今单机存储仍然能够占据市场的主流,而分布式系统却是刚刚崛起的新力量呢?
让我们一起来看看吧
从单机存储和分布式存储,一个最大的差别就是额外的增加了一个新的组件,网络。
利用以太网或者是其他网络协议,组合多台机器,来一起为用户服务。因此,让我们先来一起看看这个新伙伴。
为了简化起见,我们在这里以目前使用最为广泛的 tcp/ip 作为例子来做介绍。
在计算机系统内,一个最常见的操作,就是数据的在多个 cpu 之间共享。
例如,加锁去锁操作,其本质就是利用一个共享的信号量数据来协调多个 cpu 针对某个数据块的读写访问权限。类似的操作有很多,比如 cpu 中的 numa 架构,还有各类 join 处理等,几乎所有的多线程程序,其核心都是在处理某块数据的共享读写问题。
那么,针对数据在多 cpu 的读写共享问题,我们能够采取的手段有:
1 、数据物理上是一份,通过并发读写控制的方式来达到数据共享的目的
这种方式是读写速度最快的方法,然而,这种方式也会有其代价,因为就算单块内存的读写访问速度再快,也不可能是 0 不是~ 因此针对一块数据的读写虽然很快,然而吞吐量会受到单块内存(或磁盘,针对写入)的吞吐量限制,不可能无限的增长。
2 、通过消息通信的方式,将数据 copy 到另一块存储介质 ( 内存或磁盘 ) 中
通过这种方式,我们也可以实现数据的共享,每个需要这份数据的人,都在本地复制留存一份自己的拷贝。
这样,因为可以从多个点去读取数据了,所以读取的吞吐量可以随着复制份数的增加而增加。然而,写入似乎是没办法解决的难题。。
首先,写入量没有下降,而是随着写入份数的增加而增加了。。
然后,因为要写入多份,那么另一个难题就出现了。如何保证一个数据的更新同时出现在其他内存块中?
第一种选择自然是:不同步不就好了。。但这样带来的一个代价,就是多个进程读取数据,可能会出现不一致的读取。。这样说好像有点抽象,我们把它具象化一下:
李雷原本账号里有三百元,他分别将这个钱转给了韩梅梅 100 元,又转给了沈询 100 元。那么,如果为了快速,李雷的账务数据分别在韩梅梅处和沈询处复制了一份。而他们之间又没有做任何处理。
那李雷刷新自己账户信息的时候,就可能出现以下情况:刷新第一次,读取到了韩梅梅处那份数据,于是显示自己账号内还有 200 元。再刷新一次,读取了沈询账号内的数据,显示李雷还有 300 元,再刷新下,读取到了李雷自己账号内的数据,发现余额还有 100 元。。好吧,他其实最后都不知道自己到底还剩下多少钱了。。
这虽然是效率最高的方式,不过看来是挺危险的。。。
好吧,看来要解决这个问题,又需要作个额外的同步操作。。
方案 1 :做个知识迁移,在单机事务一致性的章节( http://blog.sina.com.cn/s/blog_693f08470102uzhx.html )我们讲过,利用事务操作模型,就能够保证多份数据的强一致性。
在这里似乎也可以使用~先在每个需要复制的数据上加锁,然后进行数据的复制,然后再去锁。
这样带来的好处是很明显的,李雷无论读到哪一份数据,看到的结果都是一样的。 世界大同了~
不过,当我们把这种模式当成锤子,满世界敲钉子的时候,发现这个模型不能经常使用。。虽然看起来最方便,用户也最容易理解,但他的效率实在是太低了 … ,每次更新都要加锁去锁,而最要命的是,锁会导致线程等待。显而易见,而锁的时间越长,线程等待的时间就越长。。
还是得找其他方法 …
通过仔细观察,我们发现,对于某些场景而言,并非数据的所有版本都有同步的意义,只需要让某块数据需要被访问的时候,再进行数据同步即可。
于是,我们有了方案 2
方案 2 :设计一个数据作为主数据,其他数据为主数据的缓存数据,每次当主数据更新之后,都广播给其他数据节点一个失效请求,将所有缓存数据失效。
如果我们不需要数据的所有更新版本,那么利用这种方式能有效的减少通信次数。
在缓存领域,我们还有其他增强方式来针对一些特定的场景优化缓存的读写压力,不过继续演进下去离题太远,我们暂时在此收笔,在未来介绍缓存方案的时候,再做细致的分析吧~
通过上面的讨论,我们可以看到,数据共享的方式也主要就是上面的两种,各有优劣 …
看到这里,看官们可能会问了,您这扒拉扒拉的说了这么多,跟我们这次要讨论的分布式存储有什么关系啊?
好吧,这就是最关键的一步,各位请随我来~
分布式存储与单机存储的一个最大的不同点,就在于在原来的单机系统之外,额外的引入了网络这个因素。
与单机内基于总线的数据传输相比,基于网络的数据传输,主要体现了以下的一些变化:
1 、 传输的延迟变大。
主要的原因是各类基于网络的协议,因为要处理更复杂的组网问题,所以一般协议更为复杂,进行协议之间的相互转换也需要更多时间,这在 tcp / ip 协议中体现的更为明显。
同时,如果涉及到跨数据中心的数据传输,那么延迟会更为夸张,光速其实也是有延迟的。。虽然他很快,但杭州到青岛还是需要几百毫秒的延迟的。这比在单机内进行数据传输时的几纳秒时间,扩张了几千甚至几千万倍。
2 、传输的吞吐量变小。
目前的 tcp / ip ,主要都采用千兆网卡,所以吞吐量上仍然有比较明显的限制,每秒钟的传输量,远远小于单机内总线的吞吐量。 万兆网卡的话能够得到一定的平衡,不过要改变整个网络结构,这个代价还是很惨重的。
3 、 网络存在断线问题
在单机内是不存在断线问题的,而在多机情况下,网络连路变的更长,链路两端的机器很可能出现一台存活,另外一台却 donw 机的情况,这种情况在单机内是不会出现的。
因为延迟、吞吐量、网络断线等问题。就导致原来数据共享的成本发生了巨大的变化。
如果采用共享模型,数据在青岛,而访问发起在杭州,那么就算我们把一切额外的延迟开销都节省为 0 ,读取共享数据的延迟仍然大的惊人,以至于无法接受。。
而如果采用基于消息的复制模型呢?获得一致性读取的延迟会增加几千倍甚至几千万倍。。也完全无法接受。。
因此,分布式系统必然的很难做成与单机系统一样的效果。。
说句玩笑话,分布式系统在扩展性和容错性上远超单机系统,如果在功能上也能做到与单机系统一致甚至能超越单机系统的话,那这世界上早就没有单机系统了。。。
Ok ,今天就聊到这儿 ~
在这篇文章中,我们主要聊了一下分布式系统与单机系统的最大不同点:额外引入了网络因素。并分析了这种不同所引发的系统实现成本上的巨大变化。
在下次,我们再聊一下分布式系统在能力上远超单机系统的一些部分,比如扩展性,比如数据不丢失和服务的可用性等特性产生的原因