上回我们说到
随着互联网的爆发式发展,数据库概念领域又一次发生了摇摆,伴随着互联网的特殊需求,一批有着新鲜血液的NoSQL数据库涌现了出来,层次模型又从封印中苏醒,站在了大家面前。
这里就自然而然会有一系列的疑问产生了出来,为什么层次模型变种的NoSQL会出现并得到了一些人的认同?他满足了什么需求? 关系模型在什么地方不能满足大家的需求了?
那么,我们就从应用场景出发,尝试回答一下这些问题吧。
提到NoSQL,自然而然就会有人问了,NoSQL是因为什么而被提出来的? 又是因为什么而得到了一些人的认可呢?以及现在的演进状况如何呢?
因为我也是部分的亲历者,所以就从我的视角,来回溯一下他们发展的整体的一个发展脉络吧。
在这篇文章里,我将主要以例子的方式来做个回顾,以点带面以帮助大家对整个问题有更好的理解,对于一些细节性原理的阐述,我将放到后面的NoSQL章节里面做更深入和细致的剖析。
记得那还是在08年的时候,我们这个中间件的team刚刚成立,它的目标是支持公司业务的高速发展的一些相对公用的组件。我也是刚刚加入其中。那时候大家更多地还是在努力的学习我们假想中的对手:ebay的架构。
在ebay 的整体架构设计词典中,使用最多的就是“异步” , “最终一致” ,“幂等” 这样的词汇。 对于入行没多久的我来说,对这些词汇的本质含义还没有太多的认识,不过已经知道了原来网站的设计还真是个挺复杂的事情。
在这些词汇中,“最终一致” 是最让我困惑之一,我也算是学过数据库概念的人,虽然不管是不是死记硬背的,但一致性和隔离性的几个级别所产生的问题什么的还能基本知道,但突然来了个最终一致。。就让我觉得非常困惑了,他是什么?他和传统数据库的ACID有什么关系? 坦白说这么多年了,我虽然对他们的认识有了更深一步的理解,但让我讲,我还真不一定能用很短的篇幅讲出来。。。不过我现在唯一能够确定的是,就算是在现在,你问1000个程序员,什么是一致性,估计能得到999种不同的回答,剩下的那俩回答一样的原因是因为搜索到了同一篇网页(笑)。
而这也是当时国内外对网站架构的基本认识,因为在那之前,大部分网站主要的作用就是使用内容管理系统将编辑们发布的文章页面静态化然后给用户提供个评论窗口的程度而已。数据库有瓶颈的时候不多,有了加个cache 大部分就都能搞定了,最多最多也只需要做个简单的数据库切分,一个拆几个,用户需求也就搞定了。对于高端一些的用户,则一般是使用从银行出来的方案,弄个运算能力超强,像小山一样的黑色柜子,然后再弄个放上几百块硬盘的大盘柜,也就解决了问题。
能解决,但还是不爽,这些不爽主要是集中在这么几个地方:
1. 大型机技术被一些大厂把持着,定价权不在用户,购买的成本比较高,一般公司用不起。
2. 自己做数据库切分的话,碰到跨库join和跨库事务又不好处理
3. 数据库的灾备切换也是个头疼的问题,大家对数据安全性和性能的需求不一样,用同一个方案又不能都搞定。
这些不爽其实直到现在都一直存在着,人类的发展历史,就是不断地针对不爽而逐渐解决的过程。
但很多事情就是跷跷板,你压下了这头,那一头就抬起来,所以你看我们计算机的书里面讲某种算法的时候,是不是一般都按照这么个顺序来做介绍的:
首先,告诉你一个场景,三种方法,A的好处是B的坏处,B的好处是A的坏处,然后权衡再三,选择了方法C。再想想,怎么跟富翁娶老婆,选了半天最后选了胸大的有一样的感觉呢?玩笑玩笑~
其实这也就是我们去探索和解决问题的方式,或者说程序员在每天写程序的过程中其实就是在做一次又一次的权衡,甚至,你的每一个if ,每一个else,都是在两种可能性中做出了选择~那么,当时为什么要做出这样的选择,就成为了问题的中关键的关键。
技术的发展必定是依托于实际的需求的,就像富翁选择胸大的一样,在计算机的世界里,大家面临选择的时候也必定是从实际需求出发的。但是,很不幸的是,需求不可能都被满足,因为一些客观因素的限制,就不得不逼迫人类在两种痛苦中选择那个最轻的,而这“客观因素” 也是我们未来将要关注的东西,我会尽我所能,在未来的文章中回答大家上面的这两个问题的。
那么,我们就来看一看实际需求变化的情况,来把握当时选择的原因吧。
在web2.0蓬勃发展之前,使用数据库的主要应用场景是个大企业,金融机构在使用,他们面临的主要问题是:如何高效简单的满足用户的需求,并且能够随着用户需求的变化而快速的进行响应。而对业务量上面的要求却并不夸张,大部分情况下,每天数据库也只需要处理不算特别多的用户请求。
在这种情况下,开发的效率就成为了大家最为关注的目标,一切以开发效率为最优先选择的因素。 那么,就让我们来看看,在数据库存储领域,有哪些东西是以提升工作效率为首要目标进行设计的。
首先,关系模型就是其中之一,上篇文章我们也提到过了,关系模型主要的目标是”隔离了数据的存取路径,让用户只需要关心查询的逻辑”
然后,事务和一致性的原理和实现机制是其中之二,为了事务和一致性读,数据库付出的代价是复杂的锁实现,开销也变得比较大。
最后,约束(当然它也属于关系模型的要素,但实现上来说是分开的),也是为了方便和安全性而定义的性质
好了,你可以看到,基本上来说,数据库做了这么多年,核心目标就是为了响应“当时”的用户更快而进行的设计,从而你也可以立刻理解在上篇里面,为什么数据库的开发人员投入了大量的资源在解决对象-关系不匹配的问题上,并产生了大量的ORMapping类产品的原因了。
然后,互联网的时代到来了。
互联网行业的蓬勃发展,对数据存储带来了新的要求,我们简单的列出来看看
1. 大量的用户
2. 单个用户的数据的价值非常低
3. 数据量比较大,部分数据增长较快
4. 用户的业务逻辑相对的比较简单
对需求有了简单的定义以后,我们就来看看,传统的数据库与目前新的应用需求之间的关系,当然,我们这都是事后诸葛亮,在当时似乎没什么人能分析的这么清楚哈 :)
因为大量用户,并且单个用户的数据的价值非常低,所以自然的,在大部分应用上使用大型机和盘柜就明显不理智了,你用这玩意儿去存哪些用户点了“喜欢”?或者用这玩意去存哪些用户今天吃了竹子,明天吃了牛排?因此,一些大厂在之前的积累,与目前新价值产生的领域出现了不匹配。
所以,开源的mysql就成为了大量从LAMP架构成长起来的互联网企业的首要选择,在他们成长为大网站的时候,大量的数据存储需要以相对安全的方式进行扩展,因此,针对mysql的切分自然就成了大家的首选方案之一。
包括facebook,淘宝,甚至google在内的大量互联网企业基本都选择了使用mysql进行切分的方案来构建他们的业务系统,以满足不断上涨的用户量。
既然选择了数据库切分,那么我们自然要分析一下,数据库切分能做到什么,不能做到什么。
数据库切分的最大优势,是对之前的架构冲击不大,因为切分逻辑是很简单可以写出来的,而既然之前能够接受mysql所提供的安全性标准,那么水平的扩展更多的mysql,安全性标准基本没有发生变化,不需要担心架构和人才出现不匹配的情况,该踩的坑都大部分都踩过,社区比较大,问题能够快速得到解决。因此,这是目前而言最理智的选择之一。
但数据库切分也不是没有问题的,而且问题很多很多。。
首先,最大的问题就是业务要做重构,原来用单个数据库的时候,业务里面经常能看到多条更新的事务操作。这些操作中有不少,在数据库切分之后不能够直接运行在多台机器上,当然,有些人会反驳说:谁告诉你不行的? 2pc知道不?coodinator ,cohorts 知道不?谁说不能做!?—我的回答是,嗯,能做,但不可能能以单机事务那样的成本做到。甚至,在大部分场景下,你会因为延迟难以忍受而不得不放弃原来的事务操作模式。啊!好痛好痛,我的膝盖中了一箭!~
然后,运维和管理难度上升了,原来只有一个机器的时候,运维虽然也苦逼,但相对的没有那么苦逼。而现在,一个应用就有100多台库,假设一个在一年内挂掉的概率是1%,那么如果他们都是独立事件,100台里挂掉1台的概率是63%。扩容也是问题,怎么扩,如何扩,都是需要解决的问题。啊!好痛好痛,另一条腿也中了一箭!~
最后,关系模型也成了累赘,原来的俩表join,现在你变成了俩库的join,做是能做,延迟得考虑吧?性能得考虑吧?数据量也得考虑吧? 就算是log2N的二分查找,N=1000和N=100000000000 在查找效率上还是有一定差别的吧。
老的解决方案里存在这样和那样的问题,看起来似乎都有点棘手和难以解决。所以,时代需要新的声音,破坏与重新构造,成为了数据存储领域的主音。
然而,在如何破坏与如何重新构造这个问题上,大家产生了分歧,就像历史上无数次的政治风暴一样,有些人向左,有些人向右,更多的人困惑的站在了原地。
下一篇,就让我们来感受一下时代的脉动,真正的进入存储领域的战国时代吧。