- 浏览: 13988 次
最新评论
使用Memcached提高.net应用程序的性能
- 博客分类:
- 技术杂绘
使用Memcached提高.net应用程序的性能
2011年03月27日
如无特别说明,本博客文章为zhoufoxcn(周公)原创,任何外部引用或摘抄请注明出处,并保持内容和格式不变,未经作者同意不得用于任何盈利目的,对于非营利性转载不注明出处的保留追究法律责任的权力,谢谢合作!欢迎业内精英共同探讨交流,MSN(Email):zhoufoxcn⊙hotmail.com。
在应用程序运行的过程中总会有一些经常需要访问并且变化不频繁的数据,如果每次获取这些数据都需要从数据库或者外部文件系统中去读取,性能肯定会受到影响,所以通常的做法就是将这部分数据缓存起来,只要数据没有发生变化每次获取这些数据的时候直接从内存中区获取性能肯定会大大地提高。在.NET中提供了一个Cache类可以实现这些功能。在ASP.NET中可以通过HttpContext 对象的 Cache 属性或 Page 对象的 Cache 属性来获取这个类的实例。 在大部分情况下我们都可以使用Cache类来提高ASP.NET的性能,但是使用Cache类也有一些不足,比如我们不能指定Cache类所占用的内存的大小,此外在Cache中缓存的数据没有办法被另一台机器上的应用程序直接访问,因此在本文中提出另一种数据缓存方案,那就是使用分布式缓存。分布式缓存的特点是缓存的数据不必和应用程序在同一台机器上,从而大大增强了缓存数据的复用性。在本文介绍如何在.NET应用中使用Memcache作为分布式缓存。
Memcached介绍
Memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。在通常的应用中我们都会将数据保存到数据库中,每次需要的时候都会从数据库去查询这些数据,如果应用程序的用户很多就会出现大量并发访问数据库的情况,这样就会增加应用程序的响应时间,使用Memcached就可以有效解决这个问题。memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。像大名鼎鼎的Facebook网站就使用了Memcached。周公稍后会提供Windows平台上32位和64位的Memcached程序。
为了提高性能,Memcached中的数据都保存在Memcached内置的存储空间中。因为当Memcached重启会导致其中的数据全部丢失,所以一般的方案是将数据保存在数据库中,每次请求数据的时候先查看在Memcached有没有缓存,如果有就直接从缓存中取出数据;如果没有,就从数据库中取出数据返回给应用程序并将请求的数据缓存到Memcached中,这样一来下次请求相同的数据就可以直接从Memcached中读取而不用再去查数据库了;一旦对数据有更新,同时更新数据库和Memcached。
Memcached是一个命令行窗口程序,可以在命令行窗口中启动也可以封装在系统服务中启动。在启动Memcached时需要提供一些必须的参数,指定Memcached运行时监听的端口和最大使用的内存大小等。如果缓存的数据大小超过指定内存,那么Memcached就会按照LRU(Least Recently Used)算法自动"删除"不使用的缓存(标记为失效),新增的缓存数据就可以使用这些标记为失效的数据所占用的内存,这样就不用担心Memcached超出所指定内存的问题。此外,为了提高性能,在缓存数据过期后Memcached并不是从物理内存中删除缓存的数据,仅仅在取出改数据的时候检查它是否已经过了有效期。
目前有多种平台的Memcached版本,比如Linux、FreeBSD、Solaris (memcached 1.2.5以上版本)、Mac OS X及Windows平台,在Windows平台上还有32位和64位版本。
Memcached有一套协议,利用这套协议可以对Memcached进行数据存取和查看Memcached的状态,很多程序语言都依据这套协议来操作Memcached,比如PHP、Java、C、C++及C#等。
获取了对应平台的Memcached版本就可以运行Memcached了。在这里仅以Windows平台上的32位Memcached为例。
运行Memcached:
memcached.exe -p 11121 -m 64
上面的命令是运行Memcached,指定它的监听端口是11121(这是它的默认端口,可以指定为其它大于1024的端口,因为小于1024的端口已经有了默认指定),最大使用内存为64m,如果启用了Windows防火墙,切记要在防火墙上打开这个端口。
在调试程序时可以使用下面的命令行来运行:
memcached.exe -p 11121 -m 64 -vv
这样就会看到如下的结果:
slab class 1: chunk size 88 perslab 11915
slab class 2: chunk size 112 perslab 9362
slab class 3: chunk size 144 perslab 7281
slab class 4: chunk size 184 perslab 5698
slab class 5: chunk size 232 perslab 4519
slab class 6: chunk size 296 perslab 3542
slab class 7: chunk size 376 perslab 2788
slab class 8: chunk size 472 perslab 2221
slab class 9: chunk size 592 perslab 1771
slab class 10: chunk size 744 perslab 1409
slab class 11: chunk size 936 perslab 1120
slab class 12: chunk size 1176 perslab 891
slab class 13: chunk size 1472 perslab 712
slab class 14: chunk size 1840 perslab 569
slab class 15: chunk size 2304 perslab 455
slab class 16: chunk size 2880 perslab 364
slab class 17: chunk size 3600 perslab 291
slab class 18: chunk size 4504 perslab 232
slab class 19: chunk size 5632 perslab 186
slab class 20: chunk size 7040 perslab 148
slab class 21: chunk size 8800 perslab 119
slab class 22: chunk size 11000 perslab 95
slab class 23: chunk size 13752 perslab 76
slab class 24: chunk size 17192 perslab 60
slab class 25: chunk size 21496 perslab 48
slab class 26: chunk size 26872 perslab 39
slab class 27: chunk size 33592 perslab 31
slab class 28: chunk size 41992 perslab 24
slab class 29: chunk size 52496 perslab 19
slab class 30: chunk size 65624 perslab 15
slab class 31: chunk size 82032 perslab 12
slab class 32: chunk size 102544 perslab 10
slab class 33: chunk size 128184 perslab 8
slab class 34: chunk size 160232 perslab 6
slab class 35: chunk size 200296 perslab 5
slab class 36: chunk size 250376 perslab 4
slab class 37: chunk size 312976 perslab 3
slab class 38: chunk size 391224 perslab 2
slab class 39: chunk size 489032 perslab 2
点击"打开或关闭Windows功能"之后会看到当前系统启用的功能的状态,根据当前机器选择打开Telnet服务器端或者客户端功能,如下图所示:
经过上面的操作之后就可以在客服端远程查看Memcached的状态或者操作Memcached了。下面的命令就是连接到Memcached:
telnet localhost 11121
连接之后会出现一个命令行窗口,在这个命令行窗口中输入"stats"就可以看到当前Memcached的状态,如下就是刚刚启动的Memcached的状态数据:
STAT pid 852
STAT uptime 1399
STAT time 1300979378
STAT version 1.2.5
STAT pointer_size 32
STAT curr_items 0
STAT total_items 0
STAT bytes 0
STAT curr_connections 3
STAT total_connections 5
STAT connection_structures 4
STAT cmd_get 0
STAT cmd_set 0
STAT get_hits 0
STAT get_misses 0
STAT evictions 0
STAT bytes_read 23
STAT bytes_written 415
STAT limit_maxbytes 67108864
STAT threads 1
END
通过这个数据我们就可以了解Memcached的状态了。
这些数据所代表的意义如下:
pid:32u,服务器进程ID。
uptime:32u, 服务器运行时间,单位秒。
time :32u, 服务器当前的UNIX时间。
version :string, 服务器的版本号。
curr_items :32u, 服务器当前存储的内容数量 Current number of items stored by the server
total_items :32u, 服务器启动以来存储过的内容总数。
bytes :64u, 服务器当前存储内容所占用的字节数。
curr_connections :32u, 连接数量。
total_connections :32u, 服务器运行以来接受的连接总数。
connection_structures:32u, 服务器分配的连接结构的数量。
cmd_get :32u, 取回请求总数。
cmd_set :32u, 存储请求总数。
get_hits :32u, 请求成功的总次数。
get_misses :32u, 请求失败的总次数。
bytes_read :64u, 服务器从网络读取到的总字节数。
bytes_written :64u, 服务器向网络发送的总字节数。
limit_maxbytes :32u, 服务器在存储时被允许使用的字节总数。
上面的描述中32u和64u表示32位和64位无符号整数,string表示是string类型数据。
在.NET中应用Memcached
有很多.NET版本的Memcached客户端程序,在这里周公使用的Enyim Memcached,可以到https://github.com/enyim/EnyimMemcached/下载最新的版本。
要想在项目中使用Memcached,需要添加对Enyim.Caching.dll的应用。除此之外,我们可能还需要在config文件中配置Memcached的信息(也可以在程序代码中指定,但那样不灵活),如下就是一个config文件配置的例子: --> 如果我们配置了多个Memcached的实例,可以想上面的注释部分那样在节点下添加多个Memcached的实例配置。
这里需要说明的是如果我们需要向Memcached中添加自定义数据类型时,我们需要将该数据类型添加上[Serializable]标记。
下面是一个Enyim Memcached的例子: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Enyim.Caching; using Enyim.Caching.Memcached; /* * 作者:周公(zhoufoxcn) * 日期:2011-03-24 * 原文出处:http://blog.csdn.net/zhoufoxcn 或http://zhoufoxcn.blog.51cto.com * 版权说明:本文可以在保留原文出处的情况下使用于非商业用途,周公对此不作任何担保或承诺。 * */ namespace MemcachedMonitor { [Serializable] public class Person { public int UserId { get; set; } public string UserName { get; set; } } public class MemcachedDemo { private static MemcachedClient client = new MemcachedClient("enyim.com/memcached"); public void SetDemo() { Person person = new Person { UserId = 1, UserName = "李刚" }; //不带过期时间的存储,Memcached将根据LRU来决定过期策略 bool success=client.Store(StoreMode.Add, person.UserName, person); //带过期时间的缓存 //bool success = client.Store(StoreMode.Add, person.UserName, person, DateTime.Now.AddMinutes(10)); Console.WriteLine("存储[{0}]的结果:{1}", person.UserName, success); } public void GetDemo() { Person person = client.Get("李刚"); if (person != null) { Console.WriteLine("取回[{0}]的结果--UserId:{1},UserName:{2}", "李刚", person.UserId, person.UserName); } else { Console.WriteLine("取回[{0}]失败!", "李刚"); } } public void MultiGetDemo() { List personNameList = new List(); for (int i = 0; i 中的指定的所有数据 IDictionary resultList = client.Get(personNameList); Person person; foreach (KeyValuePair item in resultList) { person = item.Value as Person; if (person != null) { Console.WriteLine("取回[{0}]的结果--UserId:{1},UserName:{2}", "李刚", person.UserId, person.UserName); } else { Console.WriteLine("取回[{0}]失败!", "李刚"); } } } } } 说明:如果需要一次从Memcached中取回多个缓存的数据,可以参考MultiGetDemo()方法,这样一来只需要一次网络通讯就可以取回全部数据,减少网络连接时间。此外,在Memcached客户端可以使用Text或者Binary协议,经过周公千万次测试比较,使用Binary协议性能略高于使用Text协议。在上面的config文件中周公就配置使用了Binary协议。
总结,使用Memcached这样的分布式缓存可以大大提高应用程序的性能,经过周公测试,正确使用Memcached可以将单台服务器的并发访问数从20提高到1000左右,也就是提高了50倍,这是一个相当客观的提升!限于篇幅,关于Memcached的更深更详细的用法没有在本篇介绍,此文算作抛砖引玉,读者可以自行参考其它相关资料。
周公
2011-03-25
发表评论
-
linux 笔记
2012-01-20 02:12 681linux 笔记 2010年10月31日 ... -
ptrace源代码分析
2012-01-20 02:12 1684ptrace源代码分析 2011年01月04日 ptra ... -
MMS-MTK-Obigo03c
2012-01-20 02:12 1273MMS-MTK-Obigo03c 2011年02月2 ... -
Borland 基础与应用开发课程认证试题整理集
2012-01-20 02:12 650Borland 基础与应用开发课程认证试题整理集 2010年 ... -
2012-1-8
2012-01-19 10:02 5752012-1-8 2012年01月08日 ... -
暧昧的女人
2012-01-19 10:02 636暧昧的女人 2012年01月13日 暧昧 ... -
2012-1-16
2012-01-19 10:02 5152012-1-16 2012年01月16日 ... -
■反击关于盗墓一点也不腐つ
2012-01-19 10:02 550■反击关于盗墓一点也不腐つ 2012年01月07日 首先 ... -
2011-12-27
2012-01-19 10:02 6002011-12-27 2011年12月27日 亭亭玉立婀 ... -
程序人生--一个程序员对学弟学妹建议
2012-01-17 02:43 613程序人生--一个程序员对学弟学妹建议 2011年01月27日 ... -
vs2008安装boost
2012-01-17 02:43 645vs2008安装boost 2010年11月27日 ... -
关于网络
2012-01-17 02:43 515关于网络 2011年04月20日 ... -
C++学到怎么样的程度才算是达标?
2012-01-17 02:43 962C++学到怎么样的程度才 ... -
程序员是怎样炼成的(抄袭微博文章)
2012-01-17 02:43 462程序员是怎样炼成的(抄 ... -
AS3处理对象
2012-01-15 22:19 550AS3处理对象 2009年07月14日 属性 属性 ... -
as3 正则表达式
2012-01-15 22:19 595as3 正则表达式 2009年10月04日 /\scom ... -
AS3正则与js正则中反向引用
2012-01-15 22:19 674AS3正则与js正则中反向引用 2010年09月29日 ... -
常用数字正则表达式
2012-01-15 22:18 800常用数字正则表达式 20 ... -
常用正则表达式
2012-01-15 22:18 567常用正则表达式 2010年04月17日 常用数字正则表达 ...
相关推荐
8.2.2 创建ASP.NET Ajax应用程序 333 8.2.3 ScriptManager控件使用技巧 335 8.2.4 UpdaetPanel控件使用技巧 336 8.2.5 AsyncPostBackTrigger实现 外部控件引发局部刷新 338 8.2.6 Ajax错误处理 341 8.2.7 告诉用户...
8.2.2 创建ASP.NET Ajax应用程序 333 8.2.3 ScriptManager控件使用技巧 335 8.2.4 UpdaetPanel控件使用技巧 336 8.2.5 AsyncPostBackTrigger实现 外部控件引发局部刷新 338 8.2.6 Ajax错误处理 341 8.2.7 告诉用户...
《决战Nginx系统卷:高性能Web服务器详解与运维》第一部分首先讲述了Nginx服务器的功能、模块管理和进程管理,然后讲述Nginx如何...另外,本书详细讲述了应用程序服务器的缓存技术,特别是对Memcached服务器的应用。
《决战Nginx系统卷:高性能Web服务器详解与运维》第一部分首先讲述了Nginx服务器的功能、模块管理和进程管理,然后讲述Nginx如何...另外,本书详细讲述了应用程序服务器的缓存技术,特别是对Memcached服务器的应用。
为 ASP.NET Core(2.0 及更高版本)应用程序提供存储服务。 用于抽象缓存功能的小型库。 任何缓存提供程序的快速设置和广泛使用的提供程序的非常简单的包装器。 LiteX Cache 使用受支持的提供程序之间功能的最小公...
实战Nginx:取代Apache的高性能Web服务器 作者: 张宴 出版社: 电子工业出版社 出版年: 2010年2月 内容简介 Nginx (“engine x”) 是俄罗斯人Igor Sysoev编写的一款高性能HTTP 和反向代理服务器。Nginx选择了...
取代Apache的高性能Web服务器 电子工业出版社 319页 第1部分 基础篇 第1章 Nginx简介 1.1 常用的Web服务器简介 1.2 Nginx简介 1.3 选择Nginx的理由 1.4 Nginx与Apache、Lighttpd的综合对比 第2章 Nginx服务器...
张宴《实战Nginx:取代Apache的高性能Web服务器》pdf电子版下载,此资料网友共享,请购买作者正版书籍. 目录介绍: 第1部分 基础篇 第1章 Nginx简介 1.1 常用的Web服务器简介 1.2 Nginx简介 1.3 选择Nginx的理由 ...
Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...
Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...
4.1 获取相关开源程序 4.2 安装PHP 5.2.10( FastCGI模式) 4.3 安装Nginx 0.8.15 4.4 配置开机自动启动Nginx+PHP 4.5 优化Linux内核参数 4.6 在不停止Nginx服务的情况下平滑变更Nginx配置 4.7 编写每天定时切割...