从SQL到NoSQL再到NewSQL的一点思考


导读

SQL一直发展的都很好,直到1989年一个工程师发明了万维网。

互联网的蓬勃发展极大改变了数据的生产数量和生产速度。关系型数据库创立之初没有想到今天的互联网应用对可扩展性提出如此高的要求,一阵骚动后大家发现关系型数据库开始过载了。

我们收集分析的数据急剧增长,因此对于数据处理和分析技术的要求也越来越高。由于SQL越来越无法满足这些要求,NoSQL也就逐渐发展起来。

NoSQL表示“不只是SQL”。本文重点说一下NoSQL。

性能好是NOSQL系统最大的特点之一,NOSQL系统基本上都是借鉴了关系型数据库的技术,关系型数据库数十年不间断的各种优化工作已经做得很深了但还不够。到底是什么因素束缚了关系型数据库的性能呢?我们或许可以从系统设计的角度看出一些端倪。

一、索引支持


关系型数据库在单机存储引擎支持索引,比如Mysql的Innodb存储引擎需要支持索引,而NOSQL系统的单机存储引擎是纯粹的,只需要支持基于主键的随机读取和范围查询。
NOSQL系统在系统层面提供对索引的支持,比如有一个用户表,主键为user_id,每个用户有很多属性,包括用户名,照片ID(photo_id),照片URL,在NOSQL系统中如果需要对photo_id建立索引,可以维护一张分布式表,表的主键为形成的二元组。
关系型数据库由于需要在单机存储引擎层面支持索引,大大降低了系统的可扩展性,使得单机存储引擎的设计变得很复杂。


二、事务并发处理


关系型数据库有一整套的关于事务并发处理的理论,比如锁的粒度是表级,页级还是行级,多版本并发控制机制MVCC,事务的隔离级别,死锁检测,回滚,等等。
然而互联网应用大多数的特点都是多读少些,比如读和写的比例是10 : 1,并且很少有复杂事务需求,因此,一般可以采用更为简单的copy-on-write技术:单线程写,多线程读,写的时候执行copy-on-write,写不影响读服务。
NOSQL系统这样的假设简化了系统的设计,减少了很多操作的overhead,提高了性能


三、动态还是静态的数据结构


关系型数据库的存储引擎总是一颗磁盘B+树,为了提高性能,可能需要有insert buffer聚合写,query cache缓存读,经常需要实现类似Linux page cache的缓存管理机制。
数据库中的读和写是互相影响的,写操作也因为时不时需要将数据flush到磁盘而性能不高。简而言之,关系型数据库存储引擎的数据结构是通用的动态更新的B+树。然而,在NOSQL系统中,比如Bigtable中采用SSTable + MemTable的数据结构,数据先写入到内存的MemTable,达到一定大小或者超过一定时间才会dump到磁盘生成SSTable文件,SSTable是只读的。
如果说关系型数据库存储引擎的数据结构是一颗动态的B+树,那么SSTable就是一个排好序的有序数组。很明显,实现一个有序数组比实现一个动态B+树且包含复杂的并发控制机制要简单高效地多。


四、Join操作


关系型数据库需要在存储引擎层面支持Join,而NOSQL系统一般根据应用来决定Join实现的方式。
举个例子,有两张表:用户表和商品表,每个用户下可能有若干个商品,用户表的主键为,用户和商品的关联属性存放在用户表中,商品表的主键为item_id,商品属性包括商品名,商品URL,等等。假设应用需要查询一个用户的所有商品并显示商品的详细信息,普通的做法是先从用户表查找指定用户的所有item_id,然后对每个item_id去商品表查询详细信息,即执行一次数据库Join操作,这必然带来了很多的磁盘随机读,并且由于Join带来的随机读的局部性不好,缓存的效果往往也是有限的。
在NOSQL系统中,我们往往可以将用户表和商品表集成到一张宽表中,这样虽然冗余存储了商品的详细信息,却换来了查询的高效。

关系型数据库的性能瓶颈往往不在SQL语句解析上,而是在于需要支持完备的SQL特性。互联网公司面临的问题是应用对性能和可扩展性要求很高,可以通过牺牲一些接口友好性来换取更好的性能。
NOSQL系统的一些设计,从长远来看,可以总结一套约束集合,并且定义一个SQL子集,只需要支持这个SQL子集就可以在不牺牲可扩展性的前提下支持比如90%以上的互联网应用。
我们在设计和使用NOSQL系统的时候也可以适当转化一下思维,如下:


1、更大的数据量。

很多人在使用Mysql的过程遇到记录条数超过一定值,比如2000W的时候,数据库性能开始下降,这个值的得出往往需要经过大量的测试。然而,大多数的NOSQL系统可扩展性都比较好,能够支持更大的数据量,因此也可以采用一些空间换时间的做法,比如通过宽表的方式实现Join。

2、性能预估更加容易。
关系型数据库由于复杂的并发控制,insert buffer及类似page cache的读写优化机制,性能估算相对较难,很多时候需要凭借经验或者经过测试才能得出系统的性能。然后,NOSQL系统由于存储引擎实现,并发控制机制等相对简单,可以通过硬件的性能指标在系统设计之处大致预估系统的性能,性能预估可操作性相对更强。


一点想法

我个人感觉NoSQL是使用MySQL作为数据库的一个自然的演化,但SQL正在回归。

没有SQL实际上是非常有限的,每个NoSQL数据库都提供了自己独特的查询语言,这意味着开发人员需要学习更多的语言,这增加了数据库连接应用程序的难度,导致代码之间的耦合性太强,需要公司开发自己的操作和可视化工具。当然一些NoSQL数据库添加了自己的类SQL查询语言,但效果并不太好。
为什么说SQL正在回归,准确的说是SQL借助于NewSQL开始回归。

NewSQL 提供了与 NoSQL 相同的可扩展性,而且仍基于关系模型,还保留了极其成熟的 SQL 作为查询语言,保证了ACID事务特性。简单来讲,NewSQL 就是在传统关系型数据库上集成了 NoSQL 强大的可扩展性。传统的SQL架构设计基因中是没有分布式的,而 NewSQL 生于云时代,天生就是分布式架构。

主流newSQL项目:

MemSQL、ScaleDB、TiDB

聚焦技术与人文,分享干货,共同成长
更多内容请关注“数据与人”

为您推荐

发表评论

您的电子邮箱地址不会被公开。