【IT168 专稿】TimesTen是Oracle公司的数据库产品,其全称为Oracle TimesTen In-Memory Database。TimesTen是一个内存优化的关系数据库(即内存 数据库),它为应用程序提供了即时的响应性和非 常高的吞吐量。 Oracle TimesTen In-Memory Database 可以作为单独的数据库使用,也可以作为高速缓存或嵌入式数据库被部署在应用程序层中,它利用标准的 SQL接口对完全位于物理内存中的数据存储区进行操作。
TimesTen 起源于Hewlett Packard。1992年,由HP 的一个研发小组开发了最早的核心技术,即TimesTen 的实时事件处理系统,目的是为了嵌入到HP 的电信系统中。 1996年TimesTen从HP剥离出来成为独立的公司;并 于2005年6月被Oracle公司收购。
经过Oracle公司几年的整合,现在TimesTen已经与Oracle进行了很好的集成。最显著的特点是TimesTen的Cache Group,能够实现内存数据库TimesTen与传统磁盘数据库Oracle的互联互通。
在TimesTen的最新版本中,Oracle公司又对TimesTen产品在功能上进行Oracle化,加入了许多新的功能。如OCI的支持,Cluster的功能等。
安装配置
安装TimesTen之前,需要先从Oracle官方网站上下载TimesTen的安装包。当前版本安装包是timesten112230.linux8664.tar.gz。
下载完成后,对压缩包进行解压缩:
解压缩后,得到linux8664目录。TimesTen的安装文件就放在这个目录中。
在正式安装之前,需要进行一些准备工作,基本的有以下几个命令:
创建TimesTen工作组:
创建TimsTen工作用户:
对相关目录更改权属:
准备工作完成后,就可以转到之前解压缩后得到的linux8664目录下运行./setup.sh开始安装。根据提示,一步步安装即可。值得一提的是由于TimesTen拥有与Oracle数据库互联互通的Cache Group功能,这个功能需要使用到Oracle数据库的一些配置信息。在进行TimesTen安装时,安装程序会检测安装用户的环境设置,如果配置了Oracle数据库的环境变量,则安装程序会提示Oracle tnsnames.ora所在的位置。如下所示:
file in /u01/app/oracle/product/11.2.0/db_1/network/admin.
Would you like to use this TNS_ADMIN setting for the In-Memory Database Cache? [ yes ]
TNS_ADMIN will be set to /u01/app/oracle/product/11.2.0/db_1/network/admin
You can change TNS_ADMIN later by running <install_dir>/bin/ttmodinstall.
如果没有设置Oracle数据库的环境变量,则需要手动指定TNS_ADIMIN的位置。
${PageNumber}Benchmark测试
·测试环境
本次测试使用的软硬件环境如下:
硬件配置:Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz,4核8线程, 内存8GB。
操作系统: Redhat Enterprise Linux 6.0 X64。
·测试假定
本次测试为充分展示内存数据库的性能,使用TimesTen嵌入式方式,并使用OCI接口完成测试。
·数据结构
插入测试
1. 单线程
首先进行单线程的插入测试,向数据库中插入10000000条记录,性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 10000000 | 115909 |
每条记录所花费的时间(微秒) | 11.5909 | |
每秒吞吐率(object/s) | 86274.57747 |
单线程插入10000000条记录的耗时为116秒,每条记录的花费时间为11.6微秒,每秒处理的记录数为8.6万。
2. 四线程
之后我们增加线程数为4.
四个线程同时插入10000000条记录,性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 2500000 | 48040 |
2 | 2500000 | 48126 |
3 | 2500000 | 48575 |
4 | 2500000 | 48908 |
插入10000000条记录所花费的总时间(秒) | 48.41225 | |
每条记录所花费的时间(微秒) | 4.841225 | |
每秒吞吐率(object/s) | 206559.2903 |
四个线程插入10000000条记录的总耗时为48.4秒,平均每条记录耗时4.8微秒,每秒处理20.6万条数据。
3. 八线程
最后将线程数增加到八个线程,向数据库中添加10000000条记录,每个线程的性能和总体性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 1250000 | 47120 |
2 | 1250000 | 48447 |
3 | 1250000 | 48501 |
4 | 1250000 | 48551 |
5 | 1250000 | 48643 |
6 | 1250000 | 48850 |
7 | 1250000 | 48914 |
8 | 1250000 | 48953 |
插入10000000条记录所花费的总时间(秒) | 48.497375 | |
每条记录所花费的时间(微秒) | 4.8497375 | |
每秒吞吐率(object/s) | 206196.7271 |
可以看到8个并发写入10000000条记录所花费的时间大概为48.5秒,平均每秒可以添加20.6万条记录。
4. 总结
插入操作的总体吞吐率:
可以看到,插入操作的性能,四线程和8线程的吞吐率相差不大。
${PageNumber}更新测试
1. 单线程
首先进行单线程的更新测试,在数据库中进行10000000次更新,每次更新一条记录的所有字段,性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 10000000 | 133284 |
每条记录所花费的时间(微秒) | 13.3284 | |
每秒吞吐率(object/s) | 75027.7603 |
单线程更新10000000条记录的耗时为133秒,每条记录的更新花费时间为13.3微秒,每秒处理的记录数为7.5万。
2. 四线程
之后我们增加线程数为4.
四个线程同时更新10000000条记录,性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 2500000 | 57785 |
2 | 2500000 | 57967 |
3 | 2500000 | 58087 |
4 | 2500000 | 58536 |
插入10000000条记录所花费的总时间(秒) | 58.09375 | |
每条记录所花费的时间(微秒) | 5.809375 | |
每秒吞吐率(object/s) | 172135.557 |
四个线程更新10000000条记录的总耗时为58秒,平均每条记录耗时5.8微秒,每秒处理17万条数据。
3. 八线程
更新测试是通过八个线程,同时更新数据库中记录,共10000000次操作,每个线程的性能和总体性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 1250000 | 60464 |
2 | 1250000 | 60821 |
3 | 1250000 | 62649 |
4 | 1250000 | 62687 |
5 | 1250000 | 63018 |
6 | 1250000 | 63024 |
7 | 1250000 | 63116 |
8 | 1250000 | 63365 |
更新10000000条记录的耗时(秒) | 62.393 | |
更新每条记录所的耗时(微秒) | 6.2393 | |
每秒吞吐率(object/s) | 160274.39 |
可以看到8个并发同时更新10000000条记录所花费的时间大概为62.4秒,平均每秒可以更新16万条记录。此处的更新为涉及到了每条记录的每个字段。
4. 总结
更新操作的总体吞吐率:
可以看到,更新操作的性能,四线程并发操作时,吞吐率最大。
${PageNumber}查询测试
1. 单线程
首先进行单线程的查询测试,在数据库中进行10000000次查找,性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 10000000 | 31718 |
每条记录所花费的时间(微秒) | 3.1718 | |
每秒吞吐率(object/s) | 315278.3908 |
单线程进行10000000次查询的耗时为31秒,每次查询花费时间为3.1微秒,每秒处理的操作数为31.5万。
2. 四线程
之后我们增加线程数为4.
四个线程进行10000000次查找操作,性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 2500000 | 10261 |
2 | 2500000 | 10349 |
3 | 2500000 | 10365 |
4 | 2500000 | 10472 |
插入10000000条记录所花费的总时间(秒) | 10.36175 | |
每条记录所花费的时间(微秒) | 1.036175 | |
每秒吞吐率(object/s) | 965087.9436 |
四个线程进行10000000次查找操作的总耗时为10.3秒,平均每条记录耗时1微秒,每秒处理96.5万次查询操作。
3. 八线程
查询测试是通过八个线程,同时查询数据库中记录,共10000000次查询,每个线程的性能和总体性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 1250000 | 9285 |
2 | 1250000 | 9334 |
3 | 1250000 | 9357 |
4 | 1250000 | 9365 |
5 | 1250000 | 9378 |
6 | 1250000 | 9387 |
7 | 1250000 | 9406 |
8 | 1250000 | 9463 |
查询10000000次的耗时(秒) | 9.371875 | |
每次查询的耗时(微秒) | 0.9371875 | |
每秒吞吐率(object/s) | 1067022.341 |
可以看到8个并发同时查询10000000条记录所花费的时间大概为9.3秒,平均每秒可以进行106万次查询。
4. 总结
查询操作的总体吞吐率:
可以看到,查询操作的性能,8个线程并发操作时,吞吐率最大。
${PageNumber}1:1读写测试
1. 四线程
首先进行四线程的读写测试,其中2个线程做更新操作,另外两个线程做查询操作,持续运行10秒钟,每个线程的性能和总体性能如下:
线程ID | 操作 | 操作次数 |
1 | 查询 | 2439681 |
2 | 查询 | 2420937 |
3 | 更新 | 560398 |
4 | 更新 | 610507 |
每秒查询吞吐率(完成次数/s) | 486061.8 | |
每秒更新吞吐率(完成次数/s) | 117090.5 | |
总吞吐率(完成次数/s) | 603152.3 |
在四个线程进行读写测试时,平均每秒可以进行48.6万次查询,11.7万次更新,总体吞吐率为60.3万。
2. 八线程
读写测试是通过八个线程,其中四个线程持续做更新操作,另外四个线程做查询操作,持续运行10秒中,每个线程的性能和总体性能如下:
线程ID | 操作 | 操作次数 |
1 | 查询 | 1259411 |
2 | 查询 | 1252926 |
3 | 查询 | 1243040 |
4 | 查询 | 1188282 |
5 | 更新 | 317849 |
6 | 更新 | 327630 |
7 | 更新 | 343017 |
8 | 更新 | 349452 |
每秒查询吞吐率(完成次数/s) | 494365.9 | |
每秒更新吞吐率(完成次数/s) | 133794.8 | |
总吞吐率(完成次数/s) | 628160.7 |
可以看到同时进行读写测试时,平均每秒可以进行49万次查询13万次更新,总体吞吐率为62万。
3. 总结
1:1读写操作的总体吞吐率:
可以看到,1:1读写操作的性能,4线程与8线程总体吞吐率相近。
${PageNumber}删除测试
1. 单线程
首先进行单线程的删除测试,在数据库中进行10000000次删除,每次删除一条记录,性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 10000000 | 68516 |
每条记录所花费的时间(微秒) | 6.8516 | |
每秒吞吐率(object/s) | 145951.3 |
单线程进行10000000次删除操作的耗时为68.5秒,每次查询花费时间为6.8微秒,每秒处理的操作数为14.6万。
2. 四线程
之后我们增加线程数为4.
四个线程进行10000000次删除操作,性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 2500000 | 44717 |
2 | 2500000 | 46130 |
3 | 2500000 | 46172 |
4 | 2500000 | 46398 |
插入10000000条记录所花费的总时间(秒) | 45.85425 | |
每条记录所花费的时间(微秒) | 4.585425 | |
每秒吞吐率(object/s) | 218082.3 |
四个线程进行10000000次删除操作的总耗时为45.8秒,平均删除每条记录耗时4.6微秒,每秒处理21.8万次删除操作。
3. 八线程
删除测试是通过八个线程,按照记录ID,同时删除数据库中记录,共10000000个对象,每个线程的性能和总体性能如下:
线程ID | 记录数 | 耗时(毫秒) |
1 | 1250000 | 45547 |
2 | 1250000 | 45872 |
3 | 1250000 | 45878 |
4 | 1250000 | 46217 |
5 | 1250000 | 46388 |
6 | 1250000 | 46483 |
7 | 1250000 | 46560 |
8 | 1250000 | 46783 |
查询10000000次的耗时(秒) | 46.216 | |
每次查询的耗时(微秒) | 4.6216 | |
每秒吞吐率(object/s) | 216375.3 |
可以看到8个并发同时删除10000000条记录所花费的时间大概为46秒,平均每秒可以进行21.6万次删除。
4. 总结
查询操作的总体吞吐率:
可以看到,删除操作的性能,4线程和8线程吞吐率相差不大。
以上测试都是每次操作都为一个事务,每次操作只涉及一条记录。
本文总结:
TimesTen单独使用的情况较少,作为Oracle家族成员,实际使用中它更加经常作为Oracle的一个高速缓存,它们之间的内部通讯接口非常方便:
当Oracle->TimesTen 在Oracle上更新的数据会通过trigger捕获记录下来,再通过cache agent定期获取这些信息同步到TT;TimesTen->Oracle时通过分析TT日志来获得做了哪些DML操作。cache agent再同步到oracle。这些操作都可以自动刷新,并且对系统透明,这样的数据库架构效果、性能和数据保存都有不少方便之处,当然Oracle的价格也不菲也是众所周知,我们后续会介绍到IBM公司的SoliDB和eXtremeDB以及一些开源内存数据库,愿对读者起一定帮助。