缓存其实很早就了解了,并不是说做什么项目才认识它的。
谈到缓存,我们常常有这样的体验:当网速不好时,我们初次打开某个网页用时2s的话,再次打开它时可能0.5s就够了。这就是应用了缓存。
缓存,就是数据交换的缓冲区。我们知道,我们存取数据都要通过I/O操作,而计算机短时间内进行大量的数据处理的话,也就不得不伴随着频繁而快速的I/O操作,硬盘就要飞速的旋转。这样不仅对硬件有损,也对效率影响很大。
于是,人们就发明了缓存技术。
一、缓存
缓存是用来避免频繁的到数据库或磁盘文件获取数据而建立的一个快速临时存储器。一般来说,缓存比数据库或磁盘容量更小,但是存取速度非常快。内存是当前技术下相对廉价且有效的缓存介质。内存价格低廉,但是存取速度是一般磁盘I/O无法比拟的。
缓存有以下几点作用:
1、临时存储频繁访问的数据;
2、减少CPU与磁盘的数据交互;
3、提高读写数据速度;
4、Web缓存还能帮助减少网络流量、降低延迟、减轻远程服务器负载等。
缓存的缺陷(主要指Web下):
1、客户通过代理获取的可能是过时的内容。
2、如果发生缓存失效,客户的访问延迟由于额外的代理处理开销而增加。因此在设计Web缓存系统时,应力求做到Cache命中率最大化和失效代价最小化。
3、代理可能成为瓶颈。因此应为一个代理设定一个服务客户数量上限及一个服务效率下限,使得一个代理系统
的效率至少同客户直接和远程服务器相连的效率一样。
4、缓存掉电丢失。制造商们已经有了解决方案:掉电时,磁头会借助惯性将缓存中的数据写入零磁道以外的暂存区域,等到下次启动时再将这些数据写入目的地。另外,我们还可以把缓存临时写入数据库或日志中,掉电后就不会丢失了。
二、分布式缓存
我们现在使用的是分布式缓存Memcached,接下来主要说说它吧。
先问问大家什么是分布式缓存?
分布式缓存系统是为了解决数据库服务器和Web服务器之间的瓶颈。如果一个网站的流量很大,这个瓶颈将会非常明显,每次数据库查询耗费的时间将会非常可观。
对于更新速度不是很快的网站,我们可以用静态化来避免过多的数据库查询。对于更新速度以秒计的网站,静态化也不会太理想,可以用缓存系统来构建。如果只是单台服务器用作缓存,问题不会太复杂,如果有多台服务器用作缓存,就要考虑缓存服务器的负载均衡。
分布式缓存应用方式:
1、按应用切分数据到不同的缓存服务器,即每个系统一个Memcached。
2、按照某种规则(hash,路由等)把数据存储到不同的缓存服务器。
3、代理模式,应用在获取数据的时候都由代理透明的处理,缓存机制有代理服务器来处理。 (比较安全) 可采用 Magent 缓存代理。
Memcached是分布式缓存的一种实现方式,来看看它的优缺点:
优点:1、它支持分布式扩展,内存可以无限制扩大;
2、使用简单,可以在客户端直接设置多个Memcached 服务器。
不足:1、数据是保存在内存当中的,掉电会全部丢失。对策:可以增加定期写入硬盘的功能。
2、Memcached以root权限运行,而且Memcached本身没有任何权限管理和认证功能,安全性不足。对策:可以将Memcached服务绑定在内网IP上,通过防火墙进行防护。
最后我们来看一个.Net MVC下的Memcached实现:
using Memcached.ClientLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace memcachedDemo.Controllers
{
public class HomeController : Controller
{
public void Memcache() {//,
//添加多个缓存服务器地址
string[] serverlist = { "192.168.00.000:11211","192.168.11.111:11211" };
//初始化池
SockIOPool pool = SockIOPool.GetInstance();
pool.SetServers(serverlist);
//设置memcached 的一些参数
pool.InitConnections = 3;
pool.MinConnections = 3;
pool.MaxConnections = 5;
pool.SocketConnectTimeout = 1000;
pool.SocketTimeout = 3000;
pool.MaintenanceSleep = 30;
pool.Failover = true;
pool.Nagle = false;
pool.Initialize();
// 获得客户端实例
MemcachedClient mc = new MemcachedClient();
mc.EnableCompression = false;
Console.WriteLine("下面是一个测试");
bool flags1 = mc.Set("user1", "my value"); //存储数据到缓存服务器,这里将字符串"my value"缓存,key 是"test"
if (mc.KeyExists("user1")) //测试缓存存在key为test的项目
{
Console.WriteLine("test is Exists");
Console.WriteLine(mc.Get("user1").ToString()); //在缓存中获取key为test的项目
}
else
{
Console.WriteLine("test not Exists");
}
// Console.ReadLine();
bool flag = mc.Delete("user1"); //移除缓存中key为test的项目
if (mc.KeyExists("user1"))
{
Console.WriteLine("test is Exists");
Console.WriteLine(mc.Get("user1").ToString());
}
else
{
Console.WriteLine("test not Exists");
}
SockIOPool.GetInstance().Shutdown(); //关闭池, 关闭sockets
Console.ReadLine();
}
//
// GET: /Home/
public ActionResult Index()
{
Memcache();
return View();
}
}
Memcached作为基础而重要的技术,在今后的系统开发中肯定会经常用到。虽然在系统中的应用还没有自己实现过,不过有了上面的基础,真正实现也不会有什么大的困难了。