闲鱼如何一招保证推荐流稳如泰山

简介: 风雨不动安如山

作者:闲鱼技术——习武

背景

近几年互联网的快速发展中,互联网业务发展越来越复杂,业务也被拆分得越来越细,阿里内部业务也发生着翻天覆地的变化,从最初的单体应用,到后面的分布式集群,再到最近几年大中台小前台的业务形态,作为后端开发,依赖的服务方越来越多,同时依赖服务方的故障因素也会越来越多的会影响到闲鱼的上层业务的稳定。例如在闲鱼主推商品流的业务场景中,商品中台数据库的抖动会造成主推商品流的卡顿或者页面显示空窗现象,个性化算法中台向量集群的扩容也会造成推荐内容延时被拖到非常长,后面还有可能依赖其他的业务中台,作为上层业务如何保证依赖的中台越来越多的情况下,还能保证服务的稳定性运行呢?

业界主流溜一遍

根据日常解决问题的经验,不能直接解决业务问题本身,可以折中解决业务问题也是一个不错的办法。上述业务问题中,当业务出现问题的时候,可以折中提前置备好所需的业务数据返回给业务,也是一个不错的办法。在闲鱼主推商品流的业务场景中,对可靠性要求非常高,因为推荐商品失败,用户看到推荐页出现空窗,业务所需的数据量大概是5页的推荐商品数据流,大概为3M左右。在实际解决问题中,笔者从业务所需的数据量级、可靠性要求级别等角度调研了业界一些通用解决办法。
image.png
为了给用户良好的业务体验,笔者主要使用服务端数据冗余、客户端数据冗余、熔断机制等方法,来确保用户对闲鱼App流畅的业务体验。笔者主要服务端数据冗余聊聊本地缓存,根据笔者在阿里断网演练的经验,断网演练时,某个区域的所有服务不可用,所以笔者在技术选型的时候没有考虑分布式缓存Redis,Memcache之类等。目前就业界本地缓存库有Guava、Caffeine、Ehcache、Cache2K、ConcurrentHashMap、Varnish、JackRabbit等,笔者选取了几个性能比较优越的缓存库比较,下面笔者从功能上、性能上、易用性、集群能力、可视化报表上等分别比较。
image.png
笔者对照目前业务需求对比了上述四个组件,在定时失效策略能力上,除了ConcurrentHashMap都是使用定时失效能力,并且三个组件时间复杂度都是O(n)。在集群能力上,Ehcache依赖自身网络协议保证集群数据一致性,不能使用现有集团内部组件保证数据一致性。在本地缓存能力上,Caffeine的写能力[1]优与Guava。在组件通用性上,Guava组件更加通用。最终笔者选用了Guava组件作为本地缓存组件,因为Guava 组件更加通用,并且很方便与阿里内部中间件集成配合使用。在集群数据同步能力,通过配置中心中间件实现数据同步,在可视化报表能力,通过定时任务打印日志,日志采集系统采集展示数据报表。接下来笔者介绍如何添加上述三种能力和优化Guava本地缓存能力。

我的集群Cache组件

Guava Caching提供了定时失效、最后访问失效、最后写入失效策略等能力,笔者主要使用了定时失效能力,在首次写入Key后,指定时间过后,该Key会失效,业务获取该Key时,会调用reload方法重新同步加载该Key。如果使用invalid方法使该Key无效,业务并发再次获取该Key,多线程加载该Key时,只有一个业务线程调用load方法加载该Key,其他线程等待该Key,加载完成后重新进入指定时间后流程。笔者在原来Guava Cache本地缓存能力上结合Spring自动注入能力,进行工程化,添加了业务所需的如下三种能力

  • 当key失效,本地缓存reload异步加载
  • 失效本地缓存key,整个集群机器上key失效能力
  • 定时上报本机Cache内各个Key在本地缓存大小

根据上述业务能力,整体流程图如下所示
image.png集群本机Cache组件的整体结构类图如下:
image.png

  • AbstractCacheLoader重写父类CacheLoader的reload方法,添加异步加载能力
  • LocalCacheManager管理所有实现AbstractCacheConfig的子类,并上报各自本地缓存大小。
  • 实现AbstractCacheConfig的业务配置子类,例如CurrentCacheConfig等,调用invalidate方法时,会通知集群本机Cache中Key消息。

业务同学在使用集群本机Cache组件时,只需要继承AbstractCacheConfig抽象类,声明为Bean,即用集群本机Cache组件,业务同学无需关心集群环境问题等。相比Guava cache组件,提供了集群本机Cache Key失效能力,以及对Key集中管理和监控,减少了单独使用Guava cache带来内存无法管理的问题。
接下来笔者介绍使用集群本机Cache组件能力的典型案例: 自动置备兜底组件。

典型栗子

自动置备兜底组件

兜底是在服务遇到外部依赖异常(超时、不可用、数据异常等),可能导致服务无可以返回的正常数据时,服务通过使用兜底数据提供服务的一种降级行为。自动置备兜底组件使用集群本机cache的本机缓存能力和集群失效能力,很方便完成兜底数据置备。在闲鱼的业务场景中使用兜底置备组件的场景非常多,例如闲鱼主推商品流等。
兜底自动置备组件原理如下:
image.png

  • 使用定时任务scheduleX2定时触发服务集群中的一台服务器,执行兜底置备,更新tair缓存内容,失效本地缓存,即失效集群server的本地缓存。
  • 当业务请求获取key时,会获取tair中最新内容,并缓存到本地,再次请求,直接本地获取。

详细业务请求流程图如下所示
image.png自动兜底组件已经在闲鱼的多个业务场景得到使用,在断网演练情况下,服务端RT延时和成功率有了明显的提升,闲鱼主要业务场景的提升效果如下:
image.png

展望

在集群本机cache组件使用过程中也发现一些问题,例如有时候集群本机cache缓存错误的配置,需要重启集群或者等待key失效,所以需要集群本机cache组件web管理功能。在集群本机cache组件推广中,发现有些业务场景的缓存key对应的缓存对象比较大,或者缓存key的数量比较多,后期按照key使用频率等级,考虑对于长期不使用的key存储到本机磁盘上,让业务方不关心缓存Key过大可能造成的问题。




参考:
[1]: Halodoc Caching Analysis

相关文章
|
搜索推荐 Java 应用服务中间件
【Maven】IDEA部署配置Maven项目教程,IDEA配置Tomcat(2019.3.3)(2023.1.3)
当涉及到软件开发和项目管理时,使用一个可靠的构建工具是非常重要的。Maven是一个广泛使用的构建工具,它为Java项目提供了一种简化的构建过程和依赖管理。 在本文中,我们将探讨如何部署Maven并开始使用它来构建您的项目。我们将介绍所需的步骤,并向您提供一些有用的提示和建议。
【Maven】IDEA部署配置Maven项目教程,IDEA配置Tomcat(2019.3.3)(2023.1.3)
|
机器学习/深度学习 人工智能 算法
闲鱼商家私信脚本,自动留言评论插件,闲鱼全自动私信群发打招呼工具
这是一款针对闲鱼自动打招呼的工具源码,可帮助用户高效发送私信促成交易。它通过自动化操作减少手动工作,包含搜索商品
|
机器学习/深度学习 人工智能 语音技术
情感识别与表达:FunAudioLLM的情感智能技术
【8月更文第28天】随着人工智能的发展,语音交互系统越来越普遍。其中,情感智能技术成为提高用户体验的关键因素之一。本文将探讨 FunAudioLLM 如何利用情感识别和表达技术来增强语音交互的真实感,并提供具体的代码示例。
1339 0
|
监控 Java 测试技术
代码精准分析在闲鱼接口测试中的应用
代码精准分析在闲鱼接口测试中的应用
1072 106
代码精准分析在闲鱼接口测试中的应用
|
存储 前端开发 JavaScript
闲鱼唤端的背后
唤醒沉睡的你
1643 107
闲鱼唤端的背后
|
安全 NoSQL Java
基于springboot+Redis的前后端分离项目(三)-【黑马点评】
当用户抢购时,就会生成订单并保存到tb_voucher_order这张表中,而订单表如果使用数据库自增ID就存在一些问题:id的规律性太明显,受单表数据量的限制。场景分析:如果我们的id具有太明显的规则,用户或者说商业对手很容易猜测出来我们的一些敏感信息,比如商城在一天时间内,卖出了多少单,这明显不合适。场景分析二:随着我们商城规模越来越大,mysql的单表的容量不宜超过500W,数据量过大之后,我们要进行拆库拆表,但拆分表了之后,他们从逻辑上讲他们是同一张表,所以他们的id是不能一样的, 于是乎我们需要保证id的唯一性。
|
前端开发 Go API
go 数据导出Excel&前台接收后端返回文件流并在浏览器提供下载
go 数据导出Excel&前台接收后端返回文件流并在浏览器提供下载
1223 0
go 数据导出Excel&前台接收后端返回文件流并在浏览器提供下载
|
弹性计算 Cloud Native Android开发
阿里云自研CPU处理器芯片倚天Yitian 710
阿里云自研CPU处理器芯片倚天Yitian 710,阿里云自研CPU处理器倚天Yitian 710,2.75 GHz主频,搭载倚天710处理器的云服务器ECS有计算型c8y、通用型g8y和内存型r8y,云服务器吧分享阿里云自研CPU处理器倚天Yitian 710性能测评
316 0
|
人工智能 IDE 算法
基于arduino的语音识别垃圾分类
这是好多年前自己的一份毕业设计,分享一下小成果-大佬勿喷! 本设计结合社会垃圾分类知识,经过实际的需求分析,采用Arduino单片机技术以及LD3320非特定语音识别分析技术开发出的智能语音识别垃圾分类系统,实现了唤醒命令激活、实时的语音交互和自动感应打开桶盖的功能,达到了自动分类垃圾的目的。 本文详细论述了智能语音垃圾分类系统的
基于arduino的语音识别垃圾分类