Ben Tech

后知后觉
posts - 4, comments - 24, trackbacks - 1, articles - 1
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

    目前正在做的一个Web应用,是做了负载均衡的。在应用中,对某些实体数据做了Memory级别的缓存处理,以减少数据库访问次数,提高性能。缓存的实现是采用Asp.net 2.0的System.Web.Caching命名空间中的类。实体数据在某些情况下会有变更,所以需要对缓存进行处理,或清除或同步。在这种情况下产生了一个问题:实体数据发生变更之后,如何通知到后台的N多个Web应用中的缓存?下面方法是做的一些尝试。

1. 采用服务的方式
    这是一种最直接的方式。当然服务的方式可以多种多样,比较简单的方式是提供一个ClearCache.aspx的页面,当实体数据发生变更之后调用N多台Web应该的这个页面。

2. 采用File Dependency的策略
    这种策略让缓存依赖于一个指定的文件,通过改变文件的更新日期来清除缓存。这种方式的缺点是,如果缓存的数据比较多,相关的依赖文件比较松散,对管理这些依赖文件有一定的麻烦。对于负载均衡环境下,还需要同时更新多台Web服务器下的缓存文件,如果多个Web应用中的缓存依赖于同一个共享的文件,可能会省掉这个麻烦,但是对Web应用中运行帐号的权限所限,终归不是那么简洁。

Code

3. 采用SqlCacheDependency的策略
    这种策略让缓存依赖与数据库中指定的数据(查询结果)。可以用Poll的方式主动调用,设定一个周期,循环调用查询语句,如果查询结果发生变化,就会清除缓存。也可以配合Sql Server 2005,采用Push的方式被动的被通知什么时候会清楚缓存。这种Push的方式是基于Sql Server 2005中Broker Service的订阅服务,SqlCacheDependency需要配合SqlDependency来实现这种方式。

Code
Code

注1:数据库中新建一个CacheDependency的表,主键为CacheKey varchar(50),另一个字段为Flag bit。缓存项依赖与CacheDependency中对应的一行。
注2:数据库中需要启动Broker Service。命令为:
alter database [dbname] set enable_broker (需要断开其他的数据库连接)。
注3:在Applicantion Start和End的时候需要开启和停止SqlDependency。

结束语:
    缓存的实现除了可以用Asp.net自带的Cache外,还可以用Entlib的Cache Application Block,没有仔细研究过。以上的三种方式是参考网上N多资源以及自己实践的结果。如果有建议或有其他方式,欢迎盖楼。

Feedback

#1楼  回复 引用 查看   

2008-06-25 22:54 by Zhuang miao      
e

#2楼  回复 引用 查看   

2008-06-25 22:59 by Jeffrey Zhao      
分布式缓存不错的阿

#3楼[楼主]  回复 引用 查看   

2008-06-25 23:05 by Benjamin Li      
老赵的响应就是快!

#4楼  回复 引用 查看   

2008-06-25 23:12 by 黑山小妖      
楼主这个项目里有没有关于分布式文件的处理?介绍一下经验呀。另外你可以看看shared cache

#5楼[楼主]  回复 引用 查看   

2008-06-25 23:40 by Benjamin Li      
@黑山小妖
你指的是分布式文件的处理具体是指什么内容?我的项目中貌似用了DFS。

#6楼[楼主]  回复 引用 查看   

2008-06-25 23:41 by Benjamin Li      
@黑山小妖
另,你指的shared cache是http://www.codeplex.com/SharedCache吗
感谢分享!

#7楼  回复 引用   

2008-06-25 23:42 by 黑山[未注册用户]
比如大量文件的读取和复制分发之类的

#8楼[楼主]  回复 引用 查看   

2008-06-25 23:45 by Benjamin Li      
没有尝试过这种东东。。

#9楼  回复 引用   

2008-06-26 02:41 by 高效空气过滤器[未注册用户]
推荐web负载集群软件。*

#10楼  回复 引用 查看   

2008-06-26 09:00 by 玉开      
Memory Cache很成熟;微软自己的分布式缓存的还没有正式版。

#11楼  回复 引用 查看   

2008-06-26 09:33 by Tristan Guo      
你的方案似乎跟是否“负载均衡环境下”没有关系伐

#12楼  回复 引用   

2008-06-26 09:46 by lzppcc[未注册用户]
你可自己实现使用remoting实现缓存.

#13楼  回复 引用 查看   

2008-06-26 14:15 by ddwinter      
像这种分布式应用的缓存,已经有很成熟的解决方案,没有必要自己去实现.
比如:memcached

是开源的缓存软件,它提供一种缓存服务。

把多台服务器的缓存集中存放在一台服务器。这有利于多台服务器间缓存的同步。

#14楼  回复 引用   

2008-06-26 14:19 by cloudjun[未注册用户]
--引用--------------------------------------------------
玉开: Memory Cache很成熟;微软自己的分布式缓存的还没有正式版。
--------------------------------------------------------

微软的velocity有了CTP1,里面就有updating cache的notification功能,貌似很不错。

#15楼  回复 引用   

2008-06-26 14:21 by cloudjun[未注册用户]
--引用--------------------------------------------------
ddwinter: 像这种分布式应用的缓存,已经有很成熟的解决方案,没有必要自己去实现.
比如:memcached

是开源的缓存软件,它提供一种缓存服务。

把多台服务器的缓存集中存放在一台服务器。这有利于多台服务器间缓存的同步。

--------------------------------------------------------

我写了篇简单的memcached 和 微软velocity的比较,在这里http://www.cnblogs.com/cloudjun/archive/2008/06/25/1229316.html,memcached据我所知没有notification机制。

#16楼  回复 引用 查看   

2008-06-26 14:46 by 小庄      
建议楼主还是使用Memory Cache吧!
一直对这个SqlCacheDependency不太明白的地方是数据的更改可以PUSH到程序中去通知缓存?还要依靠Broker Service服务?楼主的代码里没有这个PHSH机制啊?难道这个PUSH机制在SqlCacheDependency实现了?也就是说SqlCacheDependency中有调用Broker Service的代码?

#17楼  回复 引用   

2008-06-26 16:30 by wwonion[未注册用户]
不明白楼主是在什么时候使缓存失效的,我按楼主的代码运行了一遍,并不会让缓存失效。

还请楼主指点一下。

#18楼[楼主]  回复 引用 查看   

2008-06-26 16:55 by Benjamin Li      
@小庄
这种Push的机制是通过SqlDependency实现的,对SqlCacheDependency来说是透明的,请看注3。

@wwonion
缓存是否失效是看SelectCommand中查询结果是否有变化。也就是说,只要改变一下对应CacheKey的Flag的值,缓存就会失效。另外看看你是否实现了注3中的提到的SqlDependency。Flag的类型改成uniqueidentifier应该会更合适

#19楼  回复 引用 查看   

2008-06-26 18:29 by 陛下      
念书的时候记得在“路由算法”(?)中存在类似问题,
每个服务器自维护一份地址长表,
有关它们之间如何更新、同步数据,貌似有些成熟算法的;
我只对“令牌”(token)这个名词还存些印象,
每个服务器组中有个“头”拥有数据最终裁定权,
同时当权者出现异常时支持“换届选举”。

不知道跟楼主说的是不是同一个问题,
感觉上接近于楼主说的“采用File Dependency的策略”。

时间长了,知识也忘的差不多了。

#20楼[楼主]  回复 引用 查看   

2008-06-26 19:14 by Benjamin Li      
@陛下
没有你说的那么复杂,我的本意是让多个Web应用中的Cache共同依赖于一个共享文件,只要这个文件发生变化,就清除缓存。或者多个Web应用的Cache依赖于他本机的某个特定的文件,如果实体数据发生变化,那么我们要保证同时更新这多个依赖文件。

#21楼  回复 引用   

2008-07-08 14:19 by lizheng[未注册用户]
受教了,楼主要多发些好文

#22楼  回复 引用   

2008-10-06 16:48 by leoning[未注册用户]
发现跟负载均衡没关联呢?
SqlCacheDependency的策略具体如何使用?在单一个web server上是没问题的,如用到负载均衡,如何保证多台web server上cache的值保持同步?

#23楼  回复 引用 查看   

2010-03-16 17:18 by Alifellod      
来自2010的声音
写的很好.