微服务架构下静态数据通用缓存机制

戳蓝字“CSDN云计算”关注我们哦!


作者:Ala6

来源:Docker


640?wx_fmt=jpeg

在分布式系统中,特别是最近很火的微服务架构下,有没有或者能不能总结出一个业务静态数据的通用缓存处理机制或方案,这篇文章将结合一些实际的研发经验,尝试理清其中存在的关键问题以及探寻通用的解决之道。
什么是静态数据

640?wx_fmt=png


这里静态数据是指不经常发生变化或者变化频率比较低的数据,比如车型库、用户基本信息、车辆基本信息等,车型库这种可能每个月会更新一次,用户和车辆基本信息的变化来源于用户注册、修改,这个操作的频率相对也是比较低的。
另外这类数据的另一个特点是要求准确率和实时性都比较高,不能出现丢失、错误,以及过长时间的陈旧读。
具体是不是应该归类为静态数据要看具体的业务,以及对变化频率高低的划分标准。在这里的业务定义中,上边这几类数据都归为静态数据。


为什么需要缓存

640?wx_fmt=png


在面向用户或车联网的业务场景中,车型信息、用户基本信息和车辆基本信息有着广泛而高频的业务需求,很多数据都需要对其进行关联处理。在这里缓存的目的就是为了提高数据查询效率。静态数据通常都保存在关系型数据库中,这类数据库的IO效率普遍不高,应对高并发的查询往往捉襟见肘。使用缓存可以极大的提升读操作的吞吐量,特别是KV类的缓存,没有复杂的关系操作,时间复杂度一般都在O(1)。注意这里说的缓存指内存缓存。
当然除了使用缓存,还可以通过其它手段来提高IO吞吐量,比如读写分离,分库分表,但是这类面向关系型数据库的方案更倾向于同时提高读写效率,对于单纯提升读吞吐量的需求,这类方案不够彻底,不能在有限的资源情况下发挥更好的作用。


通用缓存机制

640?wx_fmt=png


下面将直接给出一个我认为的通用处理机制,然后会对其进行分析。
640?wx_fmt=png
对于某个具体的业务,其涉及到六个核心程序:
  • 业务服务:提供对某种业务数据的操作接口,比如车辆服务,提供对车辆基本信息的增删改查服务。

  • 关系数据库:使用若干表持久化业务数据,比如SQLServer、MySQL、Oracle等。

  • 持久化队列:可独立部署的队列程序,支持数据持久化,比如RabbitMQ、RocketMQ、Kafka等。

  • 缓存处理程序:从队列接收数据,然后写入缓存。

  • 数据一致处理程序:负责检查缓存数据库和关系型数据库中数据是否一致,如果不一致则使用关系数据库进行更新。

  • 缓存数据库(Redis):支持持久化的缓存数据库,这里直接选了Redis,这个基本是业界标准了。


以及两个外部定义:
  • 数据生产者:业务静态数据的来源,可以理解为前端APP、Web系统的某个功能或者模块。

  • 数据消费者:需要使用这些业务静态数据的服务或者系统,比如报警系统需要获取车辆对应的用户信息以便发送报警。


下面以问答的形式来说明为什么是这样一种机制。
为什么需要业务服务?
既然是微服务架构,当然离不开服务了,因为这里探讨的是业务静态数据,所以是业务服务。不过为了更好的理解,这里还是简单说下服务出现的原因。
当今业务往往需要在多个终端进行使用,比如PC、手机、平板等,既有网页的形式,又有APP的形式,另外某个数据可能在多种不同的业务被需要,如果将数据操作分布在多个程序中很可能产生数据不一致的情况,另外代码不可避免的冗余,读写性能更很难控制,变更也基本上是不敢变的。通过一个业务服务可以将对业务数据的操作有序的管理起来,并通过接口的形式对外提供操作能力,代码不用冗余了,性能也好优化了,数据不一致也得到了一定的控制,编写上层应用的人也舒服了。
为什么不是进程内缓存?
很多开发语言都提供了进程内缓存的支持,即使没有提供直接操作缓存的包或库,也可以通过静态变量的方式来实现。对数据的查询请求直接在进程内存完成,效率可以说是杠杠滴了。但是进程内缓存存在两个问题:
  • 缓存数据的大小:进程可以缓存数据的大小受限于系统可用内存,同时如果机器上部署了多个服务,某个服务使用了太多的内存,则可能会影响其它服务的正常访问,因此不适合大量数据的缓存。

  • 缓存雪崩:缓存同时大量过期或者进程重启的情况下,可能产生大量的缓存穿透,过多的请求打到关系数据库上,可能导致关系数据库的崩溃,引发更大的不可用问题。


为什么是Redis?
Redis这类数据库可以解决进程内缓存的两个问题:
  • 独立部署,不影响其它业务,还可以做集群,内存扩容比较方便。

  • 支持数据持久化,即使Redis重启了,缓存的数据自身就可以很快恢复。


另外Redis提供了很好的读写性能,以及方便的水平扩容能力,还支持多种常用数据结构,使用起来比较方便,可以说是通用缓存首选。
为什么需要队列?
队列在这里的目的是为了解耦,坦白的说这个方案中可以没有队列,业务服务在关系数据库操作完成后,直接更新到缓存也是可以的。 之所以加上这个队列是由于当前的业务开发有很明显的系统拆分的需求,特别是在微服务架构下,为了降低服务之间的耦合,使用队列是个常用选择,在某些开发模型中也是很推崇的,比如Actor模型。
举个例子,比如新注册一个用户,需要赠送其300积分,同时还要给其发个注册成功的邮件,如果将注册用户、赠送积分、发成功邮件都写到一起执行,会产生两个问题:一是注册操作耗时增加,二是其中某个处理引发整体不可用的几率增大,三是程序的扩展性不好;通多引入队列,将注册信息分别发到积分队列和通知队列,然后由积分模块和通知模块分别处理,用户、积分、通知三个模块的耦合降低了,相互影响变小了,以后再增加注册后的其它处理也就是增加个队列的事,整体的扩展性得到了增强。
队列作为一种常用的解耦方案,在缓存这里虽然产生的影响不大,但是除了缓存难免同时还会有其它业务处理,所以为了统一处理机制,这里保留了下来。(既然用了,就把它发扬光大。)
为什么队列需要持久化?
持久化是为了解决网络抖动或者崩溃导致数据丢失的问题,在数据从业务服务到队列,队列自身处理,再从队列到缓存处理程序,中间都可能丢失数据。为了解决丢失数据的问题,需要发送时确认、队列自身持久化、接收时确认;但是需要注意确认机制可能会导致重复数据的产生,因为在未收到确认时就需要重新发送或接收,而数据实际上可能被正常处理,只是确认丢失了;确认机制还会降低队列的吞吐量,但是根据我们的定义业务静态数据的变更频率应该不高,如果同时还需要较高的并发分片是个不错的选择。
这里持久化队列推荐选择RabbitMQ,虽然吞吐量支持的不是很大,但是各方面综合不错,并发够用就好。
为什么需要数据一致检查程序?
在业务服务操作完关系数据库后,数据发送到队列之前(或者不用队列就是直接写入缓存之前),业务服务崩溃了,这时候数据就不能更新到缓存了。还有一种情况是Redis发生了故障转移,Master中的更新没有同步到Slaver。通过引入这么一个检查程序,定时的检查关系数据库数据和缓存数据的差别,如果缓存数据比较陈旧,则更新之。这样提供了一种极端情况下的挽救措施。
这个检查程序的运行频率需要综合考虑数据库压力和能够承受的数据陈旧时间,不能把数据库查死了,也不能陈旧太久导致大量数据不一致。可以通过设置上次检查时间点的方式,每次只检查从上次检查时间点(或者最近几次,防止Redis故障转移数据未同步的问题)到本次检查时间点发生变更的数据,这样每次检查只对增量变更,效率更高。
同时需要理解在分布式系统中,微服务架构下,数据不一致是经常出现的,必须在一致性和可用性之间做出权衡,尽力去降低影响,比如使用准实时或最终一致性。
只要数据一致检查程序是不是就够了?
假设没有缓存处理程序,通过定时同步关系数据库和缓存数据库是不是就够了呢?这还是取决于业务,如果是车型库这种数据,增加一个新的车型,本来之前就没有,时间上并不是很敏感,这个是可以的。但是对于新增了用户或者车辆,数据消费者还是希望能够马上使用最新的数据进行处理,越快越好,这时使用同步或者准同步更新就能更加贴近需求。
为什么不用缓存过期机制?
使用缓存过期机制可以不需要缓存处理程序和数据一致检查程序,业务服务首先从Redis查询数据,如果数据存在就直接返回,如果不存在则从关系数据库查询,然后写入Redis,然后再返回,这也是一种常用的缓存处理机制,网上可以查询到很多,很多人用的也很好。
但是缓存的过期时间是个问题:缓存多长时间过期,设置的短可以降低数据的陈旧,但是会增加缓存穿透的概率,即使采用随机的缓存过期时间,在Redis重启或者故障转移的情况下还是会可能导致缓存雪崩,雪崩的情况下采用数据预热机制,也可能会导致服务更长时间的不可用;设置的长可以提升缓存的使用率,但是增加了数据陈旧,在上边对静态数据的定义中对其准确率和实时性都有较高的要求,业务上能不能接受需要考虑。而且如果操作数据和查询存在波动的峰谷,是不是要引入动态TTL的机制,以达到缓存使用和直接访问数据库的一种平衡,这就需要权衡业务需求和技术方案。


总结

640?wx_fmt=png


通过上边的这些问题问答,再来看看上面提出的微服务架构下静态数据通用缓存处理机制。
  • 通过业务服务来包装对数据的操作,不管是操作关系数据库还是缓存数据库,数据消费者其实不需要关心,它只关心业务服务能不能提供高并发实时数据的查询能力。

  • 利用分布式系统中经常使用队列进行解耦的方式,业务服务不干写入缓存的事,增加一个队列订阅数据变更,然后从队列取数据写入缓存数据库。

  • 对于绝大部分正常的情况,通过队列更新缓存数据和业务服务中更新缓存数据,其实时性是差不多的,同时实现了业务操作和写缓存的解耦。

  • 在极端崩溃导致数据不一致的情况下,通过数据一致检查程序进行补救,尽快更新缓存数据。

  • 现在业务服务可以通过访问Redis缓存来提供对静态数据的高并发准实时查询能力,缓存中不存在的数据就是不存在,没有缓存穿透。


对于微服务架构而言,这个机制借助队列这种通用的解耦方式,独立了缓存更新处理,通过准实时更新和定时检查,保证了缓存的实时性和极端情况下较短时间内达到最终一致,通过缓存的持久化机制消除了缓存穿透和雪崩,在缓存的数据较大或读取并发较高时支持水平扩容,可以认为对业务静态数据提供了一种广泛适用的缓存处理机制。
这个方案在某些情况下可能是没有必要的,比如你要缓存一个全国限行的城市列表,使用一个进程内缓存就够了。
最后剩下的就是工作量的问题了,这个会给开发和维护带来复杂性,队列有没有用的顺手的,人手是不是够,业务需求是什么样的,需要考虑清楚。



推荐阅读


1.微信群:

添加小编微信:color_ld,备注“进群+姓名+公司职位”即可,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!


2.征稿:

投稿邮箱:liudan@csdn.net;微信号:color_ld。请备注投稿+姓名+公司职位。

640?wx_fmt=png喜欢就点击“好看”吧!

MySQL数据库从入门实战课

12-31
限时福利1:购课进答疑群专享柳峰(刘运强)老师答疑服务。 限时福利2:购课后添加学习助手(信号:csdn590),按消息提示即可领取编程大礼包! 注意:原价129的课程,最后2天限时秒杀仅需49元!! 为什么说每一个程序员都应该学习MySQL? 根据《2019-2020年中国开发者调查报告》显示,超83%的开发者都在使用MySQL数据库。 使用量大同时,掌握MySQL早已是运维、DBA的必备技能,甚至部分IT开发岗位也要求对数据库使用和原理有深入的了解和掌握。 学习编程,你可能会犹豫选择 C++ 还是 Java;入门数据科学,你可能会纠结于选择 Python 还是 R;但无论如何, MySQL 都是 IT 从业人员不可或缺的技能! 【课程设计】 在本课程中,刘运强老师会结合自己十多年来对MySQL的心得体会,通过课程给你分享一条高效的MySQL入门捷径,让学员少走弯路,彻底搞懂MySQL。 本课程包含3大模块:  一、基础篇: 主要以最新的MySQL8.0安装为例帮助学员解决安装与配置MySQL的问题,并对MySQL8.0的新特性做一定介绍,为后续的课程展开做好环境部署。 二、SQL语言篇: 本篇主要讲解SQL语言的四大部分数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL,学会熟练对库表进行增删改查等必备技能。 三、MySQL进阶篇: 本篇可以帮助学员更加高效的管理线上的MySQL数据库;具备MySQL的日常运维能力,语句调优、备份恢复等思路。  

Python入门到实战一卡通

06-09
<span><span><span><span> <p class="ql-long-24357476"> <span> </span> </p> <p class="ql-long-24357476"> 【课程特色】 </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">1、超强师资+体系全面+ 1 对 1 答疑+离线缓存+永久有效,无限回放</span> </p> <p class="ql-long-24357476"> 2、知识全面系统,从Python入门到逐步进阶到爬虫、数据分析、Web框架、人工智能应用 </p> <p class="ql-long-24357476"> <br> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">【优惠说明】</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">1、8大课程,250余节视频课,原价998元,今日联报立减800,仅需198元</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">2、</span>现在购课,就送价值800元的编程大礼包! </p> <p class="ql-long-24357476"> 备注:请添加信:itxy41,按提示获取讲师答疑服务。 </p> <p> <br> </p> <p class="ql-long-24357476"> 讲师介绍:裴帅帅,前百度资深架构师,现爱奇艺算法架构师全程亲自授课。 </p> <p> <br> </p> <p class="ql-long-24357476"> 【为什么要学习这门套餐课?】 </p> <p class="ql-long-24357476"> Python无论是在web/爬虫/人工智能/大数据/机器学习/测试/运维/数据分析等等领域都有大量的应用,但是作为小白来讲,很难确定最适合自己的应用方向。 </p> <p> <br> </p> <p class="ql-long-24357476"> 在这门课程中,将带你从零入门Python,并向你讲授实战 Python 各个应用方向的核心知识点,同时应用于实战项目。 </p> <p> <br> </p> <p class="ql-long-24357476"> 【学完后我将达到什么水平?】 </p> <p class="ql-long-24357476"> 你将能够熟练掌握 Python 在人工智能时代的多种技能,具备使用 Python 编写代码完成 Web 后台开发、网络爬虫、数据分析、机器学习、推荐系统等多种项目实战的能力,掌握 Python 全栈工程师的核心能力。 </p> <p> <br> </p> <p class="ql-long-24357476"> 【课程学习路径】 </p> <p class="ql-long-24357476"> 本套课以市场就业和职位需求为核心,从 Python 入门到多领域实战,并结合 Python 全栈工程师的进阶路线,共分为八大模块,分别是:Python 基础、Python Web 开发、Python 爬虫、Numpy 数据计算、Pandas 数据分析、Python数据可视化、Tensorflow 深度学习、推荐系统实战应用模块。 </p> <p> <br> </p> <p class="ql-long-24357476"> 套餐中一共包含8门Python课程(共246讲)助你从零进阶Python全栈工程师! </p> <p class="ql-long-24357476"> 课程1:《Python零基础入门视频教程》 </p> <p class="ql-long-24357476"> 课程2:《Python爬虫从入门到实战》 </p> <p class="ql-long-24357476"> 课程3:《Python使用Flask开发Web服务》 </p> <p class="ql-long-24357476"> 课程4:《Python使用Numpy入门数据计算》 </p> <p class="ql-long-24357476"> 课程5:《Python使用Pandas入门数据分析》 </p> <p class="ql-long-24357476"> 课程6:《Python数据图表可视化》 </p> <p class="ql-long-24357476"> 课程7:《Tensorflow深度学习从入门到实战》 </p> <p class="ql-long-24357476"> 课程8:《推荐系统技术入门到实战》 </p> <p> <br> </p> <p class="ql-long-24357476"> 【面向人群】 </p> <p class="ql-long-24357476"> 1、在校计算机专业或者对软件编程感兴趣的学生; </p> <p class="ql-long-24357476"> 2、想要使用数据分析、网络爬虫提升职场竞争力升职加薪的各行各业的企业白领; </p> <p class="ql-long-24357476"> 3、想要转方向成为数据分析师、大数据开发、机器学习算法、推荐系统工程师的职场码农; </p> <p class="ql-long-24357476"> 4、准备从事人工智能、Python开发的程序员。 </p> </span> <p> <br> </p> <p class="ql-long-24357476"> <br> </p> <p> <br> </p> <p class="ql-long-24357476"> 【课程知识体系图】 </p> </span></span></span> <p> <img src="https://img-bss.csdnimg.cn/202006100818561687.png" alt=""> </p>

150讲轻松搞定Python网络爬虫

05-16
【为什么学爬虫?】        1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要的数据,这门课程,你都能学到!        2、如果是作为一个其他行业的开发者,比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件和网站 【课程设计】 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: 网络请求:模拟浏览器的行为从网上抓取数据。 数据解析:将请求下来的数据进行过滤,提取我们想要的数据。 数据存储:将提取到的数据存储到硬盘或者内存中。比如用mysql数据库或者redis等。 那么本课程也是按照这几个步骤循序渐进的进行讲解,带领学生完整的掌握每个步骤的技术。另外,因为爬虫的多样性,在爬取的过程中可能会发生被反爬、效率低下等。因此我们又增加了两个章节用来提高爬虫程序的灵活性,分别是: 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 Scrapy和分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 通过爬虫进阶的知识点我们能应付大量的反爬网站,而Scrapy框架作为一个专业的爬虫框架,使用他可以快速提高我们编写爬虫程序的效率和速度。另外如果一台机器不能满足你的需求,我们可以用分布式爬虫让多台机器帮助你快速爬取数据。   从基础爬虫到商业化应用爬虫,本套课程满足您的所有需求! 【课程服务】 专属付费社群+每周三讨论会+1v1答疑
©️2020 CSDN 皮肤主题: 终极编程指南 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值