`
njs458sd
  • 浏览: 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
分享到:
评论

相关推荐

    亮剑.NET深入体验与实战精要2

    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 告诉用户...

    亮剑.NET深入体验与实战精要3

    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服务器详解与运维.z01

    《决战Nginx系统卷:高性能Web服务器详解与运维》第一部分首先讲述了Nginx服务器的功能、模块管理和进程管理,然后讲述Nginx如何...另外,本书详细讲述了应用程序服务器的缓存技术,特别是对Memcached服务器的应用。

    决战Nginx: 系统卷 - 高性能Web服务器详解与运维.zip

    《决战Nginx系统卷:高性能Web服务器详解与运维》第一部分首先讲述了Nginx服务器的功能、模块管理和进程管理,然后讲述Nginx如何...另外,本书详细讲述了应用程序服务器的缓存技术,特别是对Memcached服务器的应用。

    LiteXCache:LiteXCache 是一种简单而强大的高性能缓存机制,将同步和异步用法与一些高级缓存用法相结合,可以帮助我们更轻松地处理缓存!

    为 ASP.NET Core(2.0 及更高版本)应用程序提供存储服务。 用于抽象缓存功能的小型库。 任何缓存提供程序的快速设置和广泛使用的提供程序的非常简单的包装器。 LiteX Cache 使用受支持的提供程序之间功能的最小公...

    实战Nginx:取代Apache的高性能Web服务器

    实战Nginx:取代Apache的高性能Web服务器 作者: 张宴 出版社: 电子工业出版社 出版年: 2010年2月 内容简介  Nginx (“engine x”) 是俄罗斯人Igor Sysoev编写的一款高性能HTTP 和反向代理服务器。Nginx选择了...

    实战Nginx.取代Apache的高性能Web服务器

    取代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服务器 第一章

    张宴《实战Nginx:取代Apache的高性能Web服务器》pdf电子版下载,此资料网友共享,请购买作者正版书籍. 目录介绍: 第1部分 基础篇 第1章 Nginx简介 1.1 常用的Web服务器简介 1.2 Nginx简介 1.3 选择Nginx的理由 ...

    JAVA上百实例源码以及开源项目

     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...

    JAVA上百实例源码以及开源项目源代码

     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...

    实战nginx-张宴

    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 编写每天定时切割...

Global site tag (gtag.js) - Google Analytics