架构师之路--从业务角度谈缓存的选型

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: 架构师之路--从业务角度谈缓存的选型

 想起来几年前挺火的前岛国国民女神学霸-小岛方晴子。当时替她说话的人都很惨,导师被逼自杀。她收到的压力侮辱不是常人可以想象的。但是她却坚强的活着,去年还出了书。我去日本的时候,下了新干线,前面有一群女学生,她们看到我了,立刻聚集成一团,一边看我一边说悄悄话。我才发现日本人穿的衣服基本就是黑,白,灰。他们也不穿羽绒服,女孩子大冬天都是光着腿。而我穿着黄绿色的羽绒服,确实像个怪胎。为什么来之前没人告诉我[大哭][大哭]。8年过去了,想起来还觉得尴尬。日本人是很爱背后说别人坏话的。所以我感谢我是个很普通的女孩子,而且生在中国。没人闲的没事去扒我之前做过的坏事。比如我很久前看不惯一个自己没能力还势利的混蛋,所以写了个程序刷爆了他的邮箱。再比如我自己写了个小程序循环注册一个网站参加抽奖,得了好多小东西。


  但是女孩子天生就是很坚强的,女孩子为爱而活,其他的什么都扛的下。写《傲慢与偏见》的女作家简.奥斯汀,大家看到她写的书的女主角们大概都能想象到作者本人是个聪明,智慧,自己漂亮且有一个更漂亮的姐姐,又很幽默的女孩。但是她却在自己心爱的男孩子傍了个富婆之后终生未嫁,高富帅向她求婚她没同意。一生寄人篱下,与恋人死去不愿做他人妇的姐姐相依为命,心中的痛苦又与谁人说。30多岁开始患有严重的忧郁症,直到她得知自己心爱的男孩去世的消息,自己也郁郁而终。感恩自己运气好,可以快快乐乐做个普通人。

  

  我们部门并发量最大的接口服务前段时间发生了几次业务端的流量猛增,扛不住的情况。瓶颈在缓存上。根本性的改造正在进行中。谈一谈这段时间由这个问题引发的思考。


  首先说之前的架构确实很老了,现在直接负责这个服务的男神哥哥也很年轻,有问题是正常的。缓存选用的是乐视统一的couchbase集群,是个memcached升级版,已经实现了持久化,本质是一个文档型的数据库,有人评价其性能要超过mongoDB。然后乐视网封装了它,自己起名叫cbase,前面用moxi代理。实际上使用觉得其性能让人擦汗。 

 

  接口服务将数据库里的全量视频和专辑刷入缓存。缓存扛不住了都不会穿透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可能可以解决部分问题,但不是终极解决方案。因为接口服务是基于多个维度来查找的,更合适用只存储和索引,不分词的搜索引擎,可以有多少内存吃多少内存,速度优势的原理和上面介绍的缓存都是一样的。为了更好的性能,我要实现自己的搜索引擎,具体规划请参考我的其他文章。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
运维 负载均衡 安全
深度解析:Python Web前后端分离架构中WebSocket的选型与实现策略
深度解析:Python Web前后端分离架构中WebSocket的选型与实现策略
96 0
|
26天前
|
消息中间件 运维 NoSQL
基础架构组件选型及服务化
【10月更文挑战第15天】本文概述了分布式系统中常见的基础架构组件及其选型与服务化的重要性。
|
1月前
|
消息中间件 运维 NoSQL
基础架构组件选型及服务化
【10月更文挑战第2天】本文介绍了常见的分布式基础架构组件,包括分布式服务化框架(如Dubbo、Spring Cloud)、分布式缓存(如Redis、Memcached)、数据库及分布式数据库框架(如MySQL、TiDB)、消息中间件(如Kafka、RabbitMQ)和前端接入层(如LVS、Nginx)。文中探讨了组件选型问题,强调统一标准的重要性,避免重复劳动与维护难题。最后,提出基础架构服务化的必要性,通过标准化和平台化提升运维效率
|
3月前
|
缓存 监控 架构师
缓存数据一致性 - 架构师峰会演讲实录
缓存数据一致性 - 架构师峰会演讲实录
|
3月前
|
缓存 架构师 数据库
缓存系统稳定性 - 架构师峰会演讲实录
缓存系统稳定性 - 架构师峰会演讲实录
|
3月前
|
存储 缓存 关系型数据库
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
67 0
|
3月前
|
存储 缓存 数据库
Django后端架构开发:信号与缓存架构开发
Django后端架构开发:信号与缓存架构开发
71 0
|
4月前
|
消息中间件 缓存 架构师
对抗软件复杂度问题之降低代码的复杂度,如何解决
对抗软件复杂度问题之降低代码的复杂度,如何解决
|
4月前
|
开发者 Sentinel 微服务
高并发架构设计三大利器:缓存、限流和降级问题之降级策略中的有限状态机的三种状态切换的问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之降级策略中的有限状态机的三种状态切换的问题如何解决
|
4月前
|
监控 应用服务中间件 nginx
高并发架构设计三大利器:缓存、限流和降级问题之Nginx的并发连接数计数的问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之Nginx的并发连接数计数的问题如何解决

热门文章

最新文章