您好,欢迎来到二三娱乐。
搜索
您的当前位置:首页开源数据库的现状

开源数据库的现状

来源:二三娱乐

数据库作为业务的核心,在整个基础软件栈中是非常重要的一环。近几年社区也是新的方案和思想层出不穷,接下来我将总结一下近几年一些主流的开源数据库方案和背后的设计思想以及适用场景。本人才疏学浅如有遗漏或者错误请见谅。本次分享聚焦于数据库既结构化数据存储 OLTP 及 NoSQL 领域,不会涉及 OLAP、对象存储、分布式文件系统。

开源RDBMS与互联网的崛起

很长时间以来,关系型数据库一直是大公司的专利,市场被 Oracle / DB2 等企业数据库牢牢把持。但是随着互联网的崛起、开源社区的发展,上世纪九十年代 MySQL 1.0 的发布,标志着关系型数据库的领域社区终于有可选择的方案。

MySQL

另外值得一提的是 MySQL 5.6 中引入了多线程复制和 GTID,使得故障恢复和主从的运维变得比较方便。另外,5.7(目前处于 GA 版本) 是 MySQL 的一个重大更新,主要是读写性能和复制性能上有了长足的进步(在5.6版本中实现了SCHEMA级别的并行复制,不过意义不大,倒是MariaDB的多线程并行复制大放异彩,有不少人因为这个特性选择MariaDB。MySQL 5.7 MTS支持两种模式,一种是和5.6一样,另一种则是基于binlog group commit实现的多线程复制,也就是MASTER上同时提交的binlog在SLAVE端也可以同时被apply,实现并行复制)。如果有单机数据库技术选型的朋友,基本上只需要考虑 5.7 或者 MariaDB 就好了,而且 5.6、5.7 由 Oracle 接手后,性能和稳定性上都有了明显的提升。

PostgreSQL

我认为,单机数据库的时代很快就会过去。摩尔定律带来的硬件红利总是有上限的,现代业务的数据规模、流量以及现代的数据科学对于数据库的要求,单机已经很难满足。比如,网卡磁盘 IO 和 CPU 总有瓶颈,线上敏感的业务系统可能还得承担 SPOF(单点故障) 的风险,主从复制模型在主挂掉时到底切还是不切?切了以后数据如何恢复?如果只是出现主从机器网络分区问题呢?甚至是监控环境出现网络分区问题呢?这些都是单机数据库面临的巨大挑战。所以我的观点是,无论单机性能多棒(很多令人乍舌的评测数据都是针对特定场景的优化,另外甚至有些都是本机不走网络,而大多数情况数据库出现的第一个瓶颈其实是网卡和并发连接……),随着互联网的蓬勃发展和移动互联网的出现,数据库系统迎来了第一次分布式的洗礼。

分布式时代:NoSQL的复兴和模型简化的力量

在介绍 NoSQL 之前,我想提两个公司,一个是 Google,另一个是 Amazon。

Google

Amazon

新思潮

另外这个时期(2006 年前后持续至今)一个比较重要的思潮就是数据库(持久化)和缓存开始有明确的分离——我觉得这个趋势是从 memcached 开始的。随着业务的并发越来越高,对于低延迟的要求也越来越高;另外一个原因是随着内存越来越便宜,基于内存的存储方案渐渐开始普及。当然内存缓存方案也经历了一个从单机到分布式的过程,但是这个过程相比关系型数据库的进化要快得多。这是因为 NoSQL 的另外一个重要的标志——数据模型的变化——大多 NoSQL 都抛弃了关系模型,选择更简单的键值或者文档类型进行存储。数据结构和查询接口都相对简单,没有了 SQL 的包袱,实现的难度会降低很多。另外 NoSQL 的设计几乎都选择牺牲掉复杂 SQL 的支持及 ACID 事务换取弹性扩展能力,也是从当时互联网的实际情况出发:业务模型简单、爆发性增长带来的海量并发及数据总量爆炸、历史包袱小、工程师强悍等等。其中最重要的还是业务模型相对简单。

嵌入式存储引擎

在开始介绍具体的开源的完整方案前,我想介绍一下嵌入式存储引擎们。

随着 NoSQL 的发展,不仅仅缓存和持久化存储开始细分,存储引擎也开始分化并走上前台。之前很难想象一个存储引擎独立于数据库直接对外提供服务,就像你不会直接拿着 InnoDB 或者 MyISAM甚至一个 B-tree 出来用一样(当然,bdb 这样鼎鼎大名的除外)。人们基于这些开源的存储引擎进行进一步的封装,比如加上网络协议层、加上复制机制等等,一步步构建出完整的风格各异的 NoSQL 产品。

这里我挑选几个比较著名存储引擎介绍一下。

TC

LevelDB

LevelDB 拥有极好的写性能,线程安全,Batch Write 和 Snapshot 等特性,使其很容易的在上层构建 MVCC 系统或者事务模型,这对数据库来说非常重要。另外值得一说的是,Facebook 维护了一个活跃的 LevelDB 的分支,名为 RocksDB。RocksDB 在 LevelDB 上做了很多的改进,比如多线程 Compactor、分层自定义压缩、多 MemTable 等。另外 RocksDB 对外暴露了很多 Configuration,可以根据不同业务的形态进行调优;同时 Facebook 在内部正在用 RocksDB 来实现一个全新的 MySQL 存储引擎:MyRocks,值得关注。RocksDB 的社区响应速度很快也很友好,实际上 PingCAP 也是 RocksDB 的社区贡献者。我建议新的项目如果在 LevelDB 和 RocksDB 之间纠结的话,请果断选择 RocksDB。

B-tree 家族

混合引擎

NoSQL

说完了几个比较著名的存储引擎,我们来讲讲比较著名的 NoSQL。在我的定义中,NoSQL 是Not Only SQL 的缩写,所以可能包含的范围有内存数据库,持久化数据库等,总之就是和单机的关系型数据库不一样的结构化数据存储系统。

我们先从缓存开始。

memcached

Redis

Twemproxy

MongoDB

尽管 MongoDB 早期的版本各种不稳定,性能也不太好(早期的 Mongo 并没有存储引擎,直接使用了 mmap 文件),集群模式还全是问题(比如至今还未解决的 Cluster 同步带宽占用过多的问题),但是因为确实太方便了,在早期的项目快速迭代中,Mongo 是一个不错的选择。但是这也正是它的问题,我不止一次听到当项目变得庞大或者「严肃」的时候,团队最后还是回归了关系型数据库。Anyway,在 2014 年底 MongoDB 收购了 WiredTiger 后,在 2.8 版本中正式亮相,同时 3.0 版本后更是作为默认存储引擎提供,性能和稳定性有了非常大的提升。

但是,从另一方面讲,Schema-less 到底对软件工程是好事还是坏事这个问题还是有待商榷。我个人是站在 Schema 这边的,不过在一些小项目或者需要快速开发的项目中使用 Mongo 确实能提升很多的开发效率,这是毋庸置疑的。

HBase

HBase 就是这么一个系统的实现,底层依赖 HDFS。HBase 本身并不实际存储数据,持久化的日志和 SST file (HBase 也是 LSM-Tree 的结构) 直接存储在 HDFS 上,Region Server (RS) 维护了 MemTable 以提供快速的查询,写入都是写日志,后台进行 Compact,避免了直接随机读写 HDFS。数据通过 Region 在逻辑上进行分割,负载均衡通过调节各个 Region Server 负责的 Region 区间实现。当某 Region 太大时,这个 Region 会分裂,后续可能由不同的 RS 负责,但是前面提到了,HBase 本身并不存储数据,这里的 Region 仅是逻辑上的,数据还是以文件的形式存储在 HDFS 上,所以 HBase 并不关心 Replication 、水平扩展和数据的分布,统统交给 HDFS 解决。

Cassandra

C*不能简单的归纳为读快写慢,或者读慢写快,因为采用了 qourm 的模型,调整复制的副本数以及读的数量,可以达到不同的效果,对于一致性不是特别高的场景,可以选择只从一个节点读取数据,达到最高的读性能。另外C*并不依赖分布式文件系统,数据直接存储在磁盘上,各个存储节点之间自己维护复制关系,减少了一层 RPC 调用,延迟上比 HBase 还是有一定优势的。

不过即使使用 qourm 的模型也并不代表C*是一个强一致的系统。C*并不帮你解决冲突,即使你 W(写的副本数) + R(读请求的副本数) > N(节点总数),C*也没办法帮你决定哪些副本拥有更新的版本,因为每个数据的版本是一个 NTP 的时间戳或者客户端自行提供,每台机器可能都有误差,所以有可能并不准确,这也就是为什么C*是一个 AP 的系统。不过C*一个比较友好的地方是提供了 CQL,一个简单的 SQL 方言,比起 HBase 在易用性上有明显优势。

中间件与分库分表

NoSQL 就先介绍到这里,接下来我想说的是一些在基于单机关系型数据库之上的中间件和分库分表方案。

这些技术确实历史悠久,而且也是没有办法的选择。关系型数据库不比 Redis,并不是简单的写一个类似 Twemproxy 的中间件就搞定了。数据库的中间件需要考虑很多,比如解析 SQL,解析出 sharding key,然后根据 sharding key 分发请求,再合并;另外数据库有事务,在中间件这层还需要维护 Session 及事务状态,而且大多数方案并没有办法支持跨 shard 的事务。这就不可避免的导致了业务使用起来会比较麻烦,需要重写代码,而且会增加逻辑的复杂度,更别提动态的扩容缩容和自动的故障恢复了。在集群规模越来越大的情况下,运维和 DDL 的复杂度是指数级上升的。

中间件项目盘点

未来在哪里?NewSQL!

一句话,NewSQL 就是未来。

Spanner综述

但是 Spanner 的创新之处在于通过硬件(GPS时钟+原子钟)来解决时钟同步的问题。在分布式系统里,时钟是最让人头痛的问题,刚才提到了C*为什么不是一个强 C 的系统,正是因为时钟的问题。而 Spanner 的厉害之处在于即使两个数据中心隔得非常远,不需要有通信(因为通信的代价太大,最快也就是光速)就能保证 TrueTime API的时钟误差在一个很小的范围内(10ms)。另外 Spanner 沿用了很多 Bigtable 的设计,比如 Tablet / Directory 等,同时在 Replica 这层使用 Paxos 复制,并未完全依赖底层的分布式文件系统。但是 Spanner 的设计底层仍然沿用了 Colossus,不过论文里也说是可以未来改进的点。

Google 的内部的数据库存储业务,大多是 3~5 副本,重要一点的 7 副本,遍布全球各大洲的数据中心,由于普遍使用了 Paxos,延迟是可以缩短到一个可以接受的范围(Google 的风格一向是追求吞吐的水平扩展而不是低延迟,从悲观锁的选择也能看得出来,因为跨数据中心复制是必选的,延迟不可能低,对于低延迟的场景,业务层自己解决或者依赖缓存)。另外由 Paxos 带来的 Auto-Failover 能力,更是能让整个集群即使数据中心瘫痪,业务层都是透明无感知的。另外 F1 构建在 Spanner 之上,对外提供了更丰富的 SQL 语法支持,F1 更像一个分布式 MPP SQL——F1 本身并不存储数据,而是将客户端的 SQL 翻译成类似 MapReduce 的任务,调用 Spanner 来完成请求。

其实 Spanner 和 F1 除了 TrueTime 整个系统并没有用什么全新的算法,其意义在于这是近些年来第一个 NewSQL 在生产环境中提供服务的分布式系统技术。

Spanner 和 F1 有以下几个重点:

1. 完整的 SQL 支持,ACID 事务;

2. 弹性伸缩能力;

3. 自动的故障转移和故障恢复,多机房异地灾备。

NewSQL 特性确实非常诱人,在 Google 内部,大量的业务已经从原来的 Bigtable 切换到 Spanner 之上。我相信未来几年,整个业界的趋势也是如此,就像当年的 Hadoop 一样,Google 的基础软件的技术趋势是走在社区前面的。

社区反应

CockroachDB

CockroachDB 的技术选型比较激进,比如依赖了 HLC 来做事务的时间戳。但是在 Spanner 的事务模型的 Commit Wait 阶段等待时间的选择,CockroachDB 并没有办法做到 10ms 内的延迟;CockroachDB 的 Commit Wait 需要用户自己指定,但是谁能拍胸脯说 NTP 的时钟误差在多少毫秒内?我个人认为在处理跨洲际机房时钟同步的问题上,基本只有硬件时钟一种办法。HLC 是没办法解决的。另外 Cockroach 采用了 gossip 来同步节点信息,当集群变得比较大的时候,gossip 心跳会是一个非常大的开销。当然 CockroachDB 的这些技术选择带来的优势就是非常好的易用性,所有逻辑都在一个 binary 中,开箱即用,这个是非常大的优点。

TiDB

目前从全球范围来看,另一个朝着 Spanner / F1 的开源实现这个目标上走的产品是 TiDB(终于谈到我们的产品了)。TiDB 本质上是一个更加正统的 Spanner 和 F1 实现,并不像 CockroachDB 那样选择将 SQL 和 Key-Value 融合,而是像 Spanner 和 F1 一样选择分离,这样分层的思想也是贯穿整个 TiDB 项目始终的。对于测试、滚动升级以及各层的复杂度控制会比较有优势;另外 TiDB 选择了 MySQL 协议和语法的兼容,MySQL 社区的 ORM 框架和运维工具,直接可以应用在 TiDB 上。

和 F1 一样,TiDB 是一个无状态的 MPP SQL Layer,整个系统的底层是依赖 TiKV 来提供分布式存储和分布式事务的支持。TiKV的分布式事务模型采用的是 Google Percolator 的模型,但是在此之上做了很多优化。Percolator 的优点是去中心化程度非常高,整个集群不需要一个独立的事务管理模块,事务提交状态这些信息其实是均匀分散在系统的各个 Key 的 meta 中,整个模型唯一依赖的是一个授时服务器。在我们的系统上,极限情况这个授时服务器每秒能分配 400w 以上个单调递增的时间戳,大多数情况基本够用了(毕竟有 Google 量级的场景并不多见);同时在TiKV中,这个授时服务本身是高可用的,也不存在单点故障的问题。

TiKV和 CockroachDB 一样也是选择了 Raft 作为整个数据库的基础;不一样的是,TiKV整体采用 Rust 语言开发,作为一个没有 GC 和 Runtime 的语言,在性能上可以挖掘的潜力会更大。

关于未来

我觉得未来的数据库会有几个趋势,也是 TiDB 项目追求的目标。

数据库会随着业务云化,未来一切的业务都会跑在云端,不管是私有云、公有云还是混合云,运维团队接触的可能再也不是真实的物理机,而是一个个隔离的容器或者「计算资源」。这对数据库也是一个挑战,因为数据库天生就是有状态的,数据总是要存储在物理的磁盘上,而移动数据的代价比移动容器的代价可能大很多。

多租户技术会成为标配,一个大数据库承载一切的业务,数据在底层打通,上层通过权限,容器等技术进行隔离;但是数据的打通和扩展会变得异常简单,结合第一点提到的云化,业务层可以再也不用关心物理机的容量和拓扑,只需要认为底层是一个无穷大的数据库平台即可,不用再担心单机容量和负载均衡等问题。

OLAP 和 OLTP 会进一步细分,底层存储也许会共享一套,但是SQL优化器这层的实现一定是千差万别的。对于用户而言,如果能使用同一套标准的语法和规则来进行数据的读写和分析,会有更好的体验。

在未来分布式数据库系统上,主从日志同步这样落后的备份方式会被 Multi-Paxos / Raft 这样更强的分布式一致性算法替代,人工的数据库运维在管理大规模数据库集群时是不可能的,所有的故障恢复和高可用都会是高度自动化的。

QA

问:HANA等内存数据库怎么保证系统掉电而处理结果不丢?传统数据库也用缓存,可是HANA用的内存太大。

黄东旭:没用过 HANA,但是直观感觉这类内存数据库的可用性可能通过集中方式保证:

写入会先写 WAL;

写入可能会通过主从或者paxos 之类的算法做同步和冗余复制还有 HANA 本身就是内存数据库,会尽可能把数据放到内存里,这样查询才能快呀。

问:对于传统创业公司如何弥补NoSQL的技术短板?快速的引入NoSQL提高效率?

黄东旭:选用 NoSQL 主要注意两点:

做好业务的调研,估计并发量,数据量,数据的结构看看适不适合;

对各种 NoSQL 擅长和不擅长的地方都尽可能了解。

不要盲目相信关系型数据库,也不要盲目相信 NoSQL,没有银弹的

问:有多个条件  比如年龄20到30或年龄35到40 并且加入购物车或下单  这种数据怎么存储?

黄东旭:购物车这种场景是典型的 OLTP 的场景,可以选用关系型数据库 MySQL PostgreSQL 什么的,如果对于扩展性的数据跨机房有要求的话,可以调研一下 NewSQL,比如我们的 TiDB。

问:多纬度查询应该选择哪种数据库?

黄东旭:多纬度查询可以说是一个 OLAP 的场景,可以选用 Greenplum 或者 Vertica 之类的分析性数据库。

问:想知道为什么需要这些开源的数据库,既然已经有了MySQL、DB2、Oracle这些成熟的数据库,成本考虑,还是传统数据库满足不了需求?

黄东旭:对,传统数据库的扩展性是有问题的,在海量并发和数据量的场景下很难支持业务。所以可以看到比较大的互联网公司基本都有自己的分布式数据库方案。

问:未来可能不再需要数据仓库吗?

黄东旭:大家可以想想数据仓库的定义,如果是还需要离线的从线上库倒腾数据到数据仓库上,这样很难做到实时查询,而且空间的利用率也低,我认为是目前并没有太好的方案的情况下的折衷……

如果有一个更好的数据库能解决数据仓库的场景,为什么还需要一个独立的数据仓库?

Copyright © 2019- yule263.com 版权所有 湘ICP备2023023988号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务