想起来几年前挺火的前岛国国民女神学霸-小岛方晴子。当时替她说话的人都很惨,导师被逼自杀。她收到的压力侮辱不是常人能够想象的。可是她却坚强的活着,去年还出了书。我去日本的时候,下了新干线,前面有一群女学生,她们看到我了,马上汇集成一团,一边看我一边说悄悄话。我才发现日本人穿的衣服基本就是黑,白,灰。他们也不穿羽绒服,女孩子大冬天都是光着腿。而我穿着黄绿色的羽绒服,确实像个怪胎。为何来以前没人告诉我[大哭][大哭]。8年过去了,想起来还以为尴尬。日本人是很爱背后说别人坏话的。因此我感谢我是个很普通的女孩子,并且生在中国。没人闲的没事去扒我以前作过的坏事。好比我好久前看不惯一个本身没能力还势利的混蛋,因此写了个程序刷爆了他的邮箱。再好比我本身写了个小程序循环注册一个网站参加抽奖,得了好多小东西。html
可是女孩子天生就是很坚强的,女孩子为爱而活,其余的什么都扛的下。写《傲慢与偏见》的女做家简.奥斯汀,你们看到她写的书的女主角们大概都能想象到做者本人是个聪明,智慧,本身漂亮且有一个更漂亮的姐姐,又很幽默的女孩。可是她却在本身心爱的男孩子傍了个富婆以后终生未嫁,高富帅向她求婚她没赞成。一辈子寄人篱下,与恋人死去不肯作他人妇的姐姐相依为命,心中的痛苦又与谁人说。30多岁开始患有严重的忧郁症,直到她得知本身心爱的男孩去世的消息,本身也郁郁而终。感恩本身运气好,能够快快乐乐作个普通人。mysql
本文首发于静儿1986的博客,原文地址是http://www.cnblogs.com/xiexj/p/6897806.html。redis
咱们部门并发量最大的接口服务前段时间发生了几回业务端的流量猛增,扛不住的状况。瓶颈在缓存上。根本性的改造正在进行中。谈一谈这段时间由这个问题引起的思考。算法
首先说以前的架构确实很老了,如今直接负责这个服务的男神哥哥也很年轻,有问题是正常的。缓存选用的是乐视统一的couchbase集群,是个memcached升级版,已经实现了持久化,本质是一个文档型的数据库,有人评价其性能要超过mongoDB。而后乐视网封装了它,本身起名叫cbase,前面用moxi代理。实际上使用以为其性能让人擦汗。 sql
接口服务将数据库里的全量视频和专辑刷入缓存。缓存扛不住了都不会穿透DB。这里我只想说:若是我们要是发现数据库可能要雪崩,作熔断,作隔离都是可取的。可是彻底不用,要它做甚[汗]. 媒资接口是一个多维度的查询服务,缓存直接当DB用,而这个缓存的结构对数据的计算是很不利的。从数据库里取数据耗时通常也就是几ms。从缓存中取数据量级并无减小,还会过量使用缓存形成cbase集群的高负载。并且mysql是有本身的缓存的,查询一点儿都不慢,加上索引,线上已经有的读写分离,其余成熟的技术,性能也不差。业务复杂性大大增长,业务处理的CPU计算量大大增长,实际性的缓存的高速也微乎其微。数据库
话说到此,先比较一下mysql和memcached。小程序
以前广泛的理解是关系型数据库自身庞大,处理过程很是耗时。可是随着mysql的优化,解析sql语句的时间还好。通常耗时的就是读,因为读写分离的技术,也还好。重要的是控制并发线程数,也就是链接数在100个如下。这个我自身在一个系统没上线的时候用线上服务器实际试验过。QPS可承受的压力在1w多。缓存
来看看咱们项目,接口服务前台11台服务器,平均每台QPS2k多,峰值在3k多,合起来不会超过4w。写的主库是单节点,压力很小。从库是三个节点的集群。DBA说从库能够承受QPS4w(咱们用的是mariadb)。可是咱们都直接访问memcached了。memcached集群运维说用一个key去压QPS可达到2.5w。实际上压测value大小在5k的,也就几k[狂汗],而咱们项目中超过1k的占绝大多数。看文章说mysql5.7中使用InnoDB Memcached插件可实现QPS100w。阿里云开发了一个AliSQL,也是mysql官方版本的一个分支,说是性能还要好。服务器
因此,要是我,宁愿不用memcached缓存,也不能不用DB啊。因此通常你们的使用方法是memcached缓存计算结果,采用最近最少使用算法或者是最不常用算法等失效策略,尽可能少的缓存。第一次去取数据的时候查询DB,将结果缓存到memcached中。有数据更新或者删除,就删除memcached的相关记录。经典用法有经典用法的设计理念。数据结构
咱们的cbase集群分配了500G内存,实际上只用到了80G。且不说在这种使用率的状况下的哈希分布,实际上memcache内存管理的原理是将内存分红大大小小的片断,
这种结构内存浪费自己就比较严重。若是咱们的数据大数据比较多的话,这种内存的浪费就更明显。另外,若是数据块比较大,大数据比较多的时候,计算哈希地址发生碰撞的概率会增长。碰撞的地址须要rehash,增长了计算时间。
那将redis换成memcached会怎样?
Redis有一些高级功能,可是Redis是单线程,高级功能占据CPU, I/O操做会被阻塞,因此仍是比较建议只做为一个k/v的缓存。举个例子,Redis不是支持有序集合嘛,若是取有序集合的必定范围的元素,它内部使用了skiplist,关于跳表的详细描述请看个人另外一篇博客<看Lucene源码必须知道的基本规则和算法>。时间复杂度是log(n),仍是须要计算的。并且因为这个单线程,Redis在处理100K以上1M如下的大数据的时候比memcached仍是稍显逊色的。这个1M如下是怎么来的呢?memcached内存结构规定最大的value值只能达到1M了,而Redis可达到512M。
Redis不只仅支持简单的k/v类型的数据,同事还提供list,set,zset,hash等数据结构的存储。这一点确实颇有用。
Redis支持数据的备份,即master-slave模式的数据备份。不论是备份也好,集群间的数据同步也好,宕机后的aof恢复也好,如今主流的解决方法使用的都是操做日志。实现原理和mysql采用binlog的方式是同样的。在使用的时候要注意其延时情况。
Redis会在内存中长期存储全部的key。但它采用数据回收机制,可以将陈旧value从内存中删除以提供新value所必需的缓存空间。旧的数据只是内存中被删除,磁盘上还有。不会由于回收而影响命中。因此Redis没有最大过时时间限制。Memcached最大过时时间是一个月,不然会写入失败。
据说Redis是支持身份验证的,实际开发中没用过这个功能。
Redis的做者和我是一个风格的,什么都不想用现成的。去年夏天我本身剪了一次头发,剪得比较成功。后来又剪了一次,惨不忍睹,可是为了记念此次失败,好几个月没换发型。Redis的做者管理IO用的不是memcached那样现成的libevent,而是本身封装了一个简单的AeEvent事件处理框架。内存管理也是同样,本身写了一个zmalloc.h和zmalloc.c,将内存大小存入内存块头部。用zmalloc代替malloc,zcalloc代替calloc,zrealloc代替realloc,zfree代替free。作C开发的就是高大上,想怎么分配内存就怎么分配内存。
综上所述,Redis可能能够解决部分问题,但不是终极解决方案。由于接口服务是基于多个维度来查找的,更合适用只存储和索引,不分词的搜索引擎,能够有多少内存吃多少内存,速度优点的原理和上面介绍的缓存都是同样的。为了更好的性能,我要实现本身的搜索引擎,具体规划请参考个人其余文章。
感谢这半年多,一直不断有朋友来我这边推荐工做的,挖人的,有推荐工做兼挖人的。正好有这个平台,问问你们最近有想动一动的么?在北京的童鞋有想去阿里,蚂蚁金服,美团点评,美团金融,猫眼电影,京东,乐视网咱们部门也在招人,还有东直门的创业公司,燕郊的创业公司。总之,均可以找我,简历发我邮箱 xiexiaojing@le.com。
你们帮忙提提意见,是否是个人博客设计的不太好看?我一贯审美观不太好。是否是页首横幅上面的照片比较丑?好吧,这个我妈要承担50%的责任。