用于处理消息队列的方法、设备和计算机程序的制作方法

文档序号:6489538阅读:320来源:国知局
专利名称:用于处理消息队列的方法、设备和计算机程序的制作方法
技术领域
本发明涉及数据处理系统,更具体地,涉及通过这样的系统对消息队列进行的处理。
背景技术
经常需要将行为序列“重放(replay)”到数据库或者其它系统(如消息发送系统)中。
该序列可以以各种级别表示,例如,日志重放(在恢复中使用)、事务改变重放(使用在数据库复制中)、或者呼叫重放(属于所进行的呼叫的检查日志,可能在SQL或者存储的过程级别上、或者甚至在更高的应用级别上)。
经常地,原始行为的执行与数据库事务和确保逻辑顺序(有时候仅部分顺序)的锁定技术高度平行。这个并行性对获得好的系统性能是必需的。
以将被重放的序列表示用数据库事务和锁定技术确保的逻辑顺序。问题在于必须尽可能快地重放,并且这也需要一定的并行度。然而,仍旧需要保持原始的逻辑次序。
作为示例,考虑将重放的序列表示为工作项队列的系统。每个工作项表示原始的事务,并包含将要进行的数据库记录级别更新列表。
(在这里使用术语更新包括改变数据库的任何操作,至少包括SQLINSERT、DELETE和UPDATE语句,并且还包括诸如数据定义更新之类的任何其它更新。)其自然(非常简单化的)实现是单个“主事务”线程//主事务线程for each work item//即原始事务get(e.g.read)work itemfor each recorde update in work itemapply update//例如,记录级别更新end for each update
commit(work item read operation and database update operation)end for each work item然而,每个“施加(apply)更新”(其通常需要在可以施加更新之前取出(例如,读取)的相关数据库记录)可能需要当前没有保存在与数据库相关联的缓冲池中的数据,因此处理延迟直到取回(retrieve)所需要的数据。这样,问题在于可能严重影响处理吞吐量。
当然理解的是,由于可能使用标准的数据库懒写入(lazy write)技术,所以实际上将更新返回到数据库盘也具有对应的问题。
尽管这个问题可施加到消息发送系统,但是它较不重要。由于大多数队列活动在队列结束时是可预测的,所以可以适当可预测地预取将要读取的消息缓冲池。换言之,典型地以FIFO(先入先出)顺序读取队列,并且,这样可以可预测地且连续地预取该队列。
在数据库系统中进行这样的预测是非常困难的。这是因为,从数据库中依次读取的记录典型地散布在整个数据库盘中,并且,对数据库的工作可能不需要依次(即,连续地)存储的数据记录。
美国专利6092154公布了一种在多媒体环境中使用线程列表对数据进行预先超高速缓存的方法。通过主应用而把将需要的数据列表(读取请求)传递到数据存储装置中。然而,在多媒体环境中,可以通过主应用而方便地指定作为读取请求的结果而需要的数据。在数据库环境中,主应用可能不知道存储数据的方式,或者即使它知道,主应用可能也不能够将其合适地传送到数据存储装置。这样,有可能后续操作所需要的部分数据将不可用。
美国专利6449696也公开了利用读取请求基于列表内容而从盘中预取数据。

发明内容
因此,本发明提供了一种用于处理消息队列的方法,每个消息表示至少一个用于对数据库进行更新的请求,该方法包括以下步骤浏览消息;从所浏览的消息中提取更新请求;以及将伪更新请求发送到负责要更新的数据库的数据库管理系统(DBMS),其中,伪更新请求包括指示DBMS不应该执行更新而应该预取当请求对应的真实更新时所需要的数据的指示。
优选地将伪更新请求转换成为预取请求;并预取所需要的数据。
优选地,随后启动真实更新请求,该真实更新请求使用预取的数据来执行。优选地,破坏性地从队列中得到包括更新的消息。优选地,该破坏性获得与实际的数据库更新相互协调(两个阶段的提交),使得直到已经实际接收到对更新的确认才删除消息的副本。
在一个实施例中,主线程执行启动更新请求的步骤,并且一个或多个提前读取线程执行浏览消息的步骤。
优选地,保持主线程落后提前读取线程预定处理量。可以根据消息、更新等来估量(measure)这个处理量,并且该处理量有助于确保数据在需要时存在于存储器中。如果主线程太近,则有在要求执行更新请求时所需要的数据可能不在存储器中的危险。另一方面,如果主线程落后太远,则存在存储器变得太满而导致不得不重写还没有使用的数据的危险。
在一个实施例中,预取请求具有被保留的预定形式,并且将标识符与其关联,以便可以标识所保留的预定形式,并用于真实更新请求的随后执行中。优选地,响应伪更新请求而返回该标识符。
在一个实施例中,由DBMS将伪更新转换成为具有预定形式并与标识符相关联的预取请求。该标识符接收自DBMS并在发布真实更新请求时使用。
优选地,响应将预取的数据用于更新请求,通知存储器管理器可以将所已使用的所预取的数据从存储器丢弃。这有助于避免存储器变满溢。
根据一个方面,提供了一种用于在数据库管理系统(DBMS)上对DBMS所控制的数据库的更新请求进行预处理的方法,该方法包括在DBMS上接收更新请求;在DBMS上接收指示该更新请求是伪更新请求、并因此DBMS不应该执行该更新而应该预取当请求对应的真实更新时所需要的数据的指示;将伪更新请求转换成为预取请求;以及基于该预取请求来预取所需要的数据。
优选地,随后接收真实更新请求,并且使用所预取的数据来执行真实更新请求。
在一个实施例中,预取请求具有预定的形式并被保留。然后,将标识符优选地与所保留的预定形式相关联,以便可以标识所保留的预定形式,并用于真实更新请求的随后执行中。优选地,响应该伪更新请求而返回该标识符。
在一个实施例中,利用真实更新请求接收标识符,并将其用于真实更新请求的执行中。
根据另一方面,提供了一种用于处理消息队列的设备,每个消息表示至少一个用于对数据库进行更新的请求,该设备包括用于浏览消息的装置;用于从所浏览的消息中提取更新请求的装置;以及用于将伪更新请求发送到负责要更新的数据库的数据库管理系统(DBMS)的装置,该伪更新请求包括指示DBMS不应该执行更新而应该预取当请求对应的真实更新时所需要的数据的指示。
根据另一方面,提供了一种用于在数据库管理系统(DBMS)上对DBMS所控制的数据库的更新请求进行预处理的设备,该设备包括用于在DBMS上接收更新请求的装置;用于在DBMS上接收指示该更新请求是伪更新请求、并因此DBMS不应该执行该更新而应该预取当请求对应的真实更新时所需要的数据的指示的装置;用于将伪更新请求转换成为预取请求的装置;以及用于基于预取请求来预取所需要的数据的装置。
根据另一方面,提供了一种用于处理消息队列的计算机程序,每个消息表示至少一个用于对数据库进行更新的请求,该计算机程序包括适配为当在计算机上运行时执行包括如下步骤的方法的程序代码装置浏览消息;从所浏览的消息中提取更新请求;以及将伪更新请求发送到负责要更新的数据库的数据库管理系统(DBMS),其中,伪更新请求包括指示DBMS不应该执行更新而应该预取当请求对应的真实更新时所需要的数据的指示。
根据另一个方面,提供了一种用于在数据库管理系统(DBMS)上对DBMS所控制的数据库的更新请求进行预处理的计算机程序,该计算机程序适配为包括当在计算机上运行时执行如下方法步骤的程序代码装置在DBMS上接收更新请求;在DBMS上接收指示该更新请求是伪更新请求、并因此DBMS不应该执行该更新而应该预取当请求对应的真实更新时所需要的数据的指示;将伪更新请求转换成为预取请求;以及该基于预取请求来预取所需要的数据。


图1示出根据现有技术的数据库系统;图2图解根据优选实施例的本发明的处理;以及图3进一步图解根据优选实施例的本发明的处理。
具体实施例方式
图1示出根据现有技术的数据库系统。系统10具有用于执行处理的工作项(消息)队列20。每项工作表示对数据库30中的记录的至少一个更新。
从右向左(FIFO顺序)读取工作队列20,这样,可以将数据库30所需要的数据看作数据项(记录)A、B、C、D。(注意,每项工作可以表示多于一个更新,且因此可以从数据库30要求多于一个记录。)施加应用(apply application)40从队列20读取,并从数据库管理系统(DBMS)70(经由数据库接口45)请求合适的数据。该DBMS包括查询处理器50(包括分析程序),其经由缓冲池管理器(没有示出)从缓冲池60(易失性存储器)请求数据。如果在缓冲池中没有找到数据(这是有可能的),则必须从数据库本身取出数据。因为数据库可能在盘上存储数以千计的记录,并且因为未必是以可预测顺序存储数据,所以,虽然将所需要的数据取回到缓冲池60中,但是可能会严重影响系统的吞吐量。在这个例子中,工作队列20要求以那个顺序将记录A、B、C和D取出,但是盘以完全不同的顺序(A、C、D、B)存储这些记录。为此,预测性地预取记录(即,通常按序列顺序)对数据库是没用的,例如,在读取A后得到C。
本发明要解决这个问题。图2图解根据优选实施例的本发明的处理,并应该结合图1看图2。
施加应用40中的主提前读取线程浏览来自队列20的每个工作项(步骤100)。如先前所论述的,每个工作项包括数据库30的所请求的至少一个更新。对于每一个这样的请求更新,生成先驱更新线程(步骤110)。每个先驱更新线程(经由DBMS 50)启动将所要求的数据的取到缓冲池60中,使得当被请求时可以对数据库30施加适当的更新(步骤120)。
先驱更新线程没有改变数据库本身(它们仅仅读取数据),这样,可以容易地并行施加这些线程。这个并行性允许数据库使它的I/O方案最优化(以与将在原始事务的并行执行期间具有的方式相同的方式)。
先驱呼叫的完全实现优选地确保将所有的相关数据(与记录和索引二者有关的)读入到缓冲池。例如,进行设置人员#1234的薪水到50000的更新。这将可能包括人员记录本身,和与人员#有关的对人员表的索引。如果有关于薪水的索引,则也优选地将其预取。
有三种可以用来获得先驱更新(伪更新)的机制机制A其中,先驱线程将更新请求转换成为相关联的预取请求,其为查询(即,取出合适数据而不实际执行更新本身的查询),并且将该请求发布到数据库。这样,用关于人员#1234的查询模拟了该先驱呼叫。
机制B其中,扩展数据库接口45,以便允许先驱线程向数据库指示该呼叫是先驱呼叫(伪更新请求)而不是“真实”的更新。先驱线程从工作项中提取更新请求(图3的步骤200);将该更新请求发送到DBMS(步骤210);并(经由具有更新请求的指示)通知DBMS,这个是伪更新请求,使得DBMS可以将伪更新请求转换成为预取请求以便取出所需要的数据(步骤220)。
机制C其中,进一步扩展数据库接口45,例如,通过在呼叫之间传递用于更新的标记(标识符),使得来自先驱线程(启动预取请求)和来自主事务线程(即,随后执行所请求的更新的线程)的呼叫明显相关联。注意,机制C优选地为机制B的扩展。
机制A不涉及对数据库的改变。然而,它在将更新转换成为相关查询时通过而涉及施加应用的更多工作。也有可能该查询将没有强制数据库读取缓冲池中的所有合适数据;在这个例子中,可以适当地不预取关于薪水的索引的相关部分。这是因为,施加应用可能没有完全理解数据库如何存储它的信息,或者可能发现难以将合适的请求传达到DBMS。在机制B中解决了这些问题。
在机制B中,将伪更新请求转换成为预取请求,并将其用于取出在执行对应的真实更新被请求时将需要的数据。因为DBMS产生了预取请求,所以更有可能要预取用于具体真实更新请求的所有需要数据。DBMS知道存储数据的方式,并能够将其有效地转换成为合适的预取请求。
为了更完全地说明机制C,当由施加应用生成先驱更新请求时,将其发送到查询处理器,以便查询处理器将该更新请求解析成为内部(预定)形式。这个内部形式用于确定从数据库中取回什么数据。一旦取回了数据,则可以丢弃这个内部形式。然而,在这么做的过程中,当主线程希望进行该真实更新时,将不得不再次解析该更新请求。
为了节约时间和处理功率,查询处理器可以保存作为先驱更新请求结果的解析的内部形式,并且,这可以与被传递回到施加应用的标记相关联。当主事务线程希望进行该更新请求时,可以由施加应用将相同的标记传递到DBMS,然后,这可以用于确定该请求的合适解析内部形式。这个改进消除了对两次解析的需求。
缓冲池管理器(没有示出)还优选地使用机制C的查询标记,以确定何时不再需要预取的数据项。当将该标记从施加应用传递回到DBMS以便实施更新时,从缓冲池中取回相关数据,然后,优选地将标记传递到缓冲池管理器,以便向其指示可以从缓冲池中消除与该标记相关联的数据。仅仅在这样的情况中优选地将数据从缓冲池中消除。
这将降低以下风险预取的数据甚至在对其有需求之前就被从缓冲池中消除、或者相反地在缓冲池中被保留过长时间而对其它数据不利。
应该注意,尽管通过施加应用可以在没有改变数据库实现或者接口的情况下实现机制A,但机制B和C需要改变数据库接口和实现。
如上面所提到的,主提前读取线程在主事务线程(也在施加应用40中运行)之前操作。主事务线程以与提前读取线程在前面所作相同的方式得到每个工作项,但是,这次却实际上将工作项从队列中消除,以便实际进行所请求的更新。因为提前读取(和先驱线程)已经提前确定主事务线程将需要的数据,所以应该已经将需要的数据取到缓冲池60中了。这样,缓冲池管理器应该能够直接从缓冲池60中取回主线程所请求的数据,以便可以进行所请求的更新。由于可以马上得到所请求的数据,所以,I/O没有延迟,并且大大改进了这个执行。(如前面陈述的,可以使用标准的懒写入技术来实际上将更新的数据返回到盘中。)由于执行的原因,重要的是主事务线程没有太接近或者远远落后于主提前读取线程。(如果主线程远远落后,则可能在还没有使用老数据时不得不用新数据重写缓冲池;如果主线程太接近于提前读取线程,则该数据可能在对其尚没有需求之前就已经被适当地预取到缓冲池中了。)这样,优选的是在主提前读取线程和主事务线程之间存在一些形式的信令,以便防止此发生。
因此,优选地允许主提前读取线程(以及从而其先驱线程)在主事务线程之前不多于预定量(requiredReadahead)(例如,在处理的工作项、处理的更新或者处理的字节中所估量的)。
这样,施加应用40具有两个计数器,readaheadAmountProcessed和masterAmountProcessed。在优选的实施例中,根据所处理的工作项来估量requiredReadahead值。每当提前读取线程移动到下一个工作项,就增加readaheadAmountProcessed。每当主线程完成工作项的处理,就增加masterAmountProcessed。主提前读取线程包括睡眠循环(sleep loop),其促使提前读取线程所控制的任何先驱线程也睡眠while(readaheadAmountProcessed-masterAmountProcessed>requiredReadahead)sleep(10)以这个方式,提前读取线程没有在主线程之前太远。这很重要,因为否则,存在缓冲池60将变得满因此有必要将那里还没有被使用的数据移除的风险。
主线程也包括睡眠循环while(readaheadAmountProcessed-masterAmountProcessed<requiredReadahead)sleep(10)这确保主线程没有超过主提前读取线程。
注意,提前读取项的完成可以不是以有序的方式出现,因此难以精确地限定提前读取已经到达多远。这样,可以使这个信令更高级,以允许精确地完成先驱更新。
应该注意的是,在某些情况下,更新是以第一更新的执行改变实现后面的更新所必须读取的数据的方式而彼此依赖。例如
开始,佛瑞德(Fred)在Y部门。
将佛瑞德移动到X部门。
将佛瑞德的部门的管理者改变为比尔。
对[1]的先驱执行将把佛瑞德的数据读取到缓冲池中。这个数据将在后面主事务线程执行[1]时使用。[2]的先驱执行可能发生在这个更新之前,并因此把Y部门(佛瑞德的老部门)的数据读取到缓冲池中。然而,[2]的真实执行将要求X部门(佛瑞德的新部门)的数据在缓冲池中。
在这些情况中,主事务线程可以在执行对应的真实更新时延迟(即,因为所需要的数据没有在缓冲池中)。这将轻微地损害性能,但是通常地,无论如何性能都将比现有技术方法改进很多。注意,将不会导致错误结果(因为将进行事务本身的无序处理)。
改进/变化现在将描述基于上述基本思想的一些改进/变化。
至此所论述的实施例使用具有为每个先驱更新生成(产生)的新线程的单个提前读取线程,并在其工作结束时终止。
然而,线程产生/终止是耗费大的处理。这样,可以代替使用线程池。在这个实施例中,先驱更新线程池持续可用,并且,当它们的工作结束时,它们就稍后返回到池中以便再次使用。
另一个选项(可以结合线程池使用)是具有多于一个提前读取线程,并且多个提前读取线程分担工作。在一个实施例中,还使用了提前读取线程池。
该多个提前读取线程还优选地彼此用信号通知其负责哪一个工作项。以这个方式,提前读取线程不会试图做另一个提前读取线程已经完成(或者正在完成的处理中)的工作,即,没有多余地重复工作。
一种非常简单的实现是第一提前读取线程负责工作项1、4和7;第二提前读取线程浏览工作项2、5和8;而第三提前读取线程负责工作项3、6和9。
基于该基本原理的另一个改进是使用批处理。并行执行原始的事务,使得它们的日志强制(log force)(用于备份的目的)可能装箱(boxcar)(并行批处理)。这是有用的,因为日志强制是处理器密集并持有其它处理,直到该强制结束。
主事务线程被单独执行线程(这对于保存逻辑顺序很重要),并且因此没有实施装箱。然而,事务批处理可以用于仅在已经发生确定量的处理(根据时间、#消息、#更新、#字节估量的)之后执行的提交操作。由于每个提交操作也对日志引起强制操作,所以事务批处理使得能够一次强制更大量的数据,而不是频繁中断多个(消耗时间的)日志强制的主事务线程。
另一个选项是使用成对的主事务线程。利用单个主事务线程,这个线程将发送一批更新到DBMS以便处理,然后向其发送提交(或者最后的命令)。然后,主事务线程将不得不在DBMS把更新强制到数据库盘时等待。在等待从主线程(从提交)返回的控制时,另一个线程优选地正处理另一批更新,例如,使每批日志强制与随后批次的处理并行。
将理解,尽管根据将行为序列重放到数据库中而描述本发明,但是本发明不限于此。它可应用于存在将要处理的消息队列并包括对数据的随机存取的任何情况中。
权利要求
1.一种用于处理消息队列的方法,每个消息表示至少一个用于对数据库进行更新的请求,该方法包括以下步骤浏览消息;从所浏览的消息中提取更新请求;以及将伪更新请求发送到负责要更新的数据库的数据库管理系统(DBMS),其中,伪更新请求包括指示DBMS不应该执行更新而应该预取当请求对应的真实更新时所需要的数据的指示。
2.根据权利要求1的方法,包括以下步骤将伪更新请求转换成为预取请求;以及预取所需要的数据。
3.根据权利要求1的方法,包括以下步骤通过破坏性地得到包括更新请求的消息而启动真实更新请求,该真实更新请求使用预取的数据。
4.根据权利要求3的方法,其中主线程执行启动真实更新请求的步骤,并且其中一个或多个提前读取线程执行浏览消息的步骤。
5.根据权利要求4的方法,包括以下步骤保持主线程落后提前读取线程预定处理量。
6.根据权利要求2的方法,其中,预取请求是预定的形式,并且该方法还包括以下步骤保留该预定的形式;使标识符与所保留的预定形式相关联,以便所保留的预定形式可以被标识,并用于真实更新请求的随后执行中;以及响应伪更新请求而返回该标识符。
7.根据权利要求1的方法,其中,由DBMS将伪更新转换成为具有预定形式并与标识符相关联的预取请求,该方法包括以下步骤从DBMS接收标识符;以及利用更新请求通过发送标识符而发布真实更新请求。
8.根据权利要求1的方法,包括以下步骤通知存储器管理器已使用的所预取的数据可以从存储器丢弃。
9.一种用于在数据库管理系统(DBMS)上对DBMS所控制的数据库的更新请求进行预处理的方法,该方法包括在DBMS上接收更新请求;在DBMS上接收指示该更新请求是伪更新请求、并因此DBMS不应该执行该更新而应该预取当请求对应的真实更新时所需要的数据的指示;将伪更新请求转换成为预取请求;以及基于该预取请求来预取所需要的数据。
10.根据权利要求9的方法,包括以下步骤接收真实更新请求;以及使用所预取的数据来执行真实更新请求。
11.根据权利要求9的方法,其中,预取请求具有预定的形式,该方法还包括以下步骤保留该预定的形式;使标识符与所保留的预定形式相关联,以便所保留的预定形式可以被识别,并用于真实更新请求的随后执行中;以及响应该伪更新请求而返回该标识符。
12.根据权利要求11的方法,包括以下步骤利用真实更新请求接收标识符;在执行真实更新请求时使用与标识符相关联的预定形式。
13.根据权利要求9的方法,包括以下步骤通知存储器管理器已使用的所预取的数据可以从存储器中丢弃。
14.一种用于处理消息队列的设备,每个消息表示至少一个用于对数据库进行更新的请求,该设备包括用于浏览消息的装置;用于从所浏览的消息中提取更新请求的装置;以及用于将伪更新请求发送到负责要更新的数据库的数据库管理系统(DBMS)的装置,该伪更新请求包括指示DBMS不应该执行更新而应该预取当请求对应的真实更新时所需要的数据的指示。
15.一种用于处理消息队列的计算机程序,每个消息表示至少一个用于对数据库进行更新的请求,该计算机程序包括适配为当在计算机上运行时执行包括如下步骤的方法的程序代码装置浏览消息;从所浏览的消息中提取更新请求;以及将伪更新请求发送到负责要更新的数据库的数据库管理系统(DBMS),其中,伪更新请求包括指示DBMS不应该执行更新而应该预取当请求对应的真实更新时所需要的数据的指示。
16.一种用于在数据库管理系统(DBMS)上对DBMS所控制的数据库的更新请求进行预处理的计算机程序,该计算机程序适配为包括当在计算机上运行时执行如下方法步骤的程序代码装置在DBMS上接收更新请求;在DBMS上接收指示该更新请求是伪更新请求、并因此DBMS不应该执行该更新而应该预取当请求对应的真实更新时所需要的数据的指示;将伪更新请求转换成为预取请求;以及该基于预取请求来预取所需要的数据。
全文摘要
本发明涉及对消息队列的处理,每个消息表示至少一个用于对数据库进行更新的请求。浏览消息,并且从该消息中提取至少一个更新请求。将该更新请求发送到负责要更新的数据库的数据库管理系统(DBMS)。还向DBMS发送指示该更新请求是伪更新请求、并且DBMS不应该执行更新而是应该预取当请求对应的真实更新时所需要的数据的指示。
文档编号G06F17/30GK1829964SQ200480021628
公开日2006年9月6日 申请日期2004年6月16日 优先权日2003年8月2日
发明者斯蒂芬·J·托德 申请人:国际商业机器公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1