内存数据库FastDB和SQLite性能测评

本贴最后更新于 4359 天前,其中的信息可能已经水流花落

一、引言

在很多项目中,经常会碰到这样的需求,需要对大量数据进行快速存储、查询、删除等操作,特别是在一些针对诸如运营商、银行等大型企业的应用中,这些 需求尤为常见。比如智能网中的大量在线并发用户的数据管理、软交换平台中的在线信息交互、宽带/3G等数据网中在线用户行为记录等等。

针对这些情形,我们通常需要选择高性能的数据库产品,而且通常需要使用内存数据库,顾名思义,内存数据库指的是所有的数据访问控制都在内存中进行, 这是与磁盘数据库相对而言的,磁盘数据库虽然也有一定的缓存机制,但都不能避免从外设到内存的交换,而这种交换过程对性能的损耗是致命的,目前主流数据库 如SYBASE、ORACLE等都有这种缓存机制,如将特定表绑定一定的缓存,从而在一定程度上改善数据吞吐性能。而内存数据库几乎可以完全避免这种内外 存数据交换的发生,特别是在物理内存足够大的设备上尤其如此,通常这种数据库也被称为主存数据库(Main Memory DataBase, MMDB)。

二、主存数据库比较

目前比较知名的商业内存数据库有,ORACLE的TimesTen,MCObject的eXtremeDB、韩国的Altibase等,这些数据库 产品性能都非常的强劲,当然价格也相当的强劲,在非特大型系统建设时,通常让人望而却步。于是退而求其次,免费开源内存数据库给了我们第二种选择。 Berkeley DB,SQLite,MonetDB,FastDB,H2等,不一而足。本文主要针对SQLite和FastDB进行性能测评。

2.1 测试准备

首先,笔者通过对评测数据的调研发现,通常认为,BDB性能不如SQLite,参考"免费的实时数据库,我们该选谁?---BerkeleyDB与SQLite评测对比 "

上文中还提到,"据说FastDB很快,但数据库大小不能大于物理内存...",于是笔者对FastDB产生了兴趣,从FastDB作者的网站看到关于 这点的介绍,并不是说数据库大小不能大于物理内存,而是说数据库大小超过物理内存时,性能与不超过时相比会有一定的降低(降低幅度未作说明,估计是不推荐 使用)。幸运地是,目前物理内存实在说不上贵,服务器内存在10G之上都是很正常的事情了。因此可以根据具体项目数据量需求来确定是否能使用 FastDB,比如并不是所有的表都需要放在内存中。下面即将描述的测试表明,一旦使用FastDB,其性能在免费MMDB产品中绝对可执牛耳。由于已经 有人对BDB和SQLite进行过比较,因此下面仅将FastDB与其中的优胜者SQLite进行性能测评。SQLite采用内存模式,即打开数据库使使 用":memory:"参数,此时SQLite不产生数据库文件,所有操作都在内存中,这一点需要特殊说明,与之不同的是,FastDB有两种模式,磁盘 模式和无盘模式,前者会产生磁盘文件,后者则与SQLite的内存模式相同。

说是测评,其实过程也很简单,无非是设计测试CASE,编写测试CODE,输出测试RESULT,最后做出结论。通常我们认为带索引的插入耗时相对 于查询和删除来说比较长,因此首先来看插入性能。采用一个简单的表来完成接下来的所有测试,表中仅包含两个字段,INTEGER intKey,和VARCHAR strKey。测试平台为Window7 32bit系统(Evaluation Copy 7127),编译器VC6 SP6。在DELL INSPIRON 640m上运行,CPU为Intel Core 2 CPU T5500 @ 1.66GHZ,内存2.5G。

对FastDB(采用磁盘模式),表结构的定义如下:

class _TestTable 

public: 
    db_int8 intKey; 
    char const* strKey; 
    TYPE_DESCRIPTOR((KEY(intKey, INDEXED), KEY(strKey, INDEXED))); 
};

REGISTER(_TestTable);

对SQLite,建表SQL如下:

CREATE TABLE [_TestTable] ( [intKey] INTEGER  NOT NULL PRIMARY KEY, [strKey] VARCHAR(50)  NULL)

2.2 不同事务模式下的插入性能比较

2.2.1 FastDB磁盘模式

我们首先按照批量事务处理的模式将intKey从1到nRecords(记录条数),并指定相应的strKey,分别调用相应的接口(均为原始 API)插入到两张表中,这里的批量事务处理模式指的是,比如插入10000条记录,插第一条之前开始事务,最后一条之后结束事务。此时在插入不同数目记 录时的表现分别如下(一万条、十万条、72万条、一百万条):

批量事务提交:

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe 
[FASTDB] Elapsed time for inserting 10000 record: 63 ms 
[SQLITE] Elapsed time for inserting 10000 record: 639 ms

E:\intrest\FastDB\PerfTest\Debug>del *.fdb (清除测试生成数据,重新测试,下同。)

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe 
[FASTDB] Elapsed time for inserting 100000 record: 1186 ms 
[SQLITE] Elapsed time for inserting 100000 record: 6318 ms

E:\intrest\FastDB\PerfTest\Debug>del *.fdb

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe 
[FASTDB] Elapsed time for inserting 7200000 record: 152460 ms 
[SQLITE] Elapsed time for inserting 7200000 record: 560121 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe 
[FASTDB] Elapsed time for inserting 1000000 record: 15522 ms 
[SQLITE] Elapsed time for inserting 1000000 record: 67423 ms

从上我们可以看出,在批量事务模式下,FastDB比SQLite的插入性能提高了3-10倍。但是在很多情况下,我们可能会需要逐条逐条的事务提交,下面给出了逐条事务模式的测试结果:

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe 
[FASTDB] Elapsed time for inserting 10000 record: 57315 ms(这个太恐怖了,不调整的话没法使用) 
[SQLITE] Elapsed time for inserting 10000 record: 780 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe (SQLITE显式分条事务) 
[FASTDB] Elapsed time for inserting 10000 record: 59967 ms 
[SQLITE] Elapsed time for inserting 10000 record: 1154 ms

从上我们可以看出,FastDB在这种情形下的性能急遽降低,降到一个几乎不能接收的水平。经过对FastDB的源代码分析(开源的好处体现出来 了),发现FastDB在每次事务提交时,都会将变更的数据内容同步到磁盘文件中(这是因为我们采用了磁盘模式),因此造成性能的显著降低。

直观上看,解决FastDB的这个问题有两种办法,一是避免每次事务提交时同步到磁盘,因为在这种应用中,这种同步操作并不需要实时进行,通常每隔 一段时间同步一次就可以了(比如1S、1Min、等根据具体项目的可靠性需要);二是使用前面提到的FastDB无盘(DISKLESS)模式。

我们首先来看第一种方案,通过SEARCH FastDB文档(文档和社区是FastDB的一个软肋),我们发现作者已经考虑到了这个问题,FastDB为数据库提供了precommit的接口,用 于完成除sync到磁盘文件外的所有事物操作,如释放mutex资源等。同时提供了backup接口,用来完成内存数据到磁盘文件的备份,甚至支持打开数 据库时同时指定定时备份到磁盘文件的间隔。这样一来,每次事务提交的效率理论上会得到大大提高,并且通过定时备份机制可以保证数据的可靠性。我们来看使用 precommit进行逐条事务提交时FastDB的表现:

E:\intrest\FastDB\PerfTest\Debug>PerfTest(使用precommit逐条提交事务) 
[FASTDB] Elapsed time for inserting 10000 record: 62 ms 
[SQLITE] Elapsed time for inserting 10000 record: 1170 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest 
[FASTDB] Elapsed time for inserting 100000 record: 1170 ms 
[SQLITE] Elapsed time for inserting 100000 record: 11747 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest 
[FASTDB] Elapsed time for inserting 1000000 record: 8081 ms 
[SQLITE] Elapsed time for inserting 1000000 record: 125768 ms

从上可以看出,在逐条事务模式下,通过使用precommit技术,FastDB性能比SQLite提高了10倍左右。当然也许有读者怀疑加了备份 机制之后的性能,确实笔者没有进行这项测试,但是,需要注意的是,FastDB在数据库关闭时会强制sync到磁盘文件,但SQLite没有这种功能,同 时,在进行这项测试时,两种数据库都没有定时备份机制,因此该比较是公平的。

2.2.2 FastDB无盘模式

再来看第二种方案,FastDB采用无盘(通过编译选项控制生成DISKLESS版本)模式,此时FastDB初始化一段共享内存(shmat or mmap),这个初始大小通常很大,并且运行期不能扩展(无盘模式的劣势)。我们将初始共享内存设置为1G,得到的测试结果如下:

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe 
[FASTDB] Elapsed time for inserting 100000 record: 624 ms (批量事务提交) 
[SQLITE] Elapsed time for inserting 100000 record: 11544 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe 
[FASTDB] Elapsed time for inserting 100000 record: 7410 ms (逐条事务提交) 
[SQLITE] Elapsed time for inserting 100000 record: 11560 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe 
[FASTDB] Elapsed time for inserting 1000000 record: 134660 ms 
[SQLITE] Elapsed time for inserting 1000000 record: 120167 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe 
[FASTDB] Elapsed time for inserting 250000 record: 23666 ms 
[SQLITE] Elapsed time for inserting 250000 record: 29110 ms

从上我们可以看出,无盘模式在大数据量下的表现与SQLite相近,这一点不是很好理解,需要研究DISKLESS的设计模式,理论上应该与 precommit模式性能相近。但是实践是检验真理的唯一标准。我们可以看出,磁盘模式的precommit方式性能表现卓越,不管从横向还是纵向来 看。

2.3 查询性能比较

下面的比较都使用磁盘模式的precommit方式,再来看索引查询的性能表现,测试时都是先插入十万条数据后,再分别对该十万条数据进行查询,需 要注意的是我们同时对FastDB是否增加HASH索引的性能进行了横向测评,FastDB增加HASH索引很简单,通过修改TYPE- DESCRIPTOR来完成,上面的class中改为TYPE_DESCRIPTOR((KEY(intKey, INDEXED), KEY(strKey, INDEXED)));即为intKey增加了Hash索引。

E:\intrest\FastDB\PerfTest\Debug>perftest (FASTDB哈希索引) 
[FASTDB] Elapsed time for inserting 100000 record: 624 ms 
[FASTDB] Elapsed time for 100000 index searches: 328 ms 
[SQLITE] Elapsed time for inserting 100000 record: 10312 ms 
[SQLITE] Elapsed time for 100000 index searches: 10935 ms

E:\intrest\FastDB\PerfTest\Debug>perftest(FASTDB非哈希索引) 
[FASTDB] Elapsed time for inserting 100000 record: 577 ms 
[FASTDB] Elapsed time for 100000 index searches: 515 ms 
[SQLITE] Elapsed time for inserting 100000 record: 10343 ms 
[SQLITE] Elapsed time for 100000 index searches: 9532 ms

从测试结果可以看出,查询十万条索引记录的效率,FastDB要比SQLite快20倍左右,并且在增加HASH索引后能够得到进一步的改善。

2.4 删除性能比较及综合表现

最后,我们在测试删除效率时,同时综合来看FastDB与SQLite之间插入、查询、删除的性能表现:

插入、查询、删除综合比较:

E:\intrest\FastDB\PerfTest\Debug>perftest(批量删除,FASTDB.removeall(),SQLITE.delete*) 
[FASTDB] Elapsed time for inserting 100000 record: 608 ms 
[FASTDB] Elapsed time for 100000 index searches: 687 ms 
[FASTDB] Elapsed time for deleting all 100000 records: 16 ms 
[SQLITE] Elapsed time for inserting 100000 record: 11107 ms 
[SQLITE] Elapsed time for 100000 index searches: 10062 ms 
[SQLITE] Elapsed time for deleting all 100000 records: 16 ms

E:\intrest\FastDB\PerfTest\Debug>perftest(逐条删除) 
[FASTDB] Elapsed time for inserting 100000 record: 593 ms 
[FASTDB] Elapsed time for 100000 index searches: 562 ms 
[FASTDB] Elapsed time for deleting all 100000 records one by one: 905 ms 
[SQLITE] Elapsed time for inserting 100000 record: 10406 ms 
[SQLITE] Elapsed time for 100000 index searches: 10249 ms 
[SQLITE] Elapsed time for deleting all 100000 records one by one: 8923 ms

从上可以看出,就删除效率而言,批量删除的速度二者相近,而逐条删除时,十万条记录的删除累积,FastDB比SQLite快了10倍左右。

 

2.5 总结

优点:FastDB磁盘模式下,采用precommit方式,性能远远优于SQLite,并且FastDB提供了完善的备份恢复机制,能够保证数据 安全。FastDB的无盘模式在小数据量时表现优越,并且不会产生磁盘数据文件,也不能加载已经保存的数据库文件,看起来更像是针对嵌入式设备(如智能手 机、PDA等)开发的,对于这种场景可以考虑使用无盘模式。

缺点:FastDB目前能够SEARCH到的比较著名的应用是PingTel公司的开源统一通信产品SIPX,该产品采用的是FastDB的磁盘模 式。这可能多少与FastDB的完全授权模式有关,而SQLite采用的是GPL的不允许闭源的商业发布。当然主要还是社区的不成熟,这从Google Trends的搜索结果也能看出。社区的不成熟会带来学习成本的增加,这一点在选型时也需要考虑。

  • FastDB
    1 引用
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    4 引用 • 7 回帖
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    346 引用 • 760 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖 • 1 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    7 引用 • 28 回帖 • 1 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖 • 2 关注
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 1 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    955 引用 • 944 回帖
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    92 引用 • 752 回帖 • 2 关注
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    151 引用 • 257 回帖 • 1 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    32 引用 • 99 回帖
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    134 引用 • 1127 回帖 • 110 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 444 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    591 引用 • 3528 回帖
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 43 关注
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 81 关注
  • 安全

    安全永远都不是一个小问题。

    199 引用 • 818 回帖
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 824 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    315 引用 • 547 回帖
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    118 引用 • 54 回帖 • 5 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 67 回帖 • 445 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 59 回帖 • 1 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 108 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 520 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    61 引用 • 29 回帖 • 10 关注
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    2 引用 • 14 回帖 • 2 关注