如何做软件性能测试报告告

性能测试报告_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
性能测试报告
阅读已结束,如果下载本文需要使用
想免费下载本文?
你可能喜欢如何做性能测试报告_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
如何做性能测试报告
系​统​化​介​绍​说​明​开​发​企​业​级​的​系​统​,​如​何​做​性​能​测​试​,​本​文​介​绍​了​使​用​J​m​e​t​t​y​、​L​o​a​d​R​u​n​n​e​r​两​种​压​力​测​试​工​具​,​以​及​n​m​o​n​监​控​工​具​,​在​调​整​、​设​置​好​各​级​参​数​配​置​前​提​下​进​行​压​测​,​详​细​分​析​测​试​结​果
阅读已结束,如果下载本文需要使用
想免费下载本文?
你可能喜欢全球最新的免费资源发布区
Linux VPS主机挂载硬盘扩容的方法和阿里云美国VPS主机性能测试报告
& 日 16:43 &
传统的VPS主机都是划定好硬盘大小,购买后想要扩容恐怕得升级套餐了,而现在流行的云主机则可以让用户自己选择硬盘大小,然后在用户新购买硬盘后,则可以将新的硬盘挂载在原VPS主机上,这样就能实现“无缝”扩容,大大提高了VPS主机的使用效率。
Linux VPS主机挂载硬盘是在纯命令的情况下完成了,由于是直接对硬盘操作,数据的安全性一定要有保障,在操作前一定要对硬盘作好备份。这里将以阿里云VPS主机挂载硬盘,来记录一下Linux VPS主机挂载硬盘的全过程,其它的主机的VPS主机可以参考执行。
说到美国主机,脑海第一个想到的就是国外人提供的空间和VPS服务,但是最近发现阿里云、腾讯云等也开始开卖在美国量产的主机空间。其实,在部落看来买国内的主机唯一的理由就是BA的问题,假如这个问题在今后某一个时间不再是个问题,国内的主机商们估计要倒一片。
而真的要让我想出购买阿里云、腾讯云在美国本土提供的主机空间的理由,恐怕也就是只有一个就是方便那些习惯用支付宝或者财付通的朋友,其它的如VPS配置、价格等都不是购买的理由。这里就来简单地测试一下阿里云美国VPS主机性能,有兴趣的朋友可以看看。
更多的有关于使用教程有:
Linux VPS主机挂载硬盘扩容的方法和阿里云美国VPS主机性能测试报告
一、阿里云美国VPS主机购买
1、阿里云美国VPS主机可以像购买国内的VPS主机一样用支付宝购买,开通和使用等都一样,参考:。ECS还可以免费试用,申请方法:。
2、这是阿里云美国VPS最低配置的价格,1GB,1核,1Mb带宽,一个月是75元。这价格和来相比,已经没有任何优势了。
3、阿里云美国VPS购买时也能增加云磁盘。
4、购买成功后,直接到阿里云控制面板中管理美国VPS主机即可。
二、阿里云美国VPS主机性能测试
1、这是阿里云美国VPS的硬盘读写速度,速度值在VPS界内已经是偏下了。
2、再来对比一下阿里云国内的VPS主机的硬盘读写速度,基本上和美国VPS主机一样,看来阿里云把生意做到美国还是用了一样的主机硬盘。
3、测试了一下阿里云美国VPS的机房带宽,表现可以。
4、用站长工具测试阿里云美国VPS的服务器IP地址显示为美国阿里云的。
5、国内响应的Ping值在250左右,比较稳定。
5、这是阿里云美国VPS用Unixbench 5.1.2测试的性能跑分,超过了1000分。(点击放大)
三、阿里云VPS主机挂载硬盘方法
1、阿里云购买VPS时默认的只有20GB的系统盘,安装了系统后基本上硬盘剩下不了多少了,所以我们一般还会再购买新的硬盘。让人无语的是阿里云的新硬盘不会自动挂载,我们每个人新购买了VPS后第一件事情就是挂载新的硬盘。
2、使用命令:df -h可以查看当前已经格式化和分区的硬盘。
3、使用命令:fdisk -l可以查看所有的硬盘。默认的是/dev/xvda,新购买的硬盘就是/dev/xvdb,如果你没有发现/dev/xvdb,那说明你不需要挂载了。
4、对数据盘进行分区。执行命令:fdisk -S 56 /dev/xvdb,根据提示,依次输入“n”,“p”“1”,两次回车,“wq”,分区就开始了,很快就会完成。
5、 查看新的分区。使用命令:fdisk -l就能看到新的分区/dev/xvdb1已经生成了。
6、格式化新分区。这里要说一下Ext3 和 Ext4两种格式。Linux kernel 自 2.6.28 开始正式支持新的文件系统 Ext4。 Ext4 是 Ext3 的改进版,修改了 Ext3 中部分重要的数据结构,而不仅仅像 Ext3 对 Ext2 那样,只是增加了一个日志功能而已。Ext4 可以提供更佳的性能和可靠性,还有更为丰富的功能
7、根据你自己的需要来选择要新分区的格式,执行命令:mkfs.ext3 /dev/xvdb1或者mkfs.ext4 /dev/xvdb1对新分区进行格式化,格式化的时间根据硬盘大小有所不同。
8、添加分区信息。执行命令:echo '/dev/xvdb1& /mnt ext3&&& defaults&&& 0& 0' && /etc/fstab或者echo '/dev/xvdb1& /mnt ext4&&& defaults&&& 0& 0' && /etc/fstab写入分区信息,然后使用命令:cat /etc/fstab查看到信息写入成功的信息。
9、这里特别提示一下:/mnt 表示是你新硬盘挂载的目录,一般来说我们都是将硬盘作为网站存储数据的,因此此处的目录可以设置为网站的目录,例如的网站目录是www,这里就可以改成/www了。
10、挂载新分区。上述操作完成后,就可以使用mount -a来完成硬盘挂载了。挂载成功后使用命令:df -h就可以看到新的硬盘分区已经出现了。
四、VPS主机解除硬盘挂载和挂载多个硬盘
1、VPS主机硬盘解除挂载。执行:umount /dev/xvdb1,再使用命令df -h就会发现硬盘分区已经没有了。
2、另一种方法就是使用阿里云VPS控制面板的云磁盘修改属性,达到磁盘释放的目的。
3、阿里云VPS主机可以增加多个独立硬盘。
4、购买后选择想要设置的硬盘挂载点。
五、阿里云VPS主机直接挂载扩展现有硬盘
1、上面我们只是将多块新硬盘挂载在阿里云VPS上的不同目录上,这样其实有一个问题就是,有时我们只是想要直接扩容原有的硬盘,而不是挂载另一个独立的硬盘出来。目前,阿里云并没有提供直接扩容硬盘的方法。
2、不过我们可以使用LVM来解决。通过使用Linux的逻辑卷管理器(Logical Volume Manager, LVM),用户可以在系统运行时动态调整文件系统的大小,把数据从一块硬盘重定位到另一块硬盘,也可以提高I/O操作的性能,以及提供冗余保护,它的快照功能允许用户对逻辑卷进行实时的备份。
3、基本原理就是:硬盘1分了两个分区,/dev/sda1和/dev/sda2,硬盘2没有创建分区。在/dev/sda2和/dev/sdb上创建物理卷,然后把这两个物理卷加入到逻辑卷组vg0中,这样,逻辑卷组vg0看起来像一块很大的逻辑硬盘。然后在其中创建两个逻辑卷/dev/vg0/lv0和/dev/vg0/lv1。最后,分别在/dev/sda1、/dev/vg0/lv0和/dev/vg0/lv1上创建文件系统,并分别把它们挂载到文件系统树中。这样看上去,逻辑卷像是一个逻辑的分区。
4、LVM的安装。首先是,加载device-mapper模块,从linux内核2.6.9开始,device-mapper模块就已经包含在内,所以你只需加载即可。加载mapper模块:modprobe dm_mod。查看是否已经加载:lsmod | grep dm_mod。
5、输出:dm_mod 63097& 4 dm_mirror,dm_multipath,dm_raid45,dm_log信息就表示成功了。如果你的内核高于2.6.9却没有此模块,可以使用yum install device-mapper命令安装。
6、其次是,安装LVM2,执行命令:yum install lvm2或者是sudo apt-get install lvm2。
7、首先是解绑:umount -a,接着编辑启动项:vi /dev/fstab,将之前/dev/xvdb1& /mnt ext3&&& defaults&&& 0& 0 这条加入进去的启动项去掉,然后保存。接着用fdisk 删除分区。假设你之前绑定的是/dev/xvdb1,执行命令:
fdisk /dev/xvdb
8、接着在用 fdisk -l查看是不是发现xvdb1已经解绑了。假设你看看到有两个盘还没挂载:/dev/xvdb和/dev/xvdc,先处理/dev/xvdb 。按下面顺序输入
fdisk /dev/xvdb
9、然后按同样办法处理 /dev/xvdc,命令:
fdisk /dev/xvdc
10、再用fdisk -l看看是不是已经出现 /dev/xvdb1和 /dev/xvdc1这两个分区了。下面分别为这两个分区创建物理卷,命令:pvcreate /dev/xvdb1和pvcreate /dev/xvdc1(如果你没有/dev/xvdc1,只是想以后为增加xvdb1容量,请自动忽略关于xvdc1的操作步骤)
11、接着创建卷组:vgcreate mygroup /dev/xvdb1,其中mygroup是卷组名,可自己定义。接着是激活卷组,命令:vgchange -ay mygroup,激活卷组后重启VPS。扩展卷组:vgextend mygroup /dev/xvdc1
12、创建逻辑卷:vgdisplay mygroup | grep "Total PE",先使用上面这个命令,得到:Total PE 15357,这个15357就是该卷组的逻辑数,执行命令:lvcreate -l15357& mygroup& -n& wwwroot,其中wwwroot是逻辑卷的卷名。
13、格式化逻辑卷:mkfs.ext3 /dev/mygroup/wwwroot。创建一个你要绑定的目录,比如/www:mkdir /www。加入启动项:echo '/dev/mygroup/wwwroot&&&& /www&&&&& ext3&&&&&& defaults&&& 0&&&& 0' && /etc/fstab。最后挂载:mount -a,用df -hal看一下,是不是已经成功了。
14、用了这个办法,如果你以后想再次扩展增加这个分区,也很容易的,假设你用fdisk -l 看到/dev/xvdd 是你新买硬盘,需要扩展到之前的分区上,用命令:
fdisk /dev/xvdd
reboot 重启
15、得到/dev/xvdd1,接着执行命令:
/pvcreate /dev/xvdd1
vgextend mygroup /dev/xvdd1
vgdisplay mygroup | grep "Total PE"
16、这个命令得到总PE数& Total PE 10240,执行命令:lvresize -l10240 /dev/mygroup/wwwroot和resize2fs /dev/mygroup/wwwroot,最后运行df -hal,看看成功没。
六、Linux VPS主机挂载硬盘小结
1、从上面的操作来看,阿里云的centos的系统盘并没有使用LVM2分区,所以无法扩展/dev/hda1盘,大家在选择网站数据存储位置时最好是放在数据盘中。而且挂载硬盘越早越好,越在后面对数据操作风险性就越大。
2、阿里云的VPS主机不能做到无缝扩容硬盘实在是一大遗憾,但是未来直接扩容应该是云主机的趋势,相信过不了多久大家就可以像扩容虚拟主机的空间一样直接在原硬盘上增加容量空间了。建议在对硬盘操作前一定做好备份。
文章出自: 部分代码参考 版权所有。本站文章除注明出处外,皆为作者原创文章,可自由引用,但请注明来源。
真的,我猜你也会喜欢的:
您或许对下面这些文章有兴趣:&&&&&&&&&&&&&&&&&&&&本月吐槽辛苦排行榜
免费资源部落博客、论坛、问答和优惠网的创建者
经常混迹于各种免费资源中,尝鲜后乐于分享给他人。用WP搭建了部落博客,没事儿就折腾Wordpress,喜欢找免费空间,但只求精,稳定,耐用。有时也会介绍一点关于建站的知识和主机、服务器的使用心得与体会。PS:此人为男。
TA的专栏:&&|&&
关于本文的作者
所属分类:
链接地址:
浏览前页:
浏览后页:
部落快速搜索栏
热门点击排行榜
网站导航栏
免费资源重点推荐
最新文章推荐
部落最新评论列表
不得不看的秘密
部落本月最受关注的热点
(热度191℃) (热度180℃) (热度145℃) (热度128℃) (热度126℃) (热度107℃) (热度95℃) (热度94℃) (热度94℃) (热度83℃) (热度83℃) (热度80℃) (热度75℃) (热度73℃) (热度72℃) (热度71℃) (热度68℃)
部落本月踩得最多的宝贝
(踩4,592次) (踩4,543次) (踩4,422次) (踩4,381次) (踩3,935次) (踩3,686次) (踩3,623次) (踩3,090次) (踩3,068次) (踩2,987次)
免费资源部落,是一个致力发布和推广来自世界各地的免费资源,包括多样实用的免费空间、各种优秀的免费软件、各样可用的免费网盘等个人博客网站。站长qi是一位很普通不过的人,长期关注网络空间、互联网、软件应用、程序开发与设计、网络应用等。免费资源部落成立的目的就是希望与更多人分享网络快乐与精彩!本站持续修改完善中,如遇不便还请谅解^_^酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
在本篇测试报告中,我们使用Yahoo!发布的标准YCSB测试规则,对MongoDB、SequoiaDB、Cassandra、HBase进行对比,并尝试给出每种不同产品所适用的应用场景。在测试配置中,我们尽可能对全部产品做到高可用配置,而在一致性级别上则使用最终一致性。
在测试中我们会对两种类型的NoSQL数据库做横向对比,包括Document-Oriented文档类数据库、以及Big-Table宽表类数据库。由于每种类型的数据库具有很多自己独特的特性,我们不能将每种特性一一表现在该测评结果中。本测试主要针对数据库在不同任务类型下的性能指标进行,且仅依赖YCSB所提供的标准测试流程。
本测试将详细列出测试的物理环境以及配置信息,以便于读者能够使用自己的环境独立验证结果。
1.测试产品
本测试主要对比两种类型的NoSQL数据库,包括四款不同的产品:
MongoDB(文档类,V2.6.1)
SequoiaDB(文档类,V1.8)
HBase(宽表类,V0.94.6-CDH 4.5.0)
Cassandra(宽表类,V1.1.12)
其中MongoDB作为当前市场占有率最高的数据库,可能是众多读者所关心的产品,提供丰富的数据库功能,号称是最接近关系型数据库的NoSQL产品;而SequoiaDB由前IBM DB2团队的研发人员创建,据称在性能和功能上能够与MongoDB做正面抗衡,同样提供很多MongoDB所提供的功能(例如分片、多索引等特性)。
HBase则是Hadoop框架的一员,也已经被广大企业和互联网用户所接受,我们使用的版本0.94.6是跟随CDH 4.5.0安装包的版本;而Cassandra则是与HBase类似的产品,由Facebook研发并进行开源,同样拥有广大的用户市场。
我们的测试使用由Yahoo!研究院发布的Yahoo Cloud Serving Benchmark (YCSB)基准测试,并将接口对各自产品的最新版进行了修改和适配。我们在正文后的附录中也提供了SequoiaDB的YCSB测试接口。
需要重新强调的是,每种不同的产品都有各自的应用场景。YCSB测试尽管是Yahoo!研究院提供的测试框架,但是在很多场景下并不能完全发挥出每个产品各自的特点。在本测试中,我们尝试使用YCSB框架给出最为客观的评估结果。如果对于该测试结果或配置存在疑问,我们欢迎广大读者根据自身需要重新调整,并将结果开放以供参考。
2. 测试场景
YCSB测试框架提供了丰富的场景配置机制,允许用户根据需要选择需要导入的数据量和增删改查之间相应的比例。在本测试中,我们导入一亿条数据,并对如下场景进行对比。
单条记录导入
单条记录导入
批量记录导入
批量记录导入
查询导入平衡
50%导入,50%查询
95%更新,5%查询
95%查询,5%更新
95%查询,5%导入
对于数据导入的场景,我们对单条记录插入和批量插入两个场景进行了区分。对于一些数据库来说,默认配置会在客户端将一批记录打包并统一发送给服务器,对于这类产品,尽管其接口为单条记录操作,我们依然将其归类为批量记录导入模式。
写入和查询的数据模拟典型日志记录的长度,具有以下特性:
字段名长度
记录总大小
全部字段类型
总裸数据量
数据副本份数
其中,SequoiaDB与MongoDB的分片均配置为一主两从;HBase所在的HDFS设置复制份数为3;Cassandra建表时使用参数replication_factor=2。
一致性级别上,我们使用最弱的最终一致性,读写的write concern均设置为1。
3. 测试环境
本测试中,测试环境总共包含4台Dell R520物理机作为数据存储。生成数据的YCSB程序与数据库运行在同一物理环境。
注:如使用独立服务器进行YCSB的数据生成,会导致千兆网瓶颈。
整个集群的拓扑结构如图1所示:
图1:测试集群拓扑
服务器环境。本测试数据库服务器使用4台Dell R520物理机环境,每台物理机配置如下:
Intel(R)Xeon&CPUE5-24201.9GHZ(6core)
6块内置SATA硬盘,2TB/块
千兆以太网
RedHatEnterpriseLinuxServerrelease6.4
kernel-release:2.6.32-358.e16.x86_64
OracleJDK1.6
4. 测试方法
本测试使用YCSB标准,基于四台物理机执行。对于每种不同产品的测试流程如下:
基于四节点部署集群,配置时尽可能基于以下准则:
高可用配置
最终一致性
功能与单节点环境保持一致
充分利用硬件资源
在四台物理机中部署YCSB集群,向本地集群写入读取数据
进行数据操作时通过YCSB产生记录的统计数量
根据结果生成Excel文件
针对其他场景重复以上步骤
并发性方面则基于以下规则:
单条记录插入每服务器24条线程
批量记录插入每服务器8条线程
其他所有操作每服务器36条线程
一、 场景1:单条记录导入
图2:单条记录导入场景
在单条记录导入场景中,SequoiaDB与MongoDB使用insert方法,writeConcern设置为Normal;HBase则设置客户端缓冲区为2KB。而在错误检验方式上,由于是单条记录插入,所以MongoDB必须在每次操作后检测返回值是否成功,因此不可以使用异步插入方式。
在图2的结果中可以看到,单条记录导入操作SequoiaDB最高,总吞吐量可以达到每秒钟近7万。而HBase与Cassandra则比较接近,在5-6万之间。MongoDB在该场景中表现较差,总吞吐量不到每秒1万。
在该场景中,YCSB在4台服务器上各启动24条线程,总共并发量为96线程。
二、 场景2:批量记录导入
图3:批量记录导入场景
批量记录导入场景的结果见图3。在该场景中,SequoiaDB与MongoDB使用各自提供的bulk insert方法;HBase则设置client buffer为4MB;Cassandra不提供批量数据导入方式。
在该测试中,批量导入数据为每批次3000条记录,每节点启动8条线程,总数32线程。
测试结果显示,SequoiaDB可以达到每秒钟近19万的导入速度,而MongoDB则与单线程导入的性能接近(1万左右),HBase也没有本质提升。
三、 场景3:单纯查询
图4:单纯查询场景
图4显示单纯随机查询的场景。在该场景中MongoDB表现最为突出,整体吞吐量达到每秒钟8万以上。SequoiaDB和Cassandra类似,大约为MongoDB的一半,在4万至5万之间徘徊。而HBase表现最差,未达到每秒1万的指标。
该场景每台物理服务器使用36条客户端线程,总数144条线程。
四、 场景4:查询导入平衡
图5:查询导入平衡场景
该场景主要模拟50%的插入和50%的查询业务(图5)。其中插入业务使用单条记录插入。
最终的结果显示,SequoiaDB的整体表现最优,平均达到每秒钟超过14000TPS,而MongoDB/HBase/Cassandra则比较接近,各自不到10000TPS。
五、 场景5:更新为主
图6:更新为主场景
如图6所示,更新为主场景模拟95%更新与5%查询的场景。该场景中,SequoiaDB表现最优,结果介于5万到6万之间每秒。
而MongoDB表现相对较弱,大约在5千每秒左右的数量级。
六、 场景6:查询为主
图7:查询为主场景
在查询为主的场景中,模拟95%查询+5%更新。在该测试中,SequoiaDB与Cassandra的性能接近单纯查询的场景,而更新操作对MongoDB的损耗相对较大,使其性能仅不到3万每秒。
HBase在随机读为主的场景下相对较慢。
七、 场景7:查询最新
图8:查询最新场景
查询最新场景为95%读+5%插入,并且读取的数据尽可能是刚刚写入的数据。
从图8中可以看出,SequoiaDB对于刚刚写入至内存中便读取的场景性能最佳,达到近4万每秒。
而MongoDB和Cassandra则相比场景6有明显下降,HBase依然性能较低。
从第三部分的各个场景对比中可以看出,SequoiaDB数据库在数据插入场景中表现最为突出,甚至超过本身以插入性能著称的Cassandra,混合读写场景下性能也可圈可点。而业界普及率最高的MongoDB则在单纯读取性能上最为抢眼,远超其他。
HBase与Cassandra虽然在写入性能上远高于MongoDB,但是和SequoiaDB相比仍然逊色一筹;而在主键随机读操作方面,Cassandra的新版本和之前的版本比起来性能大幅度上升,基本做到和MongoDB处于同一水平线,而HBase则远不能和其他产品相比。
当然,这些比较也仅仅局限于YCSB所做的测试,而文档类数据库能够提供的二级索引等机制并非是YCSB所测试的。因此,文档类数据库能够提供比宽表类数据库更多的应用场景。
如此看来,对于宽表类数据库来说,如果在其最有优势的主场都败给了文档类数据库,这是否意味着,HBase和Cassandra最大的优势已经不再,文档类数据库会在各个领域的性能表现超越宽表呢?
附录A:配置信息
1. MongoDB
MongoDB的分片分布如图9,不同颜色代表不同的分片,我们采用的是多个副本的分片
MongoDB的部署脚本如下(deploy.sh):
#!/bin/bash
sshperftest-1&mongod--configsvr--logpath/data/disk1/mongodb-cfg/configsvr.log--dbpath/data/disk1/mongodb-cfg/--port37019--journal--fork&
sshperftest-2&mongod--configsvr--logpath/data/disk1/mongodb-cfg/configsvr.log--dbpath/data/disk1/mongodb-cfg/--port37019--journal--fork&
sshperftest-3&mongod--configsvr--logpath/data/disk1/mongodb-cfg/configsvr.log--dbpath/data/disk1/mongodb-cfg/--port37019--journal--fork&
sshperftest-1&mongos--configdbperftest-0:37019,perftest-1:37019,perftest-2:37019--logpath/data/disk1/mongodb-data/mongos.log--fork&
sshperftest-2&mongos--configdbperftest-0:37019,perftest-1:37019,perftest-2:37019--logpath/data/disk1/mongodb-data/mongos.log--fork&
sshperftest-3&mongos--configdbperftest-0:37019,perftest-1:37019,perftest-2:37019--logpath/data/disk1/mongodb-data/mongos.log--fork&
sshperftest-4&mongos--configdbperftest-0:37019,perftest-1:37019,perftest-2:37019--logpath/data/disk1/mongodb-data/mongos.log--fork&
hosts=(&perftest-1&&perftest-2&&perftest-3&&perftest-4&)
disknos=(1111)
port=37017
for((i=0;i&8;++i))
for((j=0;j&3;++j))
ssh${hosts[$hostno]}&mongod--replSetdg$i--logpath/data/disk${disknos[$hostno]}/mongodb-data/mongd.log--dbpath/data/disk${disknos[$hostno]}/mongodb-data/--logappend--quiet--port$port--fork&
letdisknos[$hostno]=${disknos[$hostno]}+1
lethostno=hostno+1
if[$hostno-eq${#hosts[@]}];then
lethostno=0
letport=port+10
MongoDB的分片添加脚本如下(addshard.js):
varport=37017
varhosts=[&perftest-1&,&perftest-2&,&perftest-3&,&perftest-4&];
varhostid=0;
for(i=0;i&8;++i)
varconf=newObject();
conf._id='dg'+i;
conf.members=newArray();
for(j=0;j&3;++j)
varmember=newObject();
member._id=j;
member.host=hosts[hostid]+&:&+
conf.members[j]=
hostid=hostid+1;
if(hostid==hosts.length)
vardb=connect(conf.members[0].host+&/test&);
rs.initiate(conf);
rs.conf();
port=port+10
vardb2=connect(conf.members[0].host+'/test');
sh.addShard('dg'+i+'/'+conf.members[0].host)
MongoDB的集合创建脚本如下(createcl.sh):
mongo&&EOF
sh.stopBalancer();
db.dropDatabase();
db.runCommand({enableSharding:&ycsb&});
db.runCommand({shardcollection:&ycsb.usertable&,key:{_id:'hashed'},numInitialChunks:4096});
所有的writeConcern都为normal。
2. SequoiaDB
SequoiaDB的数据组分布情况如图10,其中不同颜色代表不同的分片。
SequoiaDB的部署脚本如下(deploy.js):
vardb=newSdb();
db.createCataRG('perftest-1',11820,'/opt/sequoiadb/database/cata/11820');
db.getRG(1).createNode('perftest-2',11820,'/opt/sequoiadb/database/cata/11820');
db.getRG(1).createNode('perftest-3',11820,'/opt/sequoiadb/database/cata/11820');
db.getRG(1).getNode('perftest-2',11820).start();
db.getRG(1).getNode('perftest-3',11820).start();
//groupnumberis8
varport=11830;
varhostid=0;
vardiskno=1;
vardiskids=[1,1,1,1];
for(i=0;i&8;++i)
db.createRG('dg'+i);
//3nodesofpergroup
for(j=0;j&3;++j)
db.getRG('dg'+i).createNode('perftest-'+(hostid+1),port,'/data/disk'+diskids[hostid]+'/sequoiadb/database/data'+port);
diskids[hostid]+=1;
hostid+=1;
if(hostid&3)
db.getRG('dg'+i).start();
创建分区集合的脚本如下(createcl.js):
vardb=newSdb()
db.dropCS('ycsb')
if(e!=-34)
throw&dropcsfailure&+e;
db.createCS('ycsb')
db.ycsb.createCL('usertable',{ShardingType:'hash',ShardingKey:{_id:1},EnsureShardingIndex:false})
varsnapshot8=db.snapshot(8,{Name:'ycsb.usertable'}).toArray();
varobj=eval(&(&+snapshot8[0]+&)&);
varsrcgroup=obj[&CataInfo&][0][&GroupName&];
varpartition=obj[&Partition&];
vargroupnames=newArray()
vargroups=db.list(7).toArray();
for(i=0;i&groups.++i)
vargroup=eval(&(&+groups[i]+&)&);
if(group[&GroupName&]==&SYSCatalogGroup&)
groupnames.push(group[&GroupName&]);
varremainderpart=partition%groupnames.
varpart=(partition-remainderpart)/groupnames.length
for(i=0;i&groupnames.++i)
if(groupnames[i]==srcgroup)
println(&splitingfrom&+srcgroup+&to&+groupnames[i]+&........&);
db.ycsb.usertable.split(srcgroup,groupnames[i],{Partition:(i*part)},{Partition:(i+1)*part});
if(remainderpart&1)
db.ycsb.usertable.split(srcgroup,groupnames[i],{Partition:endpart},{Partition:(endpart+1)})
endpart+=1;
remainderpart-=1;
HBase的数据分布情况如图11:
图11:HBase部署架构图
创始表语句使用:
create 'usertable', 'cf', {SPLITS =& ['user1', 'user2', 'user3', 'user4', 'user5', 'user6', 'user7', 'user8', 'user9' ]}
5.4Cassandra
图12是一个Cassandra四节点集群。我们采用使用二十四块硬盘同时处理数据和提交日志。
图12:Cassandra部署架构图
与测试的其他数据库不同,Cassandra 在配置中使用环形拓扑,节点需要被明确地视为&种子&节点(这有助于它们加入到环中)。在配置时,必须指定哪些令牌将映射到哪些实例。
我们使用了提供的令牌生成工具来创建节点配置。
$./tokentoolv2.py4
Cassandra 的一致性级别可以调节。每次读取和写入都可以明确地说明该操作需要什么级别的数据库一致性。由于这是一个基准测试项目,因此我们使用了最弱和最快的一致性级别(ONE)来进行读取和写入。
对于所有数据库,我们使用的复制因子都是 2。其他主要设置为:
RandomPartitioner
初始令牌空间
内存表空间
SnappyCompressor
提交日志同步
以下内容为 conf/cassandra.yaml 的设置:
cluster_name:'Test'
initial_token:0
hinted_handoff_enabled:true
max_hint_window_in_ms:3600000#onehour
hinted_handoff_throttle_delay_in_ms:1
authenticator:org.apache.cassandra.auth.AllowAllAuthenticator
authority:org.apache.cassandra.auth.AllowAllAuthority
partitioner:org.apache.cassandra.dht.RandomPartitioner
data_file_directories:
-/data/disk1/cassandra-data
-/data/disk2/cassandra-data
-/data/disk3/cassandra-data
-/data/disk4/cassandra-data
-/data/disk5/cassandra-data
-/data/disk6/cassandra-data
commitlog_directory:
/data/disk1/cassandra-log/,/data/disk2/cassandra-log/,/data/disk3/cassandra-log/,/data/disk4/cassandra-log/
,/data/disk5/cassandra-log/,/data/disk6/cassandra-log/
saved_caches_directory:/data/disk1/apache-cassandra/saved_caches
commitlog_sync:periodic
commitlog_sync_period_in_ms:10000
seed_provider:
-class_name:org.apache.cassandra.locator.SimpleSeedProvider
parameters:
-seeds:&192.168.30.62,192.168.30.64,192.168.30.65,192.168.30.67&
flush_largest_memtables_at:0.75
reduce_cache_sizes_at:0.85
reduce_cache_capacity_to:0.6
concurrent_reads:48
concurrent_writes:48
memtable_flush_queue_size:4
sliced_buffer_size_in_kb:64
storage_port:7000
ssl_storage_port:7001
listen_address:192.168.30.62
rpc_address:0.0.0.0
rpc_port:9160
rpc_keepalive:true
rpc_server_type:sync
thrift_framed_transport_size_in_mb:15
thrift_max_message_length_in_mb:16
incremental_backups:false
snapshot_before_compaction:false
column_index_size_in_kb:64
in_memory_compaction_limit_in_mb:64
multithreaded_compaction:false
compaction_throughput_mb_per_sec:16
compaction_preheat_key_cache:true
rpc_timeout_in_ms:10000
endpoint_snitch:org.apache.cassandra.locator.SimpleSnitch
dynamic_snitch_update_interval_in_ms:100
dynamic_snitch_reset_interval_in_ms:600000
dynamic_snitch_badness_threshold:0.1
request_scheduler:org.apache.cassandra.scheduler.NoScheduler
index_interval:128
encryption_options:
internode_encryption:none
keystore:conf/.keystore
keystore_password:cassandra
truststore:conf/.truststore
truststore_password:cassandra
使用以下命令对数据库进行初始化:
CREATEKEYSPACEusertable
WITHplacement_strategy='org.apache.cassandra.locator.SimpleStrategy'ANDstrategy_options={replication_factor:2};
CREATECOLUMNFAMILYdataWITHcomparator=UTF8Type
ANDkey_validation_class=UTF8Type
附录B:YCSB调整
一、 驱动调整
1. MongoDB
默认没有采用连接池的形式实现,调整为连接池形式
默认不支持批量插入,增加支持批量插入
默认不支持选择查询接口,增加支持选择查询接口
默认不支持选择readpreference,增加支持选择readpreference
为适应2.12.1版本的driver作了些调整
详细调整如下:
voidinit()
Propertiesprops=getProperties();
Stringurl=props.getProperty(&mongodb.url&,
&mongodb://localhost:27017&);
database=props.getProperty(&mongodb.database&,&ycsb&);
StringwriteConcernType=props.getProperty(&mongodb.writeConcern&,
&safe&).toLowerCase();
//finalStringmaxConnections=props.getProperty(
//&mongodb.maxconnections&,&100&);
insertmode=props.getProperty(&mongodb.insertmode&,&single&);
readpreference=props.getProperty(&mongodb.readpreference&,
&primary&);
bulknumber=Integer.parseInt(props.getProperty(&mongodb.bulknumber&,
finalStringfind=props.getProperty(&mongodb.usefindinterface&,
if(replWriteNum!=1){
writeConcern=newWriteConcern(replWriteNum);
//stripoutprefixsinceJavadriverdoesn'tcurrentlysupport
//standardconnectionformatURLyet
//&ahref=&http://www.mongodb.org/display/DOCS/Connections&&http://www.mongodb.org/display/DOCS/Connections&/a&
/*if(url.startsWith(&mongodb://&)){
url=url.substring(10);
//needtoappenddbtourl.
System.out.println(&newdatabaseurl=&+url);
MongoClientURIuri=newMongoClientURI(url);
mongo=newMongoClient(uri);
mongo.setReadPreference(ReadPreference.valueOf(readpreference));
mongo.setWriteConcern(writeConcern);
System.out.println(&mongoconnectioncreatedwith&+url);
catch(Exceptione1){
System.err
.println(&CouldnotinitializeMongoDBconnectionpoolforLoader:&
+e1.toString());
e1.printStackTrace();
publicintinsert(Stringtable,Stringkey,
HashMap&String,ByteIterator&values){
com.mongodb.DBdb=
db=mongo.getDB(database);
if(!outputclientflag){
mand(&buildInfo&);
if(commandResult.containsField(&tokumxVersion&)){
System.out.println(&tokumx&);
System.out.println(&mongodb&);
outputclientflag=
db.requestStart();
DBCollectioncollection=db.getCollection(table);
DBObjectr=newBasicDBObject().append(&_id&,key);
for(Stringk:values.keySet()){
r.put(k,values.get(k).toArray());
//WriteResultres=
if(insertmode.equals(&bulk&)){
objs.add(r);
//bulkwrite.insert(r);
if(objs.size()==bulknumber){
collection.insert(objs);
objs.clear();
//return0;
collection.insert(r);
//returnres.getN()==replWriteNum?0:1;
catch(Exceptione){
e.printStackTrace();
if(db!=null){
db.requestDone();
publicintread(Stringtable,Stringkey,Set&String&fields,
HashMap&String,ByteIterator&result){
com.mongodb.DBdb=
DBCursorcursor=
db=mongo.getDB(database);
db.requestStart();
//getCollection(table);
DBCollectioncollection=db.getCollection(table);
DBObjectq=newBasicDBObject().append(&_id&,key);
DBObjectfieldsToReturn=newBasicDBObject();
DBObjectqueryResult=
//DBCursorcursor=
if(fields!=null){
Iterator&String&iter=fields.iterator();
while(iter.hasNext()){
fieldsToReturn.put(iter.next(),INCLUDE);
if(findone){
queryResult=collection.findOne(q,fieldsToReturn);
cursor=collection.find(q,fieldsToReturn);
if(findone){
queryResult=collection.findOne(q);
cursor=collection.find(q).setReadPreference(ReadPreference.secondaryPreferred());
if(cursor!=null&&cursor.hasNext()){
queryResult=cursor.next();
if(queryResult!=null){
result.putAll(queryResult.toMap());
returnqueryResult!=null?0:1;
catch(Exceptione){
System.err.println(e.toString());
if(db!=null){
db.requestDone();
if(cursor!=null){
cursor.close();
支持通过参数控制WriteBufferSize
适应驱动做微调
详细如下:
publicvoidinit()throwsDBException
if((getProperties().getProperty(&debug&)!=null)&&
(getProperties().getProperty(&debug&).compareTo(&true&)==0))
_columnFamily=getProperties().getProperty(&columnfamily&);
if(_columnFamily==null)
System.err.println(&Error,mustspecifyacolumnfamilyforHBasetable&);
thrownewDBException(&Nocolumnfamilyspecified&);
_columnFamilyBytes=Bytes.toBytes(_columnFamily);
clientbufsize=Integer.parseInt(getProperties().getProperty(&clientbuffersize&));
publicvoidgetHTable(Stringtable)throwsIOException
synchronized(tableLock){
_hTable=newHTable(config,table);
//2suggestionsfrom&ahref=&/2009/01/performance-of-hbase-importing.html&&/2009/01/performance-of-hbase-importing.html&/a&
_hTable.setAutoFlush(false);
_hTable.setWriteBufferSize(clientbufsize*1024);
//returnhT
二、 统计数据收集
从原有的Measurements派生出ExcelMeasurementsExporter用于将生成的统计数据导出到excel文件中,ExcelMeasurementsExporter调用jxl.jar开源库实现。
统计数据由Overalloperresult、Overallresult,Periodresult这几个类存储,为了保存统计数据原来的Measurements,StatusThread都相应作了些调整。
增加如下xml配置文件
&?xmlversion=&1.0&encoding=&utf-8&?&
&transactionname=&bulkload_concurrent&/&
&!--transactionname=&bulkload&/--&
&transactionname=&singleload_concurrent&/&
&!--transactionname=&singleload&/--&
&transactionname=&readonly_concurrent&/&
&transactionname=&readheavy_concurrent&/&
&transactionname=&updateheavy_concurrent&/&
&transactionname=&insertheavy_concurrent&/&
&transactionname=&readlastest_concurrent&/&
我们增加了如下python脚本用于连续运行:
#!/usr/bin/python
#!/bin/envpython
importsubprocess
fromxml.etreeimportElementTree
importycsb
fromycsbimport(DATABASES,COMMANDS,BASE_URL,
get_ycsb_home,find_jars)
defgetloadtrans(workloadpath,root):
lst_node=root.find(&load&)
fornodeinlst_node:
load.append(workloadpath+node.attrib['name'])
returnload
defgetruntrans(workloadpath,root):
lst_node=root.find(&run&)
fornodeinlst_node:
run.append(workloadpath+node.attrib['name'])
defushelp():
print&Usage:%sdatabase&%sys.argv[0]
print&nDatabases:&
fordbinsorted(DATABASES.keys()):
print&%s%s&%(db.ljust(13),BASE_URL+db.split(&-&)[0])
sys.exit(1)
defrunscene(trans,cmd,db_classname,pervscene):
curscene=&&
foritemintrans:
curscene=os.path.basename(item)
command=COMMANDS[cmd][&command&]
options=[&-s&,&-P&,item]
ycsb_command=[&java&,&-cp&,&:&.join(find_jars(ycsb_home,database)),
COMMANDS[cmd][&main&],&-db&,db_classname]+options
ifcommand:
ycsb_command.append(command)
#print&&.join(ycsb_command)
subprocess.call(ycsb_command)
pervscene=curscene
returnpervscene
iflen(sys.argv)&2:
ifsys.argv[1]notinDATABASES:
print&ERROR:Database'%s'notfound&%sys.argv[1]
os.chdir('..')
conffile=os.getcwd()+&/conf/workload.xml&
resultfile=os.getcwd()+&/result/report_output.xls&
resultdir=os.getcwd()+&/result/&
workloadsdir=os.getcwd()+&/workloads/&
ifFalse==os.path.exists(conffile):
printconffile+&notexist&;
sys.exit(1)
root=ElementTree.parse(conffile)
loadtrans=getloadtrans(workloadsdir,root)
runtrans=getruntrans(workloadsdir,root)
os.chdir('bin')
ycsb_home=get_ycsb_home()
database=sys.argv[1]
db_classname=DATABASES[database]
runscene(loadtrans,&load&,db_classname,pervscene)
runscene(runtrans,&run&,db_classname,pervscene)
importtime
curtime=time.strftime(&%Y-%m-%d_%H_%M_%S&,time.localtime(time.time()))
newreportfile=resultdir+&report_&+curtime+&.xls&
os.rename(resultfile,newreportfile)
为尽量保证后续的查询、更新操作是基于前续的load操作,以保证缓存的高命中率。
四、 数据类型
本次测试的数据皆为字符串类型:
fieldcount=10
fieldlength=10
key字段由单词&user&后面加上64位的Fowler-Noll-Vo哈希值构成
key大小为23字节
所有字段的值采用zipfian算法生成
附录C:SequoiaDB接口
packagecom.yahoo.ycsb.
importcom.yahoo.ycsb.ByteArrayByteI
importcom.yahoo.ycsb.ByteI
importcom.yahoo.ycsb.DB;
importcom.yahoo.ycsb.DBE
importjava.util.ArrayL
importjava.util.HashM
importjava.util.I
importjava.util.M
importjava.util.P
importjava.util.S
importjava.util.V
importjava.util.L
importjava.util.concurrent.atomic.AtomicI
importorg.bson.BSONO
importorg.bson.BasicBSONO
importorg.bson.types.BasicBSONL
importcom.sequoiadb.base.SequoiadbO
importcom.sequoiadb.base.SequoiadbD
importcom.sequoiadb.base.CollectionS
importcom.sequoiadb.base.DBC
importcom.sequoiadb.base.DBC
importcom.sequoiadb.base.S
publicclassSequoiaDBClientextendsDB{
/**Usedtoincludeafieldinaresponse.*/
protectedstaticfinalIntegerINCLUDE=Integer.valueOf(1);
/**Thekeyfieldname*/
//privatestaticfinalStringKEY_FILED=&key&;
privatestaticfinalStringKEY_FILED=&_id&;
privatestaticfinalStringDEFAULT_INSERTMODE=&single&;
*Countthenumberoftimesinitializedtoteardownonthelast
*{@link#cleanup()}.
privatestaticfinalAtomicIntegerinitCount=newAtomicInteger(0);
privatestaticintbulknum=0;
/**Sequoiadbinstance.*/
privatestaticSequoiadbDatasourcesdbpools=
privateSequoiadbsdb=
/**CollectionSpaceinstance.*/
privateCollectionSpacecs=
privateDBCollectioncl=
privatestaticStringkeyfield=
privatestaticStringinsertmode=
privateList&BSONObject&objs=newArrayList&BSONObject&();
//privateintcallnumber=0;
privatestaticStringspacename=&ycsb&;
//privateDBCollectioncollection=
*InitializeanystateforthisDB.CalledonceperDBthereis
*oneDBinstanceperclientthread.
publicvoidinit()throwsDBException{
initCount.incrementAndGet();
synchronized(INCLUDE){
if(sdb!=null){
if(sdbpools!=null){
sdb=sdbpools.getConnection();
cs=sdb.getCollectionSpace(spacename);
}catch(Exceptione){
e.printStackTrace();
//initializesequoiadbdriver
Propertiesprops=getProperties();
Stringhost=props.getProperty(&sequoiadb.host&,&localhost&);
Stringport=props.getProperty(&sequoiadb.port&,&11810&);
keyfield=props.getProperty(&sequoiadb.keyfield&,&_id&);
intmaxConnectionnum=Integer.parseInt(props.getProperty(&sequoiadb.maxConnectionnum&,&100&));
intmaxidleconnnum=Integer.parseInt(props.getProperty(&sequoiadb.maxConnectionnum&,&10&));
intperiod=Integer.parseInt(props.getProperty(&sequoiadb.maxConnectionnum&,&300&));
spacename=props.getProperty(&sequoiadb.space&,spacename);
insertmode=props.getProperty(&sequoiadb.insertmode&,DEFAULT_INSERTMODE);
bulknum=Integer.parseInt(props.getProperty(&sequoiadb.bulknumber&,&5000&));
SequoiadbOptionsdbOption=newSequoiadbOption();
sdbOption.setMaxConnectionNum(maxConnectionnum);
sdbOption.setMaxIdeNum(maxidleconnnum);
sdbOption.setRecheckCyclePeriod(period*1000);
sdbpools=newSequoiadbDatasource(host+&:&+port,&&,&&,sdbOption);
//needtoappenddbtourl.
//sdb=newSequoiadb(host,Integer.parseInt(port),&&,&&);
sdb=sdbpools.getConnection();
if(!sdb.isCollectionSpaceExist(spacename)){
cs=sdb.createCollectionSpace(spacename);
cs=sdb.getCollectionSpace(spacename);
System.out.println(&sequoiadbconnectioncreatedwith&+host
+&:&+port);
}catch(Exceptione1){
System.err
.println(&CouldnotinitializeSequoiadbconnectionpoolforLoader:&
+e1.toString());
e1.printStackTrace();
thrownewDBException(e1.toString());
*CleanupanystateforthisDB.CalledonceperDBthereisone
*DBinstanceperclientthread.
publicvoidcleanup()throwsDBException{
initCount.decrementAndGet();
if(0!=objs.size()){
cl.bulkInsert(objs,DBCollection.FLG_INSERT_CONTONDUP);
sdbpools.close(sdb);
}catch(Exceptione1){
System.err.println(&CouldnotcloseSequoiadbconnectionpool:&
+e1.toString());
e1.printStackTrace();
privateList&String&getAllDataGroup(){
//获取数据组的数量
List&String&groups=newArrayList&String&();
DBCursorcursor=sdb.getList(Sequoiadb.SDB_LIST_GROUPS,null,null,null);
while(cursor.hasNext()){
BSONObjectobj=cursor.getNext();
Stringgroupname=(String)obj.get(&GroupName&);
if(!groupname.equals(&SYSCatalogGroup&)){
groups.add(groupname);
privateintgetPartition(Stringspacename,Stringtablename){
//获取源数据组
BSONObjectcondition=newBasicBSONObject();
condition.put(&Name&,spacename+&.&+tablename);
DBCursorcr=sdb.getSnapshot(Sequoiadb.SDB_SNAP_CATALOG,condition,null,null);
intPartition=0;
while(cr.hasNext()){
BSONObjectobj=cr.getNext();
Partition=((Integer)obj.get(&Partition&)).intValue();
privateStringgetSrcDataGroup(Stringspacename,Stringtablename){
//获取源数据组
BSONObjectcondition=newBasicBSONObject();
condition.put(&Name&,spacename+&.&+tablename);
DBCursorcr=sdb.getSnapshot(Sequoiadb.SDB_SNAP_CATALOG,condition,null,null);
Stringsrcgroup=&&;
while(cr.hasNext()){
BSONObjectobj=cr.getNext();
BasicBSONListcatainfo=(BasicBSONList)obj.get(&CataInfo&);
srcgroup=(String)((BSONObject)catainfo.get(0)).get(&GroupName&);
privatevoidsplitCollection(DBCollectioncl,Stringspacename,Stringtablename){
//获取数据组的数量
List&String&groups=getAllDataGroup();
intPartition=getPartition(spacename,tablename);
Stringsrcgroup=getSrcDataGroup(spacename,tablename);
intpart=Partition/groups.size();
intremainder=Partition%groups.size();
intstartpart=Partition-
for(inti=0;i&groups.size();++i){
BSONObjectstart=newBasicBSONObject();
start.put(&Partition&,i*part);
BSONObjectend=newBasicBSONObject();
end.put(&Partition&,(i+1)*part);
if(!groups.get(i).equals(srcgroup)){
cl.split(srcgroup,groups.get(i),start,end);
if(0!=remainder){
BSONObjectremainderstart=newBasicBSONObject();
remainderstart.put(&Partition&,startpart);
BSONObjectremainderend=newBasicBSONObject();
remainderend.put(&Partition&,startpart+1);
cl.split(srcgroup,groups.get(i),remainderstart,remainderend);
privatevoidcreateCollection(Stringtable)throwsDBException{
BSONObjectoptions=newBasicBSONObject();
BSONObjectsubobj=newBasicBSONObject();
subobj.put(KEY_FILED,1);
options.put(&ShardingKey&,subobj);
options.put(&ShardingType&,&hash&);
options.put(&EnsureShardingIndex&,false);
cl=cs.createCollection(table,options);
splitCollection(cl,spacename,table);
if(0!=pareTo(&_id&)){
cl.createIndex(&index&,
&{&+keyfield+&:1}&,true,true);
privateDBCollectiongetCollection(Stringtable){
if(sdb==null){
sdb=sdbpools.getConnection();
}catch(Exceptione)
e.printStackTrace();
if(cs==null){
cs=sdb.getCollectionSpace(spacename);
}catch(Exceptione)
e.printStackTrace();
if(cl==null){
booleanbExist=cs.isCollectionExist(table);
if(!bExist){
synchronized(INCLUDE){
if(cs.isCollectionExist(table)){
cl=cs.getCollection(table);
createCollection(table);
cl=cs.getCollection(table);
}catch(Exceptione)
e.printStackTrace();
sdbpools.close(sdb);
returngetCollection(table);
publicintread(Stringtable,Stringkey,Set&String&fields,
HashMap&String,ByteIterator&result){
DBCursorcursor=
DBCollectioncollection=
collection=getCollection(table);
if(collection==null){
System.out.println(&Failedtogetcollection&+table);
BSONObjectquery=newBasicBSONObject().append(keyfield,key);
BSONObjectfieldsToReturn=
if(fields!=null){
fieldsToReturn=newBasicBSONObject();
Iterator&String&iter=fields.iterator();
while(iter.hasNext()){
fieldsToReturn.put(iter.next(),&&);
cursor=collection.query(query,fieldsToReturn,null,null);
if(cursor!=null&&cursor.hasNext()){
HashMap&String,ByteIterator&resultMap=newHashMap&String,ByteIterator&();
fillMap(resultMap,cursor.getNext());
result.putAll(resultMap);
}catch(Exceptione){
System.err.println(e.toString());
e.printStackTrace();
if(cursor!=null){
cursor.close();
*TODO-Finish
*@paramresultMap
*@paramobj
@SuppressWarnings(&unchecked&)
protectedvoidfillMap(HashMap&String,ByteIterator&resultMap,
BSONObjectobj){
Map&String,Object&objMap=obj.toMap();
for(Map.Entry&String,Object&entry:objMap.entrySet()){
if(entry.getValue()instanceofbyte[]){
resultMap.put(entry.getKey(),newByteArrayByteIterator(
(byte[])entry.getValue()));
publicintscan(Stringtable,Stringstartkey,intrecordcount,
Set&String&fields,Vector&HashMap&String,ByteIterator&&result){
DBCursorcursor=
DBCollectioncollection=getCollection(table);
BSONObjectscanRange=newBasicBSONObject().append(&$gte&,
startkey);
BSONObjectquery=newBasicBSONObject().append(keyfield,
scanRange);
BSONObjectfieldsToReturn=
if(fields!=null){
fieldsToReturn=newBasicBSONObject();
Iterator&String&iter=fields.iterator();
while(iter.hasNext()){
fieldsToReturn.put(iter.next(),&&);
cursor=collection.query(query,fieldsToReturn,null,null,0,
recordcount);
while(cursor.hasNext()){
//toMap()returnsaMap,butresult.add()expectsa
//Map&String,String&.Hence,thesuppresswarnings.
HashMap&String,ByteIterator&resultMap=newHashMap&String,ByteIterator&();
BSONObjectobj=cursor.getNext();
fillMap(resultMap,obj);
result.add(resultMap);
}catch(Exceptione){
System.err.println(e.toString());
e.printStackTrace();
if(cursor!=null){
cursor.close();
publicintupdate(Stringtable,Stringkey,
HashMap&String,ByteIterator&values){
DBCollectioncollection=getCollection(table);
if(collection==null){
System.out.println(&Failedtogetcollection&+table);
BSONObjectquery=newBasicBSONObject().append(keyfield,key);
BSONObjectupdate=newBasicBSONObject();
BSONObjectfieldsToSet=newBasicBSONObject();
Iterator&String&keys=values.keySet().iterator();
while(keys.hasNext()){
StringtmpKey=keys.next();
fieldsToSet.put(tmpKey,values.get(tmpKey).toArray());
update.put(&$set&,fieldsToSet);
collection.update(query,update,null);
}catch(Exceptione){
System.err.println(e.toString());
e.printStackTrace();
publicintinsert(Stringtable,Stringkey,
HashMap&String,ByteIterator&values){
DBCollectioncollection=getCollection(table);
BSONObjectrecord=newBasicBSONObject().append(keyfield,key);
for(Stringk:values.keySet()){
record.put(k,values.get(k).toArray());
if(insertmode.equals(DEFAULT_INSERTMODE)){
collection.insert(record);
if(objs.size()!=bulknum){
objs.add(record);
if(objs.size()==bulknum){
collection.bulkInsert(objs,DBCollection.FLG_INSERT_CONTONDUP);
objs.clear();
}catch(Exceptione){
System.err.println(e.toString());
e.printStackTrace();
publicintdelete(Stringtable,Stringkey){
DBCollectioncollection=getCollection(table);
BSONObjectrecord=newBasicBSONObject().append(keyfield,key);
collection.delete(record);
}catch(Exceptione){
System.err.println(e.toString());
e.printStackTrace();
publicstaticvoidmain(String[]args){
Propertiesprops=newProperties();
props.setProperty(&sequoiadb.host&,&192.168.30.63&);
props.setProperty(&sequoiadb.port&,&11810&);
props.setProperty(&sequoiadb.space&,&test&);
SequoiaDBClientclient=newSequoiaDBClient();
client.setProperties(props);
client.init();
client.getCollection(&usertable&);
}catch(DBExceptione){
e.printStackTrace();
& 相关主题:

我要回帖

更多关于 网站性能测试报告 的文章

 

随机推荐