实现自己的O/R Mapping组件[三]-高效缓存的思考三(缓存同步研究)
缓存在实现,如何与数据库进行同步是一个令人头痛的问题。通常情况下,对于缓存的维护的职责,并不由缓存本身来进行管理,但在我思考的组件中,是需要一个自动维护与数据库进行同步的机制的,目前一般的缓存同步处理有以下几种方式,
1、通过数据库主动发送更新消息给应用程序,应用程序获取更改消息后,就去查询数据库获取最新的数据。
这种方式往往对数据库本身的机制依赖性较强,比如在Sql Server 2000中,有如下的实现方式:
a)通过"Microsoft SQL Server Notification Services 2.0 SP1"这个组件来实现应用程序与前台组件的实现。这个功能可以在Sql Server2005中直接实现,ASP2.0中的缓存同步手段中就提供了这种被称之“SQL Dependency”方式,编写难度相对较小,但这对数据库本身提供的机制有严重的依赖性。
b)也可以利用SQL Server本身的"发布-订阅"特性来实现,只是另外需要开发针对订阅手段的拦截机制,编程难度较高,对数据的依赖性也非常之大。
c)在Sql Server中通过触发器,生成一个外部的自定义格式化的文件,前台程序通过监视某一目录下的文件变化情况,制订相应的处理机制。
d)通过扩展存储过程,可以实现对外部程序的通知,这同时依赖于数据库的触发器机制。在Sql Server2000中,必须得通过C语言来实现。在Sql Server2005中则不需要。在其它不少的数据库中也有类似的机制,如Postsql,数据库中可以调用外部应用程序的函数,结合触发器的话,也可以轻易地实现数据库主动发送通知的功能。
2、在用户读取数据时,中间层组件根据不同的策略自动去查询数据库中的数据
这是一种比较常用的手段,一般有如下的实现方式:
a)在数据库中建立一张公共表,利用触发器记录数据库中的变化,每次用户访问缓存时,都去查探一下数据库中的该表中的记录,如果变化发生了,则根据变化记录去读取相应的数据,对本地数据进行更新。在SQL Server2000中,因为数据主动发消息需要安装附加组件,并需要进行复杂的编程,所以也有人采用了反向策略实现了“SQLDependency”。
b)给缓存一个生命周期的时限,如果时间超过,则到数据库中读取相应的数据进行更新,这是最常见的手段之一,在Aspnet1.1中,缓存一般就是使用的这个机制。这也是我最觉得郁闷的机制,但这也是一种非常有效的机制,可以涵盖所有的数据库进行实现。
上述方法中,除时间策略外,几乎都需要利用数据库本身的特性实现。数据库主动发送通知是最优秀的实现手段,可以把浪费减至最低,但这种手段的实现方式,也是所有的数据库提供支持最少的一种。并且,这种方式,最适合WEB的开发,性能比是最高的。
对于基于Internate的无论是分布式开发还是C/S模式的开发来说,要求数据库直接主动发送数据给应用程序,是一个非常不好的策略,因为这受到防火墙的限制,同时安全也会大打折扣。对于这个问题的当然有解决方案,也可以再在服务端通过增加一个Web service来实现,可是这样做的话,高效的数据访问比会受到一定的限制,但从减轻网络的访问流量来说,这将是一个非常好的实现方案,开发简便,大大地减低了网络流量(Web Service传送的数据最好要进行压缩处理)。如果情况更复杂一些的话,则需要考虑.NET Remoting来实现。
我不清楚其是否有其它更好的策略,上述方式中,没有一个是可以满足我的要求。如果要我选择,会很难选择,最高性能的实现方案对数据库的特性依赖性过强,这就失去了O/R Mapping中可以不管数据类型的问题。
Mmm...问题大了,只是一个缓存都那么麻烦,真是“路漫漫其修远兮”。
打算在上述方案找一个比较折衷的实现。为了革命,总要做出牺牲的,再仔细考虑一下,究竟应该牺牲打扰谁