看来我们很可以称2007为“数据库正规化的神秘面纱被揭穿的一年”。我们已经看到了一些有意思的讨论,一些大型网站为了能够处理每小时上千万的访问请求,而放弃了传统关系数据库的路子。根据Joe Gregorio最近的观察,出现了这样一些常见方案(这里强调的是我的观点):
如果你想伸展到拍字节(Petabyte,2的50次方,约千万亿)的级别,或者每天数十亿请求,你就需要:这些约束从根本上区别于(传统)关系数据库。
- 分布式部署。数据必须分布到多台机器上去。
- 无表连接(Joinless)。至少在数据存储层次上,不能使用表连接(Join),也不要定义关联完整性约束。
- 去正规化。虽然没有人直说,但我想如果你要避免使用表连接,就会有很多去正规化工作。
- 无事务。不能按事务方式操作。
这些特征可以用来描述Mnesia,Erlang的分布式数据库管理系统,通过复制方式支持高伸缩性和容错性,可以不需要传统关系数据库的表连接就检索记录。Mnesia属于Erlang/OTP项目,是为运行于Erlang虚拟机上用Erlang语言开发的应用设计的(有用于C/C++和Java的接口)。
在1999年发布的白皮书《Mnesia——适用于电信应用的分布式健壮数据库管理系统》中,作者(Håkan Mattsson、Hans Nilsson和Claes Wikstrom)介绍了这个数据库的概念和关键区别,这些概念和区别所具备的预见能力很是令人惊叹。以下来自摘要:
Mnesia数据库管理系统运行于数据拥有者应用的同一个地址空间中,但是应用不可能破坏数据库内容。这保障了快速访问的同时能够有效容错,而这二者一般是相互冲突的需求。Mnesia植根于Erlang编程语言,基于Erlang的诸多特性而得以实现。
论文第一节解释了当初建立这么一个数据库管理系统的动机是电信应用苛刻的容错和高可靠性需求。这些要求是:
论文第二节概览了Mnesia的组件。Mnesia由多个Erlang应用组成,它们提供数据库管理系统的核心服务,比如锁定、事务管理和复制。作者们指出Erlang非常适合用来实现这个系统,它包括了大概2万行代码。查询语法是Erlang的一部分,数据模型类似于对象-关系数据库管理系统。
Mnesia另一个有趣的地方是与Erlang编程语言的严密耦合,基本上把Erlang变成了数据库编程语言。这样好处很多,最大的好处是数据库使用的数据格式和编程语言用来操作数据的数据格式之间完全不会出现阻抗失配。
其数据模型支持表的概念,一条记录等价于一行,其中每一列都可以存储“任意复杂的组合数据结构,例如树、函数、闭包和代码等等”。一个Erlang复杂记录的例子如下:
X = #person{
name = klacke,
data = {male, 36, 971191},
married_to = eva,
children = [marten, maja, klara]
}.
Mnesia也支持一个和视图(View)类似的概念,这个概念被称为规则(Rules)。
复制是使Mnesia成为一个容错数据库管理系统的机制之一。数据表可以被复制到混合网络中的多个节点,而对应用来说却是透明的。被复制的数据表是对等的,也就是说没有主-从结构。
论文第三节详细描述了Mnesia的一些独有特性:
query [P.name || P < table(person), length(P.children) > X] end.
在论文第四节中,作者们探索了具体实现的各方面,比如持久、锁管理、查询实现,以及分布应用的各节点可能会运行于不同字节顺序的计算机的情况,进而使得这样一个系统能够工作于混杂环境中。
第五节讨论了性能问题,发现“脏接口”比事务控制下的对应部分快得相当多。如预期一样,同步复制的代价使事务执行时间明显延长。完成一个事务的时间(以毫秒计)在单节点上是:常规锁——1877,显式写入锁——1225,而使用“脏接口”的话是181。如果是3个节点的话,相同事务类型测量到的时间依次为:13372、12185和1121。
论文得出如下结论:
Mnesia系统现在正被爱立信用来构建实际的产品,也就是说它不再只是一个原型系统,它已经成熟到可以贴上产品的标签。
Mnesia的开发从该论文后一直在继续,加入了如分片表(fragmented tables,类似shards,但在数据库层次上处理)等更多特性,也被用在开源项目如YAWS(Erlang Web服务器)和ejabberd(XMPP服务器)中。
对于横向分片数据,Mnesia在伸缩性和低延迟事务上表现突出, 接下来的一个挑战可能是对于超大规模数据集它如何伸展。有人提到了超过6千万行的例子。然而如Bill de hÓra最近写到的,增长的数据容量将迫使我们重新思考我们的数据库策略:
我想在对日常编程工作的影响上,增长的数据容量要远远超过多核。我过去几年所做的工作,一个不变的主题就是处理越来越大的数据集。被Joe Gregorio称为“Megadata(兆数据)”(但现在希望他没这么说过)。大数据集已不再是几家大公司的深奥议题,而是变得非常常见。
然后得出结论:
大容量意味着你需要不用管数据的去向而只是写入。而且对于关键字检索方式的读取,你需要基于文件系统,而不是关系数据库管理系统(在没有表连接、约束或触发器的前提下,关系数据库管理系统就是一个索引了的文件系统)。那样最终就是像 Hadoop、 Mogilefs或 S3一样的东西——并行数据架构。
随着对Erlang/OTP的兴趣提升(包括最近的InfoQ文章),这个项目最终也应该是像Mnesia一样的东西。
查看英文原文: Erlang's Mnesia - a distributed DBMS for highly scalable apps 译者简介:岳立东,Ableverse创始人,技术推广大使。开源项目 WoW(内含ToB对象数据库)和 SecureJSH创建者。目前致力于东道组件接合(Hosting Based Interfacing)理论研究,在此基础上的软件并行分布架构及对象数据库应用,技术博客 http://complystill.javaeye.com/。欲参与InfoQ中文站内容建设,请邮件至 china-editorial[at]infoq.com。