设为首页 收藏本站
查看: 1039|回复: 0

[经验分享] 由Memcached使用不当而引发性能问题的两个经验总结

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-8-31 12:36:38 | 显示全部楼层 |阅读模式
  在这个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无小事,否则一个疏忽就有可能造成生产环境发生悲剧乃至惨剧。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-106812-1-1.html 上篇帖子: 分析Memcached客户端如何把缓存数据分布到多个服务器上 下篇帖子: java客户端提交数据到memcached方法memcached+java+client个人总结
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表