Asp.Net缓存
概念:
缓存是系统或应用程序将频繁使用的数据保存到中间存储介质的方案,中间介质位于应用程序和数据源之间,与原来的应用程序直接和数据源进行交互相比,中间介质能够使应用程序更快的获取数据,
分类:
1.数据缓存
2.页面缓存
特点:
1.线程安全
2.可以设置缓存优先级
当内存不足或紧张时Asp.Net会根据优先级自动删除缓存
3.可以设置过期时间
缓存将根据过期时间自动删除
4.可以设置缓存依赖
当数据源发生改变的时候,对应的缓存将自动删除
添加缓存:
1.Item属性的Set访问器
缓存项是通过键值对的形式存入Cache中的,键为字符串类型,值为Object类型,Item是一个索引器属性,通过这种方法添加缓存,如果在添加之前有旧的缓存,新缓存将覆盖,否则将创建新的缓存,并且只能指定键和值,其它属性为默认值,也就是优先级为Normal,过期时间为无限,缓存依赖为null。
Cache[“MyCache”]=ObjectValue;
2.Add方法
通过此方式可以控制Cached的所有属性,但是如果原来有相同键的缓存,此方法将无效。
3.Insert方法
此方法有4个重载,比Add方法更加灵活,不同的是如果原来有相同键的缓存,此方法将覆盖旧的缓存。
移除缓存:
1.过期时间无效时自动移除
2.内存紧张时系统自动移除级别低的缓存
3.依赖对象变化时自动移除
4.Remove方法编程移除
缓存依赖:
缓存依赖是为了解决当数据源发生变化时,将对应的缓存项删除的一种机制。主要分为文件缓存依赖和数据库缓存依赖。
文件缓存依赖就是当文件的内容发生改变时,将对应的缓存项删除。
CacheDePendency cdp = new CacheDePendency(“文件全名/文件夹全名”);
如果为文件夹全名,缓存依赖只监听该文件夹内的文件和文件夹得变化,对于子文件夹内的变化不会监听。
数据库缓存依赖分为“拉”和“推”两种方式,“拉”的方式是在SQL Server 2005以前,才用的一种轮询方式,“推”的方式是SQL Server 2005及以后的数据库通知技术。
在SQL Server 2005以前,数据库的缓存依赖通常采用的是数据轮询的一种机制达到目的,它的主要思想是:在要被监听的数据库中建立一些表,这些表记录被监听表的变化,Asp.Net保持打开一个数据库连接,并使用一个专门的线程定期检查这些表的记录,查看是否有更新,从而控制缓存项的生命周期,这种方式使用起来比较麻烦,并且不能及时得到新的数据,它只能在一定时间内得到新数据,而且还要一个独立的线程负责这项工作,就好像不会报警的“热得快”一样,在插上电烧水的时候,你不知道水在什么时候开,所以你不得不一会儿去看一看水开了没有,这就是所谓的“拉”方式,很显然这种技术性能并不是很高,但是毕竟能满足一些需求。而且微软在这方面也做了一些工作,使得我们用起来也不像想象中的那么麻烦(虽然它很麻烦),我们只需要做一下几步就能完成这项看似很复杂的工作。
1.使用aspnet_resql.exe启动数据库通知,其实也就是创建一些表监听很多表的变化,还有一些触发器和存储过程,当表变化时,自动记录。
Aspnet_resql -ed -E -d 数据库名称
Aspnet_resql -et -E -d 数据库名 -t 表名
2.配置Asp.Net是它启用一个专门的线程检查表的变化
<!-- caching section group -->
<caching>
<sqlCacheDependency enabled = "true" pollTime = "1000" > //通过pollTime 的设置,定时拉数据库的修改
<databases>
<add name="Northwind"
connectionStringName="NorthwindConnectionString1"
pollTime = "1000"
/>
</databases>
</sqlCacheDependency>
</caching>
3.创建缓存依赖
SqlCacheDependency scdp = new SqlCacheDependency(“数据库名”,”表名”);
在SQL Server 2005有了真正的通知机制,通知基础结构以消息系统的模式内建在数据库里叫做服务器代理,而且.Net和ADO.Net提供了一个模型,使你只需要一个查询命令,它就会告诉服务器代理,让服务器代理为影响这个查询结果担当通知者,一旦有操作影响到该查询结果,服务器代理就会向.Net发送一条消息并取消通知者角色,.Net收到消息后就会删除相应的缓存项,这种机制使得数据变化能够及时的得到通知等等好多优点,而且在微软的工作之上我们只需简单的几步就能达到目的。
1.为数据库启用通知
Alter database 数据库名 set enable_broker
2.创建缓存依赖
SqlCacheDependency acdp = new SqlCacheDependency(查询命令);
分布式缓存:
分布式缓存是缓存项不单单存储在本地计算机内存中,而使缓存存储到其它的多个计算机内存的一种技术,该技术完全抛弃了Asp.Net内置的缓存机制。
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。但是它并不提供冗余(例如,复制其hashmap条目);当某个服务器S停止运行或崩溃了,所有存放在S上的键/值对都将丢失。
Memcached的使用方法(引用地址http://www.cnblogs.com/luyinghuai/archive/2008/08/28/1278200.html)
服务的启动:
1, 将memcached-1.2.1-win32.zip解决到指定的地方,如c:\memcached
2, 命令行输入 'c:\memcached\memcached.exe -d install'
3, 命令行输入 'c:\memcached\memcached.exe -d start' ,该命令启动 Memcached,默认监听端口为 11211
可以通过 memcached.exe -h 可以查看其帮助
第一步:配置config文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="enyim.com">
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</sectionGroup>
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</configSections>
<enyim.com>
<memcached>
<servers>
<!-- put your own server(s) here-->
<add address="127.0.0.1" port="11211" />
</servers>
<socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</enyim.com>
<memcached keyTransformer="Enyim.Caching.TigerHashTransformer, Enyim.Caching">
<servers>
<add address="127.0.0.1" port="11211" />
</servers>
<socketPool minPoolSize="2" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</configuration>
这里的port:11211是, memcached-1.2.1-win32在安装时默认使用的port.当然你可以用memcached.exe -p 端口号来自行设置。
第二步, 新建TestMemcachedApp的console project
引用Enyim.Caching.dll或者在solution中加入这个project(可以下载的代码中找到)。
using System;
using System.Collections.Generic;
using System.Text;
using Enyim.Caching;
using Enyim.Caching.Memcached;
using System.Net;
using Enyim.Caching.Configuration;
namespace DemoApp
{
class Program
{
static void Main(string[] args)
{
// create a MemcachedClient
// in your application you can cache the client in a static variable or just recreate it every time
MemcachedClient mc = new MemcachedClient();
// store a string in the cache
mc.Store(StoreMode.Set, "MyKey", "Hello World");
// retrieve the item from the cache
Console.WriteLine(mc.Get("MyKey"));
// store some other items
mc.Store(StoreMode.Set, "D1", 1234L);
mc.Store(StoreMode.Set, "D2", DateTime.Now);
mc.Store(StoreMode.Set, "D3", true);
mc.Store(StoreMode.Set, "D4", new Product());
mc.Store(StoreMode.Set, "D5", new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
Console.WriteLine("D1: {0}", mc.Get("D1"));
Console.WriteLine("D2: {0}", mc.Get("D2"));
Console.WriteLine("D3: {0}", mc.Get("D3"));
Console.WriteLine("D4: {0}", mc.Get("D4"));
byte[] tmp = mc.Get<byte[]>("D5");
// delete them from the cache
mc.Remove("D1");
mc.Remove("D2");
mc.Remove("D3");
mc.Remove("D4");
// add an item which is valid for 10 mins
mc.Store(StoreMode.Set, "D4", new Product(), new TimeSpan(0, 10, 0));
Console.ReadLine();
}
// objects must be serializable to be able to store them in the cache
[Serializable]
class Product
{
public double Price = 1.24;
public string Name = "Mineral Water";
public override string ToString()
{
return String.Format("Product {{{0}: {1}}}", this.Name, this.Price);
}
}
}
}