由Memcached使用不当而引发性能问题的两个经验总结
在这个cache everywhere的时代,在这个人人都会说分布式缓存的时代,Memcached几乎已成为网站开发中的标配。
作为一名普通的coder,我们在编写缓存代码的时候,很多情况下可能都只是了解其基本原理,知道如何调用API,知道大概怎么work around,然后测试通过上线,通常这样做还真不会出事。
然而看到这几天评论猛烈的雄文因为所谓的代码性能不高而被离职的程序员及其回帖,以及之前公司内部培训发现竟然有很多人不知道framework的缓存是天生的Thread Safe,实在忍不住,抛开非技术话题,也不讨论代码可读性,就说说Memcached缓存的使用,用好用对其实并不容易,而且说不定就会有隐藏问题,真的太有总结的必要了。
1、key-value的限制
缓存的key有长度限制,key的组成有特定字符的限制。
缓存的value必须可以序列化,且缓存的单一value容量有大小限制,对于可序列化的value,应该想方设法尽量规避某些特定数据结构,比如Hashtable,DataTable这些内部其实非常非常之复杂的数据结构。对于读频繁的操作来说,每次序列化和反序列化复杂数据结构的开销可想而知。
如果连分布式缓存的key和value(尤其是value)的一般限制都搞错了,那么使用缓存的后果很可能只是白白增加了网络IO及序列化、反序列化的开销,对系统性能提升当然是巨大的反作用。
2、小心Memcached的.net客户端的误用
这一点隐藏的也比较深,下面以应用广泛的EnyimMemcached为例来简单说明。
通常我们使用的客户端每次实例化MemcachedClient对象内部都会初始化一个客户端对象池(TCP连接池,客户端命名为ServerPool)。所谓TCP连接池就是将创建好的TCP连接(连接数通常按照配置来,生产环境的配置不会小于两位数)初始化放在容器内,客户端调用的时候可以直接拿出已经存在的TCP连接来用,这样可以省去实时打开TCP连接的开销。
因为有人喜欢using一下(当然包括楼主自己了),一看到MemcachedClient是继承自IDisposable的,必须用using啊,然后就要new一个MemcachedClient对象,这样客户端内部也就不得不再初始化一个TCP连接池。如果某个使用缓存的服务方法调用频繁,很快你就会发现系统CPU飙升,页面打开速度奇慢,直至不能正常访问。
我们知道,分布式缓存系统都有一个TCP连接上限的设置,无论如何,超过这个上限都有可能引发连环反应,这种反应毫无疑问是不良副作用。
所以如果我们误用MemcachedClient,每次都new一个对象,那么高并发情况下效果就非常惨了,一方面web服务器因为TCP连接过多无法正常访问,另一方面Memcached服务器也因为连接太多负载过重而性能变得极差,依赖Memcached的服务很可能短时间内只接收到超时响应。
解决方案无比简单,配置合适的TCP连接数,MemcachedClient对象单例即可。
最后还要重申选择使用缓存的业务场景的重要性。这一点真的无法说透,但是根据一些已有经验,可以提炼出两条比较通用的缓存准则:
1、写频繁的数据不适合缓存;
2、读频繁而写不频繁的数据适合缓存。
果然正确的话都是废话,上面两条等于没说。
怕你们说无聊,还是要奉献两条自己使用缓存的主要准则,当然只是自己一家之言经验之谈,不可全信,切记,否则被总监劝退老子概不负责:
1、适合缓存的数据通常应该对外公开供(所有)人调用,私有的数据缓存多数情况下是没有意义的;
2、对准确性、实时性、安全性等要求极高的业务数据,你的数据可能不适合缓存。
顺带再提一下web开发中的性能问题。据说如果一个网站有性能问题,那么它一定会出现性能问题。数据库、缓存、消息队列、各种框架、com组件等等等等,这些web开发中的标配,有哪个使用不当不会引发系统的性能问题呢?甚至大家习以为常的拼接字符串在特定条件下都会造成系统崩溃。我们也知道生产环境就像国际政治一样错综复杂波谲云诡,测试环境、UAT环境通过并不能保证系统诸事无虞,应该时刻认识到coding无小事,否则一个疏忽就有可能造成生产环境发生悲剧乃至惨剧。
由Memcached使用不当而引发性能问题的两个经验总结的更多相关文章
- SQLServer 2012异常问题(二)--由安装介质引发性能问题
原文:SQLServer 2012异常问题(二)--由安装介质引发性能问题 问题描述:生产环境一个数据库从SQLSERVER 2008 R2升级到SQLSERVER 2012 ,同时更换硬件,但迁移后 ...
- 使用Memcached改进Java企业级应用性能:架构和设置
Memcached由Danga Interactive开发.用来提升LiveJournal.com站点性能. Memcached分布式架构支持众多的社交网络应用,Twitter.Facebook还有W ...
- [网站日志]当Memcached缓存服务挂掉时性能监视器中的表现
我们用的Memcached缓存服务是阿里云OCS,今天晚上遇到了一次OCS挂掉的情况(计划中的升级),看一下性能监视器中的表现,也许对分析黑色1秒问题有帮助. 应用日志中错误: 2014-06-05 ...
- JAVA 程序发布引发性能抖动
发布或重启线上服务时抖动问题解决方案 一.问题描述 在发布或重启某线上某服务时(jetty8作为服务器),常常发现有些机器的load会飙到非常高(高达70),并持续较长一段时间(5分钟)后 ...
- Oracle 与 PostgreSQL 函数行为的差异引发性能差异
对于Oracle,对于数据修改的操作通过存储过程处理,而对于函数一般不进行数据修改操作.同时,函数可以通过 Select 进行调用,而存储过程则不行. 一.对于volatile 函数的行为 1.Ora ...
- MySQL性能优化的20条经验
今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我 们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数 ...
- MySQL性能优化的20+条经验
1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的.当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一 ...
- 新产品为了效果,做的比較炫,用了非常多的图片和JS,所曾经端的性能是非常大的问题,分篇记录前端性能优化的一些小经验。
第一篇:HTTPserver 因tomcat处理静态资源的速度比較慢,所以首先想到的就是把全部静态资源(JS,CSS,image,swf) 提到单独的server,用更加高速的HTTPserver,这 ...
- 对于Web性能优化, 了解和经验
我们在发布项目之前压缩CSS和JavaScript源代码,这样文件体积就变小了,用户加载必要资源所花的时间也就更短了. 压缩源码和图片 JavaScript文件源代码可以采用混淆压缩的方式,CSS文件 ...
随机推荐
- 关于C#不同位数相与或,或赋值时,隐藏位数扩展该留意的问题
__int64 a; char b; a = b; a |= b; 如上情况,当b的最高位为1时,即b=0x80(或更大)时,b在扩展成64过程中会将最高位向高位扩展变成0xfffffffffffff ...
- centos安装mysql5.6的正确姿态
1.准备工作 a)卸载centos默认软件 yum remove mariadb-libs-5.5.35-3.el7.x86_64 b)安装依赖包 yum install -y perl-Module ...
- C# 根据包含文件的路径和文件的名称的字符串获取文件名称的几种方法
C# 截取带路径的文件名字,扩展名,等等 的几种方法 C#对磁盘IO操作的时候,经常会用到这些,路径,文件,文件名字,文件扩展名. 之前,经常用切割字符串来实现, 可是经常会弄错. 尤其是启始位置,多 ...
- 用window.showModelDialog() 打开的页面的返回值
有两个页面也个 Default1.aspx 另外一个是 Default2.aspx Default1.aspx 有个按钮是用来打开Default2.aspx页面的 按钮的js代码是 var win ...
- C语课设心得分享(三)
调试. 以前咱们写课后习题,一般也不需要使用调试,如果程序编译error,根据错误信息就可以改好:如果是结果错误,那么在稿纸上过几遍基本也可以得出结果. 但咱们这个课设比较大,就需要很多调试的过程,尤 ...
- CSS3样式问题
empty-cells 属性设置是否显示表格中的空单元格 tr:nth-child(even)偶数行的表格 li:nth-child(20)指定位置 2016-09-2813:23:45
- 获取WINDOW.OPEN url js中的get取值
function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)( ...
- sbt的assembly插件使用(打包所有依赖)
1.sbt是什么 对于sbt 我也是小白, 为了搞spark看了一下scala,学习scala时指定的构建工具就是sbt(因为sbt也是用scala开发的嘛),起初在我眼里就是一个maven(虽然ma ...
- mesos框架编译部署
mesos是什么呢? 一个分布式调度框架,让你编写代码时面对整个集群像面对一台机器那么简单.所有的运行,资源调度都可以由它来帮你搞掂. 1.mesos安装有两种方式: 1)参考官网的getstart, ...
- Python:print显示颜色
显示颜色格式:\033[显示方式;字体色;背景色m......[\033[0m] ------------------------------------------- --------------- ...