缓存及过期问题

我2我骄傲 2016-06-29 07:45:17
现在有两个系统,A,B

A系统负责维护基础数据
B系统有个列表需要读取B系统里的数据


现在B从A读数据的时候把数据存到了缓存,现在A系统及时加了条数据进去,B系统因为缓存没过去,导致新加的数据没显示出来。
这种情况一般如何处理呢?

1,缓存必须要有 2,缓存依赖数据库的某张表方法可行不可行??会不会把数据库拖垮。

谢谢各位!
...全文
367 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
我2我骄傲 2016-07-07
  • 打赏
  • 举报
回复
谢谢sp1234 说了这么多关于缓存的东西, 确实有些小点的理解有了更清晰的理解。
我2我骄傲 2016-07-07
  • 打赏
  • 举报
回复
引用 5 楼 sp1234 的回复:
[quote=引用 楼主 jmlovews 的回复:] 现在B从A读数据的时候把数据存到了缓存,现在A系统及时加了条数据进去,B系统因为缓存没过去,导致新加的数据没显示出来。 这种情况一般如何处理呢?
正如楼上所说,缓存的 CacheDependency 中最低级的就是 Duration,但是你现在需要更高级的缓存依赖技术。 会不会设计缓存系统,不是像有些人扯什么“把数据放到内存里”这么简单的东西,更不是单独弄一个服务器上安装什么内存数据库然后就叫做缓存(内存数据库机制都是伪缓存,你付出了网络通讯的性能代价来访问一个内存数据库的数据而已),重点就在于了解设计“缓存依赖项”的技术。记住,缓存就是本机的甚至是当前进程的高速机制,而不是弄一台单机安装一个内存数据库。 .net 的 CacheDependency机制,默认的方式除了 SqlDependency,还可以根据磁盘文件、磁盘目录的改变而自动响应,还可以根据其它缓存单元的改变而级联触发,还可以你自定义一个CacheDepenency(只要你从CacheDendency类继承即可)。按说,只有了解最后一种自定义缓存依赖项的人,才真正叫做了解了缓存技术。不过我们可以仅仅用倒数第二种来看看。 假设你有一个缓存单元
cache.Insert("13998号订单最后更新时间", item);
那么你就可以将其他一些缓存数据与之关联,例如
cache.Insert(key, data, new CacheDependency(null, new string[]{"13998号订单最后更新时间"})); 
这样,当第一个缓存单元的数据改变的一刹那,第二个缓存单元(以及同样依赖“13998号订单”的其它几十个缓存单元)就自动清除了!你可以想象到,这种依赖是可以级联的。 那么现在就是你的A数据要广播消息的问题。不是说数据库只要一有改变就广播,数据库的改动只有万分之一、十万分之一的消息才需要广播。例如假设所有的订单改变都需要广播一下,那么就单独将这个信息广播一下。 最后回到前边关键的一个关键点,所谓“内存数据库”算是缓存吗?当你单独弄一个服务器然后安装一个内存数据库,你所有的数据都要写到这个内存数据库上,然后再每一此查询数据时先去通过网络查询一次这个内存数据库,如果查不到的话再去查询数据库系统,这算是缓存吗?这时候你根本没有缓存,许多人把这个叫做缓存,那是许多人(主要是使用 java 的 没有 .net cache技术的低级工具的人)在众口一词地在歪曲概念呢。 那根本不是缓存技术,就是普通的内存数据库,而已。[/quote] 明白。3Q
我2我骄傲 2016-07-07
  • 打赏
  • 举报
回复
谢谢各位的回复! 已经决定加 分布式缓存了。
  • 打赏
  • 举报
回复
你这种A、B多个系统明显跨系统的缓存,怎么也要用上Redis吧 一般通知更新缓存由A主动通知,虽然可以依赖数据库
  • 打赏
  • 举报
回复
如果让我去掉所有多余的说法来解释缓存系统跟内存数据库服务器架构的区别,那么就是两点: 1. 缓存是进程内的高速机制,不用带宽。而内存数据库是网络机制。 2. 缓存技术的重点是缓存依赖项的设计。例如上面的
cache.Insert(key, arr, new System.Web.Caching.CacheDependency(dir.FullName));
第三个参数才是缓存技术最终要追求的目标。尽量少使用内存、尽量没有多余数据,才是缓存的目标。
sp1234_maJia 2016-06-29
  • 打赏
  • 举报
回复
使用缓存,最错误的做法就是把一个表的数据当成什么“缓存”。如果你愿意这样做,那么你就只适合于内存数据库技术,而不适合使用缓存技术。 缓存技术是轻量级的技术、“外科手术式的”技术。缓存单元很小,就是一个sql查询出来的几行、几十行数据,放到一个缓存单元里。或者只是一个“内存实体数据”。 举个例子,假设有一个 ashx 用来返回某个目录下的文件的列表,假设此目录的读写比例超过了1000:1,也就是1000次读才会有1次写,那么我们就是何时用缓存。我们可以写
private JArray CmdDir(DirectoryInfo dir)
{
    var cache = HttpRuntime.Cache;
    var key = string.Format("目录 {0} 的文件列表", dir.FullName);
    var arr = (JArray)cache[key];
    if (arr == null)
    {
        arr = new JArray();
        foreach (var f in dir.EnumerateFiles())
        {
            var obj = new JObject();
            obj.Add("name", f.Name);
            obj.Add("md5", Convert.ToBase64String(Common.CommonExtensions.MD5(f)));
            obj.Add("length", f.Length);
            arr.Add(obj);
        }
        cache.Insert(key, arr, new System.Web.Caching.CacheDependency(dir.FullName));
    }
    return arr;
}
然后写

var target = Request.QueryString["dir"];
context.Response.ContentType = "text/json";
context.Response.Write(CmdDir(target).ToString());
这里,每一次查询参数 dir 被作为缓存key。而不是什么把网站的所有可能用来输出的内容目录的文件列表都放到什么“缓存”中。 缓存单元应该是很小的、很细的,你一次要都写的是整个缓存单元中的全体数据而不是一丁点数据。如果你实际上是对所谓的“数据库表”去纠结什么缓存,如果你只是要读写数据表中的一丁点数据,那么你就适合使用内存数据库服务器架构,而不是缓存技术。
  • 打赏
  • 举报
回复
这节省的时间可以是相当可观的 --> 这多花出去的时间可以是相当可观的 内存数据库方式相比于缓存方式,慢几十倍。但是它简单,并且因为是纯内存的且无锁的机制,从而避免了关系数据库的数据库事务加锁的弊端,内存数据库通常比传统关系数据库又快几十倍。所以在你不是用缓存技术时,使用内存数据库技术,就是必然的。
  • 打赏
  • 举报
回复
上面其实有好几层楼都已经说过,在集群中,要更改缓存,那么就要从业务系统发出集群内的消息通知。从数据库的“增删改查”去考虑问题,总是最下游的外道技术,总是最耗费资源的懒惰方式。要从业务系统的代码中写上一两行代码去向集群发出通知,在保存数据到数据库之后立刻发出通知,这样就能通知其它服务器上的缓存系统立刻去更改类似上述“13998号订单最后更新时间”这样的缓存,从而级联地清除几百个缓存单元。 假设每一台服务器的每一次数据访问都要先到内存数据库服务器上去查询一次,然后在查不到的情况下再去查询后台数据库(然后再回填到内存数据库),相比于它每一次都只是访问本地、本进程内的.net cache机制,这节省的时间可以是相当可观的。因为我们都知道访问网络的时间跟访问本地内存的时间的比例关系! 假设你的缓存的命中率很低、经常刷新,而你又想提速,那么使用内存数据库技术是合适的。 另外,假设你觉得自己搞不定缓存依赖控制技术,你觉得它比较复杂,你宁可付出每一次数据读取时的网络代价、且单独架设一个内存数据库服务器,那么你使用内存数据库技术也是合适的。 所以不是说一定要使用缓存技术,你完全可以使用内存数据库技术,这可以减低学习和开发的要求。但是我们一定要将缓存技术根内存数据库技术区分开来,这样就能一眼就看穿两个编程技术的做法的区别。
  • 打赏
  • 举报
回复
redis、memorycached,以及其它内存数据库,都不是缓存。如果一个人比较客观地会去说“我用这个作为缓存”,而不会说这“就是”缓存。这个微妙的说法是有很大区别的。 你可以想象一下,假设有10台服务器,每一次访问某个数据都通过网络去访问这个内存数据库去查询数据,然后第一次查询失败时则会查询后台数据库并且把查询结果写到这个内存数据库上,这就意味着每一台服务器的每一个缓存数据查询都要付出网络代价。假设有一个服务器上改变了任何数据,除了要写到后台数据库,同时还要确保同时通过网络而将数据写到内存数据库。这跟缓存技术的的性能能比吗?这肯定不缓存技术的性能低很多很多。 但是为什么很多人把这个完全没有CacheDelendency技术的东西伪说成“缓存”呢?因为它不需要技术含量,其实是人都会懂,只是还有一些人懒得去找一两种开源的内存数据库系统来尝试。实际上对于喜欢实践的人,你可以不用缓存技术,而用一个共享的内存数据库,每一台服务器上每一次更新后台数据的时候都把数据再往这个内存数据库再写一份,而查询后台数据库之后也就把查询结果再往这个内存数据库再写一遍,在你不用缓存技术时你就可以使用内存数据库技术。
Poopaye 2016-06-29
  • 打赏
  • 举报
回复
我觉得你就不该从A读取数据 而是换成由A传送数据给B的缓存 这样才合理
  • 打赏
  • 举报
回复
引用 楼主 jmlovews 的回复:
现在B从A读数据的时候把数据存到了缓存,现在A系统及时加了条数据进去,B系统因为缓存没过去,导致新加的数据没显示出来。 这种情况一般如何处理呢?
正如楼上所说,缓存的 CacheDependency 中最低级的就是 Duration,但是你现在需要更高级的缓存依赖技术。 会不会设计缓存系统,不是像有些人扯什么“把数据放到内存里”这么简单的东西,更不是单独弄一个服务器上安装什么内存数据库然后就叫做缓存(内存数据库机制都是伪缓存,你付出了网络通讯的性能代价来访问一个内存数据库的数据而已),重点就在于了解设计“缓存依赖项”的技术。记住,缓存就是本机的甚至是当前进程的高速机制,而不是弄一台单机安装一个内存数据库。 .net 的 CacheDependency机制,默认的方式除了 SqlDependency,还可以根据磁盘文件、磁盘目录的改变而自动响应,还可以根据其它缓存单元的改变而级联触发,还可以你自定义一个CacheDepenency(只要你从CacheDendency类继承即可)。按说,只有了解最后一种自定义缓存依赖项的人,才真正叫做了解了缓存技术。不过我们可以仅仅用倒数第二种来看看。 假设你有一个缓存单元
cache.Insert("13998号订单最后更新时间", item);
那么你就可以将其他一些缓存数据与之关联,例如
cache.Insert(key, data, new CacheDependency(null, new string[]{"13998号订单最后更新时间"})); 
这样,当第一个缓存单元的数据改变的一刹那,第二个缓存单元(以及同样依赖“13998号订单”的其它几十个缓存单元)就自动清除了!你可以想象到,这种依赖是可以级联的。 那么现在就是你的A数据要广播消息的问题。不是说数据库只要一有改变就广播,数据库的改动只有万分之一、十万分之一的消息才需要广播。例如假设所有的订单改变都需要广播一下,那么就单独将这个信息广播一下。 最后回到前边关键的一个关键点,所谓“内存数据库”算是缓存吗?当你单独弄一个服务器然后安装一个内存数据库,你所有的数据都要写到这个内存数据库上,然后再每一此查询数据时先去通过网络查询一次这个内存数据库,如果查不到的话再去查询数据库系统,这算是缓存吗?这时候你根本没有缓存,许多人把这个叫做缓存,那是许多人(主要是使用 java 的 没有 .net cache技术的低级工具的人)在众口一词地在歪曲概念呢。 那根本不是缓存技术,就是普通的内存数据库,而已。
wanghui0380 2016-06-29
  • 打赏
  • 举报
回复
因为是两个系统,所以你需要有“通知”,就像现在的高考,那也是多个独立系统,所以他得有个“通知”给你 收到通知后就可以,主动更新缓存。 至于如何通知可以用滴东西就太多了。 当然加个中间件,公用一个缓存也成。不过这样你的系统改造就大了
大雨将至 2016-06-29
  • 打赏
  • 举报
回复
早晚会走上redis之路,不如现在就开练
我2我骄傲 2016-06-29
  • 打赏
  • 举报
回复
那这个缓存 可不能用 httpruntime.cache...
大雨将至 2016-06-29
  • 打赏
  • 举报
回复
改成分布式缓存,A和B都能连接,A中修改数据后同时更新缓存

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧