声明:本文章转自麻袋爸爸

一,TimesTen应用场景

在谈论TimesTen内存数据库应用场景之前,我们先来介绍一下什么是内存数据库,及其工作原理吧。内存数据库,顾名思义就是将数据存放在内存中,并通过内存操作直接完成数据库相关操作。与磁盘相比,数据在内存中的读写速度要高出几个数量级,能够极大地提高应用程序的性能。同时,内存数据库抛弃了磁盘数据管理的传统方式,基于全部数据都在内存中,重新设计了体系结构,并且在数据缓存、快速算法、并行操作方面也进行了相应的改进,所以数据处理速度比传统数据库的数据处理速度要快很多,一般都在10倍以上,TimesTen也由此而得名。内存数据库从某种角度上来看,也是一种缓存机制,是磁盘数据库的前端缓存,通过物理内存中的数据存储区的直接操作,减少了到磁盘间的 I/O 交互。

说到应用场景,TimesTen内存数据库也不是万能的,不是什么场景都适合使用TimesTen的。在实际工作中,我不只一次地被问及:“如果使用TimesTen,我们的应用程序是不是就能提升性能呢?”我只能说:“TimesTen也是有作用域的,不是什么场景都适合。判断是否适合,我们需要做一次完整的应用POC测试才能判定。”像使用其他工具是一样的,要使用TimesTen内存数据库,需要先了解它的特点。

1. TimesTen 特点

如图6-2所示,对比了Oracle数据库与TimesTen内存数据库在应用程序SQL语句执行到返回的过程,可以看到TimesTen内存数据库具有以下优势:

  • 完全内存存储和内存读写,没有缓冲缓存管理开销;

  • 更短的SQL路径导致更快的性能,更少的CPU指令导致更少的CPU开销。

图6-2 Oracle与TimesTen基础架构对比

从以上对比中,我们可以归总一个结论:TimesTen的数据读写速度快,事务并发处理能力强。但是也需要关注到TimesTen的一些限制。TimesTen在进行架构设计的时候,有以下几个关注点:

  • 拒绝热点争用,高并发的热点争用更易产生CPU问题;

  • 高效I/O要求,TimesTen的数据文件和日志文件均存储在磁盘上,与内存保持同步,如果磁盘I/O不佳会成为性能短板;

  • 单库容量不宜过大,会导致恢复成本高;

  • 字段不宜过长,内存存储比磁盘存储更消耗容量。

换而言之,我们在享受TimesTen内存数据库带来的高性能和高并发优势的同时,需要注意由此而可能出现的问题点。TimesTen的高速也是需要有代价的,是需要建立在优秀架构设计的基础上。与Oracle的厚重的基础架构相比,TimesTen显得有些“单薄”,更像是一个敏捷数据库,在使用过程中,我们应该尽可能地遵守“快进快出”的原则,一些比较厚重的应用并不适合使用TimesTen数据库。

2. 适用场景和注意事项

归总一下,有哪些场景适合使用TimesTen吧:

  • 业务逻辑简单、快速响应的OLTP应用,比如:互联网秒杀活动、网上拍卖、电子计费等;

  • Oracle数据库并发争用压力过大的应用,可以分离到TimesTen上,通过分库分表实现快速响应;

  • 对于一些数据量较大、业务逻辑复杂、数据耦合性非常强的应用,如:MIS、OLAP,将不是TimesTen所擅长处理的。

TimesTen内存数据库的最大优势是解决高并发争用压力,同时在响应时间上作出优化,不是从分钟级到秒级的优化,而是从秒级到毫秒级的优化,这才是其最擅长的。在使用设计上需要注意以下方面:

  • 表、索引结构设计简单,字段长度较短,且尽可能只使用常用字段类型;

  • 函数、存储过程、序列等数据库对象尽量不使用;

  • SQL语句简单(不含复杂的表关联和子查询等),单条语句响应时间尽量能控制在毫秒级;

  • 如果作为Oracle的前置缓存,数据刷新频率不宜过高。

二,Timesten技术架构

1. 应用形式

前面说到,TimesTen可以单独使用,也可以作为Oracle的缓存来使用,这里我们就先来介绍一下TimesTen内存数据库的使用形式,具体如下:

  • TimesTen内存数据库(TimesTen In-Memory Database):其为一个针对内存进行了优化的关系数据库,它为应用程序提供了即时响应性和非常高的吞吐量。TimesTen作为缓存或嵌入式数据库部署在应用程序层中,利用标准的SQL接口对完全位于物理内存中的数据存储进行操作。

  • Oracle数据库缓存(Oracle In-Memory Database Cache):其为一个数据库选件,它与Oracle数据库配合使用,作为Oracle数据库的一个高速缓存,为前端应用提供了实时、可更新的缓存。其将来自数据库的对性能极其关键的一系列表缓存到应用程序层,从而缩短应用程序事务响应时间。

2. 内部架构

知其然需知其所以然,TimesTen的高并发处理优势源自何处呢?我们需要来深入研究一下它的技术架构。

若要求快速的响应,就需要简单高效的架构来作为保障,如图6-3所示,和Oracle数据库一样,TimesTen的架构中也可以分为三个部分:

  • 内存结构:负责与前端应用的数据交互和直接的数据库操作;

  • 后台进程:负责应用、内存结构、文件结构之间的交互,作用就像通讯员一样;

  • 文件结构:与内存的交互,存储数据库到磁盘,并记录相关日志,需要注意的是,和Oracle不同,文件和内存的交互是在后台异步完成的,不会直接影响到应用与内存交互的性能。

图6-3 TimesTen技术架构

(1)内存结构

先来看一下内存结构吧。在内存结构中,包含如下三个主体结构:

  • Data Store:保存所有数据库数据的区域,我们将其视为一个独立的数据库,可以对应Oracle的数据文件和高速缓存的合集,只不过存储位置完全在内存区域;

  • 日志缓存:用于暂时存储记录Data Store变更的日志,可以对应到Oracle的SGA共享内存区域的日志缓存(Log Buffer);

  • 临时数据区域:临时存储执行计划等数据的共享区域,排序等等操作临时使用。相比与Oracle,TimesTen在此处作出了结构上的简化,可以视为Oracle的多个内存区域的合集,也正因为这样的简化,TimesTen在使用上相当于就必需保证简单化,否则争用热点出现,其性能甚至可能不如Oracle数据库。

在应用程序和主体内存结构之间,还架设了一层TimesTen的引擎,其需要在配置文件中进行具体的指定,功能为执行SQL语句并返回执行结果。

(2)后台进程

在后台进程中,我们可以分为常驻进程和可选进程两种,常驻进程是TimesTen数据库所必需的,包括:

  • 主进程(Daemon):负责监听功能(Listener),读取配置文件信息,及分配和监视子进程。

  • 子进程(Sub Daemon):负责加载和卸载Data Store,将日志缓存写入日志文件,监视和解除死锁,及执行检查点。

如果需要实现TimesTen数据库与Oracle数据库交互的高可用架构,可选进程也是不可少的。可选进程主要包括:

  • 复制代理(Replication Agent):用以实施TimesTen主备数据库直接的复制工作,以及AWT缓存集合的数据刷新,以保证数据库高可用,有些类似与Oracle的Data Guard,但是相对来说,结构较为简单;
  • 缓存代理(Cache Agent):实施缓存连接,开启缓存代理后,可以在TimesTen和Oracle之间开启心跳连接,并且数据定时刷新,使得TimesTen成为Oracle的前置缓存数据库;

  • Server进程:当TimesTen采用C/S连接模式时,响应客户端连接的服务器进程。

  • Process进程:当TimesTen采用Direct连接模式时,响应连接请求的进程。

(3)文件结构

最后来看一下TimesTen数据库的文件结构,是否可以看到一些Oracle的影子呢?麻雀虽小,五脏俱全,TimesTen的文件结构包括:

  • 配置文件:

TimesTen服务器端的配置信息都被记录在sys.odbc.ini文件中,包括:服务器端基本配置和各个Data Store的初始化参数;

客户端连接的配置信息则被记录在sys.ttconnect.ini文件中,如果需要使用C/S连接模式,就需要配置该文件;

ttendaemon.options则用来记录TimesTen主进程所需要的配置信息,包括后台日志目录、日志大小、C/S连接端口号、TNS_ADMIN目录等。

  • 警告日志文件:

ttmesg.log记录的是TimesTen运行情况的日志记录,有些类似于Oracle的alert.log文件;

tterrors.log则记录的是报错信息,有些类似于Oracle的系统进程跟踪文件;

instance_info用来记录该主机上安装过的TimesTen软件信息,包括:版本、软件目录、主进程端口号等。

  • 在线日志文件:

可以视为Oracle的在线重做日志文件和归档重做志文件的合集,在TimesTen中是没有两者概念之分的,都称为在线日志文件,与Oracle不一样的是,其没有循环重复使用的机制,日志的数量会一直增加,需要定期清理,当满足如下条件时,会自动清理过期日志文件:

  • 关联事务已经全部提交完成的;
  • 检查点文件不再需要的;
  • 复制代理不再需要的;
  • Oracle缓存连接的缓存代理不再需要的;
  • 如果数据库进行过备份,则同时备份集中已经包含的。
  • 预留日志文件:

也可以称为恢复日志文件,是在TimesTen宕机时恢复使用,如磁盘空间满了,TimesTen会使用该预留的日志文件记录日志,保证不丢数据(每个Data Store只能配置3个预留日志文件)。

  • 检查点文件:

这类文件也是TimesTen比较特别之处,我们可以视其为数据文件,主要用来记录和同步Data Store的内存数据,是内存在磁盘上的一个镜像。当TimesTen重启或恢复的时候,子进程会将检查点文件的数据重新加载到Data Store内存区域。

每个TimesTen实例有两个检查点文件,在做检查点操作的时候会交替写入这两个文件,两个检查点文件之间的存在一定的时间间隔。在TimesTen数据库中,有三种类型的检查点:

  • 阻塞(Blocking)检查点,做该检查点操作时会加上数据库级别的锁,它是一个完全检查点,必须保证事务的一致性;
  • 非阻塞(Fuzzy)检查点,做检查点时不会加数据库级别的锁,不影响应用使用,通常数据库工作时周期性进行的就是该类检查点,它是一个不完全检查点,不必保证事务的一致性;
  • 静态(Static)检查点,TimesTen实例在创建和卸载的时候会做这种类型的检查点,此时不论是否存在脏数据块,都会全库写一遍数据文件。

需要注意的是,TimesTen与Oracle不一样,没有那么复杂的后台进程配置和触发关系,内存与检查点文件的记录和同步都是通过子进程来完成的。

为什么TimesTen需要配置两个检查点文件呢?主要还是为了保证数据冗余和快速恢复,当一个检查点失败,数据库宕机了,也可以通过另一个检查点文件快速的进行日志恢复。然而,因为有两个检查点,使得TimesTen内存与文件系统的I/O交互压力也相应增大了,内存数据库对前端应用是没有I/O的,但后台交互的I/O问题是不能小视的。

3. 连接方式

当应用端向TimesTen数据库发起连接的时候,主要可以有两种连接的模式:

(1)直接(Direct)连接模式

Oracle推荐的连接方式,具有最佳的性能,TimesTen数据库与中间件部署在同一台主机上,同处于中间件层,应用程序通过ODBC/JDBC直接对数据库进行访问,与传统的C/S模式相比,减少了TCP/IP、IPC方面的开销。

然而,TimesTen和中间件部署在同一台主机上,一定程度上增加了运维的风险。

(2)客户端/服务器(C/S)连接模式

传统的连接方式,性能比直接驱动器连接差,TimesTen数据库与中间件处于不同的主机上,客户端与服务器一般以TCP/IP方式连接,存在网络开销。

从性能上来看,直接连接的模式是有优势的,但也不是说应用程序就一定要选择该连接模式,还是需要考虑在运维方面是否能够接受因此而带来的风险。另一角度来看,TimesTen通常是作为数据库来进行运维的,被定义在数据库层,而直接连接的模式要求将其置于中间件层进行部署与运维,需要考虑在跨部门合作上的风险是否可以接受。

4. 高可用形式

我们说过TimesTen可以通过复制代理的方式实现类似于Oracle数据库Data Guard的容灾复制功能,但在功能上却没有那么强大,属于轻量级的应用。然而,因为架构的简单,所以形式更趋于多样化。

先来看一下复制代理的基本特征:

  • 复制代理是一种基于事务日志的复制,即通过在线日志的应用来实现复制功能,而非简单的基于SQL语句的复制;
  • 复制代理是通过TCP/IP流套接(Stream Socket)收发更新信息;

  • 复制代理也可以像Data Guard一样,选择同步复制或异步复制的模式;

  • 复制的粒度精细到日志的时间戳,有效解决了更新版本冲突的问题。

再来看一下常见的复制形式,如图6-4所示,TimesTen基于复制技术的高可用架构可分为:主从复制、双主复制、环形复制、衍生复制四种。

图6-4 高可用复制模式

然而,在TimesTen数据库的架构设计上,我们还是要秉承简单快捷的原则,一定程度上可以参考MySQL复制的设计,虽然可以选择的方式很多,但只选择和使用最简单、最不容易出错、最容易排错的方式。TimesTen本身就是轻量级的,简单至上,我们不能期望其能像Oracle一样强大。因此,这里推荐主从复制方式,通常应用的要求基本上都能满足。

二.TimesTen原理及应用场景的更多相关文章

  1. Java线程池使用和分析(二) - execute()原理

    相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的 ...

  2. Java进阶(七)正确理解Thread Local的原理与适用场景

    原创文章,始自发作者个人博客,转载请务必将下面这段话置于文章开头处(保留超链接). 本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ Th ...

  3. Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  4. [转帖]Docker五种存储驱动原理及应用场景和性能测试对比

    Docker五种存储驱动原理及应用场景和性能测试对比 来源:http://dockone.io/article/1513 作者: 陈爱珍 布道师@七牛云   Docker最开始采用AUFS作为文件系统 ...

  5. laravel基础课程---7、文件处理、闪存、cookie(cookie原理和使用场景)

    laravel基础课程---7.文件处理.闪存.cookie(cookie原理和使用场景) 一.总结 一句话总结: 页面请求服务器的时候是把这个页面中所有的cookie都带上了的,cookie里面也存 ...

  6. Dockerfile多阶段构建原理和使用场景

    本文转载自Dockerfile多阶段构建原理和使用场景 导语 Docker 17.05版本以后,新增了Dockerfile多阶段构建.所谓多阶段构建,实际上是允许一个Dockerfile 中出现多个 ...

  7. ThreadLocal 原理和使用场景分析

    ThreadLocal 不知道大家有没有用过,但至少听说过,今天主要记录一下 ThreadLocal 的原理和使用场景. 使用场景 直接定位到 ThreadLocal 的源码,可以看到源码注释中有很清 ...

  8. Kylin系列之二:原理介绍

    Kylin系列之二:原理介绍 2018年4月15日 15:52 因何而生 Kylin和hive的区别 1. hive主要是离线分析平台,适用于已经有成熟的报表体系,每天只要定时运行即可. 2. Kyl ...

  9. 深入解析ThreadLocal 详解、实现原理、使用场景方法以及内存泄漏防范 多线程中篇(十七)

    简介 从名称看,ThreadLocal 也就是thread和local的组合,也就是一个thread有一个local的变量副本 ThreadLocal提供了线程的本地副本,也就是说每个线程将会拥有一个 ...

随机推荐

  1. 移动端 Web 开发前端知识整理

    文章来源: http://www.restran.net/2015/05/14/mobile-web-front-end-collections/ 最近整理的移动端 Web 开发前端知识,不定期更新. ...

  2. 轮播插件unsilder 源码解析(二)

    $.fn._active = function(className) { //当前的添加class,相邻元素去除class return this.addClass(className).siblin ...

  3. 387. First Unique Character in a String

    Given a string, find the first non-repeating character in it and return it's index. If it doesn't ex ...

  4. SQL拼接自己需要的字符串

    SQL行转列有多种写法,如果想把多行数据拼接成为新的一行,比如: 首先,将查询转为XML 替换XML的标签 将第一个字符,去掉试用 STUFF函数 sql STUFF用法 1.作用 删除指定长度的字符 ...

  5. 如何发布带静态资源的库——android 篇

    1.首先要使用 android sdk 提供的命令行工具处理已有的项目: cd YourProjectDir android update project -p ./ 2.上一步生成的 build.x ...

  6. jcFeather Maya 羽毛插件

    jcFeather 2.8.6 插件持续更新地址为:http://www.jerrykon.com/jcFeather.html 和 http://www.creativecrash.com/maya ...

  7. 常用shell 命令整理 一 进程 cpu

    1.查看内存从大到小排列 ps -e -o "%C : %p : %z : %a"|sort -k5 -nr 分析: -e 显示进程 -o 按用户自定义格式显示 %C cpu %p ...

  8. php无限极分类以及递归(thinkphp)

    php无限极分类: 无限极分类重点在于表的设计: 1在model中: class CatModel extends Model{ protected $cat = array(); public fu ...

  9. MVC路由配置例

    public static void RegisterRoutes(RouteCollection routes) { string suffix = string.Empty; routes.Ign ...

  10. 分布式的Id生成器

    项目中需要一个分布式的Id生成器,twitter的Snowflake中这个既简单又高效,网上找的Java版本 package com.cqfc.id; import org.slf4j.Logger; ...