ImageVerifierCode 换一换
格式:DOCX , 页数:7 ,大小:23.34KB ,
资源ID:3712103      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3712103.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(MongoDB与Tokyo Tyrant性能比较.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

MongoDB与Tokyo Tyrant性能比较.docx

1、MongoDB与Tokyo Tyrant性能比较MongoDB与Tokyo Tyrant性能比较MongoDB与Tokyo Tyrant性能比较2010年11月15日星期一下午11:10(1):基础CRU操作以前的项目大都把数据存放在关系型数据库中,关系型数据库的优势在于使用普及,资料丰富,且有大量辅助类库来简化开发。当然它们的问题比较明显的,一是在数据量上升的情况下伸缩性比较差,且进行结构调整的代价比较高。因此现在有个所谓NoSQL的运动也逐渐普遍起来了,它便是借助一些非关系型存储方式来开发项目(个人认为其实将它解释为Not Only SQL更为合适)。因此在新项目里,我也想尝试一下使用之前

2、一直只是听说的存储方式。在和同事的交流过程中,我了解到他们的项目正在尝试使用Tokyo Tyrant(后称TT)进行存储,并且据说效果不错,因此我一开始也打算尝试使用TT进行主要存储,为此也花了一定时间为其编写.NET平台下的驱动程序。不过在驱动程序的开发过程中,我逐渐意识到TT的功能有着严重的限制,似乎并不适合作为接下来项目的主要存储方式。因此,我又将眼光转向了之前关注过的MongoDB上。MongoDB也是NoSQL的代表之一,是一个面向文档的,架构灵活(Schema-less)的存储方式,在仔细阅读相关资料之后,我发现它的功能与TT相比可谓天上地下,非常适合许搭建各类项目(关于这点以后有

3、机会再谈)。不过,既然选择NoSQL的原因是性能,那么他们的性能表现究竟如何呢?TT的性能表现在业界非常出名,而MongoDB的使用便相对较少了(当然,官网列举了不少案例,最近著名的开源网站SourceForge也打算使用MongoDB重新设计他们的网站)。为此,我决定亲手比较一下两者的性能表现。测试环境及数据由于缺乏合适的环境,因此我不得不在我的MBP上进行这次性能比较,参数如下:OS:Mac OS Xv 10.6.2(Snow Leopard)RAM:4GB/1067MHz/DDR 3CPU:2.53GHz Intel Core 2Duo64-bit Kernel and Extensio

4、ns:YesTT在64 bit环境下编译,MongoDB使用64 bit版本。在测试执行时,我尽量关闭多余的应用程序,避免其它因素造成影响。同样,由于条件限制,我只得把客户端和服务器跑在同一台机器上。测试代码使用Ruby编写,这是由于两者都有官方提供的驱动程序。此外,由于我对于两者的优化都不太熟悉,因此它们都使用了默认的配置。关于测试数据,我将存入110万条新闻数据,包含以下字段:ID:标识,32位整数,带索引Title:标题,字符串CategoryID:分类ID,32位整数,带索引CreateTime:日期,保存为32位整数,带索引UserID:用户ID,32位整数,带索引Tags:标签集合

5、,字符串数组,带索引Source:来源,字符串SourceUrl:来源URL,字符串Status:状态,32位整数为了相对接近真实的环境的数据分布特征(便于以后进行查询操作比较),我设计了这样的测试数据(具体可阅读代码):2万个分类,分别拥有10个至100条新闻,总共110万条记录。1万个用户,根据分类id取模得到其归属。创建时间从2010年1月1日起递增,每条记录增加1秒。每条记录拥有2到6个Tag,除了其中一个之外,都从一个1.7万个Tag库中获取。每条记录的字符串字段都不长(20-30字符)由于TT只支持字符串的值(但可以建立数字索引,会将字符串当作数字来识别),因此事实上所有的值都会转

6、化为字符串进行保存。此外,由于存在根据Tag查找新闻的业务,因此对于Tags字段也建立了索引,其中MongoDB直接支持对字符串数组的索引(索引其中每个元素),而在存入TT时则转化为空格分隔的字符串,并为其建立倒排索引(Token Inverted Index)以便进行全文查找。在存储方式上,所有数据将放入MongoDB的同一个集合内,而TT则选用Table Database存储结构。在使用TT时,另一种做法是完全使用键值对来保存一条记录的各个字段,不过这样做会大大限制TT的功能,或是会为系统编写带来额外的复杂度,便不考虑Hash/B+Tree/Fixed-length等存储方式了。插入操作性

7、能比较具体代码在tt-insert.rb及mdb-insert.rb文件中。两段代码均使用一个连接,使用循环每次插入一条:由于如果每次都建立连接,会在TCP/IP连接的打开关闭上消耗大部分时间,由于实际项目中基本都会使用连接池等机制来复用连接,因此这方面便不多做考虑;再者,由于实际插入时几乎不可能批量操作,因此这里并不使用两者提供的批量插入功能。脚本每插入10万条记录便打印出所耗时间,结果如下:从结果上看,MongoDB大约有10%的领先,不过总体来说两者的差距不大。值得一提的是,TT在数据量越大的情况下,每插入10万条记录的耗时越长(也从同事的使用过程中确认了这一点)。因此,一开始两者插入速

8、度几乎没有差距,但是慢慢地TT便落后于MongoDB了。目前推测这可能是TT的Table Database存储结构特有的问题,不知道随着数据量的增长TT表现如何,因为对于一个大型系统来说,100多万条记录实际上只是一个很小的数目。有同事推测,TT插入性能低是因为建立了Tags字段的倒排索引,于是我也测试了不在Tags字段上建索引的情况。令人惊讶的是,同样去除Tags字段的索引之后,MongoDB的性能提升超过20%,而TT的性能提升却微乎其微。值得一提的是,放入相同的记录之后,TT的文件为400多M,但MongoDB则为整整2G。因此推测这是MongoDB进行空间预分配的结果,邮件列表上的这个

9、讨论也证实了这一点。此外,上面每次测试都是从零开始的,经测试如果在插入前为MongoDB预分配文件空间,则性能还会有些许提高。通过主键获取记录性能比较具体代码在tt-get-by-key.rb及mdb-get-by-key.rb文件中。两段代码同样均使用一个连接,使用循环进行100万次Get操作,每次都随机获取一个110万以内的数字,并作为ID进行Get操作。同样,每10万次Get操作后打印出所耗时间,结果如下:在Get操作方面,MongoDB有大约20%的领先。不过从实际情况分析,这方面的差距也不是太大,因为在项目中根据主键获取记录的操作8成以上都是落在缓存上的,因此在这方面对存储的要求并不

10、高。通过主键更新记录性能比较具体代码在tt-update-by-key.rb及mdb-update-by-key.rb文件中。两段代码各自使用同一个连接,使用循环进行大量的更新操作。每次随机获取一个110万以内的数字,并作为ID更新其CreateTime、Title、Source、SourceUrl、Status五个字段。结果如下:首先是MongoDB的三次测试结果,每次更新100万条数据。从数据上看,三次查询的性能越来越高,这个现象在重启服务器之后可以重现(三次测试之间并没有重启服务器)。请注意,TT的三次测试均只更新了10万条记录(因为100万条记录耗时太长)。和MongoDB类似,一开始

11、查询性能较差,但是会慢慢提高,这个现象在重启服务器后也能重现,于是猜测是缓存的结果。即便如此,TT的更新时的最高速度只有大约没秒1500次,而MongoDB却超过了每秒5000次。这是因为TT在功能上有硬伤:它无法像SQL的UPDATE语句那样更新某条记录的部分字段,因此必须全部取出,修改后再整体写入。而MongoDB支持高效的直接修改-这也成为MongoDB放在首页上的招牌功能。因此,TT对于更新某个分类下所有新闻的状态这样的操作会很不适应,而它的这个限制导致我们很难实现如乐观并发控制这样的手段。此外,在实际应用中客户端与服务器不会使用本地连接,因此在生产环境中TT和MongoDB在这方面的

12、差距可能会更明显一些。总结到目前为止,我们测试了TT和MongoDB在CRU三种基本操作下的性能,似乎MongoDB全面胜过Tokyo Tyrant。不过需要强调的是,这个测试还很不全面:它没有使用合适的环境,也没有对两者进行适当的优化。此外,两者在并发情况下,或是同时读写下的表现如何也是值得进一步考察的,我也会设计更多的测试用例。因此,这里的数据仅供参考,如果有合适的环境我也会重新进行测试。(2):并发写入操作在上一次的测试中我们比较了MongoDB与Tokyo Tyrant的Table Database两种存储方式的性能。不过由于条件限制,我只能在自己的MBP上测试,而这至少会带来两个问题

13、。首先,真实环境下客户端和服务器是通过内网连接的,它的性能比本地回环要慢不少,一些和网络传输性能有关的问题可能会体现不出。其次,由于无法进行并发测试(并发测试的客户端资源占用较高,放在同一台机器上准确性较差),这又和生产环境有很大区别了。因此,我前两天向同事借了台性能测试用的机器,希望可以得到更可靠的结果。测试环境与数据这次我使用了新的环境进行性能测试:OS:CentOS release 5.3(Final)RAM:4GBCPU:Intel(R)Xeon(R)CPU E54052.00GHz(64 bit,4 cores*2)其他:SCSI硬盘,ext3文件系统客户端与服务器端配置相同,两台机

14、器使用百兆网相连,测试时服务器保持空闲。测试数据的结构与之前相同(包括索引),数据分布同样保持一致,每个线程插入的数量较少,但每次测试的总数均不低于上次(110万条)。为了测试并发插入的性能,我稍微改写了测试脚本。首先,我为它增加init参数,它的作用是初始化存储结构(清除数据,建立索引),拿MongoDB的测试脚本为例:#ruby mdb-insert.rb init index for CreateTime created.index for CategoryID created.index for UserID created.index for Tags created.initial

15、ize completed.此外,脚本还支持分类范围的指定,例如:#ruby mdb-insert.rb 101 200这表示我们将插入CategoryID为101至200的新闻,由于每个分类中均匀分布10至100条记录,因此只要范围的上下限保持10的倍数,这样平均每个分类有55条新闻,于是新闻ID也可以此计算出来。例如分类101至200的新闻,其ID便为5501至11000。您可以通过阅读代码了解这些细节。为了并行测试,每次我就将同时执行多个脚本进行插入,每个脚本提供不同的参数。我使用类似这样的shell脚本来启动并行任务:#!/bin/bash#mdb-insert.sh echo=ini

16、tialize=ruby mdb-insert.rb init for(i=1;i=5;i+)do let begin=$(4000*($i-1)+1)let end=$(4000*$i)echo=start task$i=ruby mdb-insert.rb$begin$end logs/mdb-insert-$begin-$end.log&done这段脚本将启动5个任务,每个任务将插入4000个分类,即22万条记录。5个任务总共插入110万条记录,与前次持平。接下来的测试中,我在增加任务数量的同时也会适当降低每个任务插入的记录数目。最多我将启用100个任务,每个任务插入1000个分类,即所

17、有任务共计插入550万条记录,是之前的5倍。在所有的测试中,无论多少个任务都是同时启动,且几乎同时结束(与总耗时相比很小)。因此,在接下来的数据中我不会列出每个任务的开始及结束时间,如果您关心这部分数据,可以在文章结尾处可以获得本次测试生成的所有记录文件。Tokyo Tyrant性能测试第1次测试启动5个任务,每个任务4000个分类,共计插入110万条记录。结果如下(第1行粗体表示万条记录,每个数字的单位为秒,下同):与之前的现象类似,当数据库中的数据越多时,插入速度也会随之减慢:在每个任务插入前1万条记录时,耗时大约为5、6秒。但是到了中后期,每插入1万条数据则需要等待15至20,甚至30秒

18、的时间。值得注意的是,虽然使用了较好的服务器,但是并行插入110万条记录的时间却比上次要来的多(这次耗时340秒,而之前是)。原因可能是客户端与服务器端的分离导致网络速度的下降。另一种可能我猜测是,根据Tokyo Cabinet的文档中提到文件读写锁的使用,因此每次只能插入一条记录,且插入(或更新)时无法读取数据,因而在并发环境下Tokyo Tyrant(它其实是Tokyo Cabinet上层的TCP服务器)的表现并不会有所提高。不过据读过Tokyo Cabinet代码的同事说,Tokyo Cabint在使用Table Database的时候锁粒度不会那么大,因此关于这点还需要寻找进一步的资料

19、。第2次测试启动10个任务,每个任务还是4000个分类,因此共计插入220万条记录。结果如下:第2次测试的总数据量为第1次的2倍,而耗时却是第1次的3.5倍,这应该还是由于数据量增大而导致的插入性能降低。但是,我们目前还不能排除这和并发连接数有关的可能-虽然我们有理由相信这个性能问题只和数据量相关(稍后再说)。为了查明并发程度和性能是否有关系,我们再进行第3次测试。第3次测试启动20个任务,每个任务2000个分类,因此共计仍旧是220万条记录。结果如下:这个结果实在是非常能够说明问题:第3次的耗时与上一次几乎完全相同,这意味着加大并发量并不会影响TT的性能。这是因为TT在服务器端维护了一个线程

20、池(现在的测试,也是默认情况下为8个线程),因此请求再多,同时进行的任务也是有限的,而累积的任务会排在队列中。这也是使用队列和固定数量工作线程的好处:即使压力再大,服务器端的吞吐量也能够一直保持较高水准,而客户端请求的响应时间随着请求数量增大而线性增长。如果没有队列,随着压力增大,服务器端吞吐量会剧烈下降(一般至少也是线性的),而客户端请求的响应时间增长更快,直至超时。为此,我们也没有必要继续测试更多的并发数量了,因为即便是再多并发,TT的吞吐量(即插入记录的数目)也只是和数据库中记录数量相关。根据测试,我们可以总结出:插入110万条记录的平均吞吐量为:大约3225条/秒插入220万条记录的平

21、均吞吐量为:大约1833条/秒当数据库包含100万条数据时吞吐量为:17001800条/秒当数据库包含200万条数据时吞吐量为:150160条/秒似乎随着数据量的增加,TT的吞吐量下降得也非常明显。这其中可能有索引的因素在里面,因此如果您想要得到适合自己的结果,最好可以亲自进行试验。MongoDB性能测试与TT相同,第1次测试启动5个任务,每个任务4000个分类,共计插入110万条记录。结果如下:在5个并发任务的情况下,MongoDB的表现较TT要出彩不少。首先,随着数据库中已有记录的增加,插入速度并没有降低的迹象,可以说十分平稳。此外,在同样的客户端和服务器环境下,MongoDB插入110万

22、条数据的耗时比TT的一半还要略少一些。而且,虽然网速带来的一定负面影响,但可能是由于服务器配置的提高,再加上并发写入的性能优势,此次测试比上次单机环境下的表现也要好上许多。那么在数据量和并发继续增大的情况下MongoDB表现如何呢?于是第2次测试启动10个任务,每个任务还是4000个分类,共计插入220万条记录。结果如下:第2次的数据量为第1次的2倍,而耗时则大约为2.08倍,两者基本保持一致,这说明了MongoDB在数据量和并发量增加的情况下,吞吐量几乎没有改变。第3次测试依旧与TT相同,启用20个任务,每个任务2000个分类,共计插入220万条记录。结果如下:在总数据量不变的情况下,我们又

23、将并发量提高了一倍,但是MongoDB依旧表现出的稳定的吞吐量,总耗时与第2次测试几乎完全相同。这样看来,似乎在MongoDB在内部也有个类似于TT的队列机制以保证一定的吞吐量。为了验证这个看法,我再次加大了数据量和并发量。在第4次测试中我启用了50个任务,每个任务还是2000个分类,这样插入的记录数据则达到了550万。结果如下:在50个并发任务下,MongoDB终于略显疲态。第4次测试的数据量为第3次的2.5倍,但耗时却接近3.5倍。为了验证这是由于数据量增加,还是并发量提高引起的问题,我又进行了第最后一次测试。第5个测试中启用了100个任务,但每个任务只写入1000个分类,则总条目数还是和

24、第4次相同,为550万。结果如下:请注意,由于每个任务插入1000个分类,即5.5万条记录,因此上表中最后一栏为5.5而不是6。随着并发量的增大,MongoDB的耗时继续增加了。由于这个表现和之前的预测不同,我又把第4次和第5次测试各执行了一遍,结果并没有太大区别,基本可以排除环境异常这样的可能。经过5次测试的结果,我们可以得出MongoDB的性能指标:5个并发,插入110万条记录的平均吞吐量:大约6600条/秒10个并发,插入220万条记录的平均吞吐量:大约6300条/秒20个并发,插入220万条记录的平均吞吐量:大约6300条/秒50个并发,插入550万条记录的平均吞吐量:大约4500条/

25、秒100个并发,插入550万条记录的平均吞吐量:大约4100条/秒总体来说,虽然在数据量和并发量增大的情况下MongoDB的吞吐量有所下降,但是MongoDB的表现比TT还是要抢眼不少,而且在绝对数值上还是相当出彩的。其他信息其他还有一些信息可能值得参考。在进行测试时,我发现TT进程的CPU占有率比较低,除了少量时候出现80150%以外(top命令的结果,8核服务器),绝大部分时间CPU占有率只有2040%。MongoDB的CPU占有率比TT要高出不少,基本上保持在80110%之间(数据量和并发量在这里影响不大)。但是总体来说CPU的占有率都很低,毕竟现在的测试属于IO密集型操作。不过在内存占

26、有率方面,两者的区别很大。在测试过程中(服务器内存4G),TT进程的内存占有率一直保持在20%一下,而MongoDB会缓步增加,最后保持在80%上下。此外,在插入了550万条数据之后,MongoDB的数据文件增长到了6G。这个数字比上次测试的2G/110万稍有缓解,但还是比TT要大上许多。最后再来谈谈为什么仅仅测试了并发插入而没有更新和删除:其实这也是通过使用场景而设计出来的测试用例。因为对于此类存储来说,大量并发插入的场景比较多,例如日志记录,用户行为记录,或是SNS应用中常见的News Feed等等。这些场景的特点就是需要数据的不断增长,而大量密集的更新则很少会出现删除就更不用说了。至于并行的更新,我接下来也会进行测试的,只是可能会模拟一些实际的场景,例如在更新的同时进行不断地读取和插入吧。特别声明:1:资料来源于互联网,版权归属原作者2:资料内容属于网络意见,与本账号立场无关3:如有侵权,请告知,立即删除。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1