Aurora Cache???? ???Cache??????

2011-12-26 12:37:44by SeaCat

AuroraCacheDesign2

Cache数据更新检查

要使cache数据准确有效,就必须要解决这样几个问题:怎样检查cache是否失效?怎样让cache中的数据保持最新?以及如何更新?这些问题的答案,往往取决于数据使用的频率,更新的频率,重新创建的成本等因素。一般而言,常见的模式有以下几种:

数据使用者创建,数据修改者刷新

基于主键的数据库记录缓存是这类模式的代表。例如,通过用户的id来获取用户数据。首先检查指定id的记录在cache中是否存在,如果存在,就直接使用cache中的数据,否则,执行实际的数据库查询,再将结果写入cache。另一方面,在用户记录的更新程序中,完成实际的数据库操作之后,再从cache中删除对应的记录。这样,下次重新访问这条记录时,由于cache中已经没有记录,就会触发cache数据的创建。

这种模式必须确保所有会导致数据更新的入口,都有相应的cache失效处理。假设有多个异构系统使用同一套数据库,并且每个系统都有对同一表进行更新的可能,那就必须确保每个系统在更新完记录之后都采取同样的cache失效操作。

数据使用者独立完成检查、刷新

这类模式最典型的例子就是磁盘文件的缓存。如果磁盘文件内容比较大,将文件内容放到cache中,不必每次都去重新读取文件而消耗I/O成本,是一个不错的主意。需要读取文件内容时,先检查cache中是否已有该文件的cache版,并通过文件的最后更新时间来检查cache创建后,该文件是否已经修改过。如果任意一个条件满足,则重新从磁盘读取文件,并将内容写入cache;否则,就可以直接使用cache中的数据。

失效风暴

所有由cache的使用者同时完成cache数据创建的模式,都要考虑这样的问题:如果数据是被多个客户端并发访问,一旦cache失效,有可能会有多个处理客户端请求的线程同时开始cache数据的重建。如果并发访问量非常大,那么数据更新之后,有可能会引发所谓的*“Cache失效风暴”*。假设在数据更新操作中,对某条记录执行了cache清理操作,而同时又有大量并发用户在尝试访问这条记录,就会突然产生大量的并发查询,对数据库造成冲击。如果数据读写都非常频繁,还可能会导致这样一个问题:第一次更新引发的cache重建过程尚在进行,第二次更新又发生了,如果在多线程的环境下,由于某些特殊原因第二次更新引起的cache重建先于第一次完成,结果第一次更新引发的cache重建会以过期的数据覆盖第二次。

从不检查,定期刷新

如果对数据读取的实时性要求不是那么高,可以考虑这种策略。例如,一个电子商务网站的产品浏览界面。由于产品数据更新的频率远远低于用户浏览产品数据的频率,所以,可以考虑对这个界面内容进行cache。通常在更新完产品后,并不需要用户绝对实时地看到更新后的内容。更改一个商品的描述,后续访问该商品的用户在2秒钟之后才看到最新的结果,通常是可以接受的。这时,就可以让cache数据定期失效,定期重建。

根据cache创建者的不同,又可以将这个模式再细分为两类:使用者同时负责创建,以及使用者和创建者分离。Memcached支持cache数据的失效时间设置,可以很好地实现前者:在写入cache的时候,就可以指定一个失效时间,超过这个时间后,cache自动失效。这样,下次访问的时候,由于cache missing会导致一次重建,使得cache中的数据与最新数据保持同步。另外,也可以单独启动一个线程,按指定的时间定期获取最新的数据,写入cache中。虽然这种模式在某种程度上会导致架构更加复杂,但由于cache的重建变成一个工作量恒定的,与访问量无关的单一线程,可以很好地避免“失效风暴”。

Cache的生存周期

永远存在

有些数据是应用程序需要频繁访问并且消耗资源较少的,例如:screen、Business Model源文件,以及其它XML配置文件;或者,系统反问频率最高的一些页面:首页,登录界面,这类数据可以认为是永远存在于cache中,没有必要因为资源不足而移除。

根据使用频率动态移除

如果把所有内容都cache住,会占用过多的内存资源,所以,通过数据的使用频率,来决定哪些数据应该更长久地保留,是合理的。Memcached在遇到内存不足的时候,将通过“最少使用最先移除”的算法,将当前使用量最少的cache清除,以便为新数据的写入分配空间。

Demo
    Attachments

      Comments

      0 Responses to the article

      暂时没有评论。

      发表评论