由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文件 ...
随机推荐
- 表格制作模块xlwt
import xlwtworkbook = xlwt.Workbook(encoding = 'ascii') #创建workbook 括号内容视情况而定sheetname = 'Sheet'book ...
- 使用sessionStorage、localStorage存储数组与对象(转)
http://my.oschina.net/crazymus/blog/371757 使用sessionStorage.localStorage存储数组与对象 发表于3个月前(2015-01-26 1 ...
- Python全栈之路---运算符与基本的数据结构
运算符 一.算术运算符: 练习: + 加法 两个对象相加 1 + 2得到3:'a' + 'b'得到'ab'. - 减法 一个数减去另一个数或者是负数 5 - 3得到2:-2得到一个负数 * 乘法 两个 ...
- 企业项目如何打包成.ipa文件
首先准备好企业的项目,真机和申请好的正式证书,关于企业证书的申请此处不再写,可以参考网上相关的教程,本人并未参与证书申请,所以此处不敢乱写. 1.找到正式证书与描述文件,双击打开(需要密码,这个要问申 ...
- 彻底了解android中的内部存储与外部存储
我们先来考虑这样一个问题: 打开手机设置,选择应用管理,选择任意一个App,然后你会看到两个按钮,一个是清除缓存,另一个是清除数据,那么当我们点击清除缓存的时候清除的是哪里的数据?当我们点击清除数据的 ...
- 选择合适的String拼接方法(这篇博客是我抄的)
package com.test; public class FreeFile { public static void main(String[] args) { // 加号拼接 String st ...
- 高频交易策略[z]
Market Order以最高速下市价单(market order)是买方最基本的策略 Looking for Price Discrepancies 这个就是高频统计套利(high frequenc ...
- redis 内存泄露
http://www.oschina.net/question/2266476_246221 http://stackoverflow.com/questions/24304212/how-to-de ...
- [Python] 关于64位机的numpy安装问题
最近刚换成64位的系统,重新安装了win10,VS也从原来的2010变为了现在的2013. 利用原来32位电脑硬盘里的python2.7安装包安装,然后打算安装numpy. 上来碰到问题:在windo ...
- 进程调度算法Linux进程调度算法
这次介绍一下操作系统的进程调度算法 操作系统的调度分为三种:1.远程调度(创建新进程):2.中程调度(交换功能的一部分):3.短程调度(下次执行哪个进程) 这次讲述的就是短程调度,可以简单的看作咱们平 ...