写点什么

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

  • 2021-02-21
  • 本文字数:2304 字

    阅读完需:约 8 分钟

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

背景

近几年互联网的快速发展中,互联网业务发展越来越复杂,业务也被拆分得越来越细,阿里内部业务也发生着翻天覆地的变化,从最初的单体应用,到后面的分布式集群,再到最近几年大中台小前台的业务形态,作为后端开发,依赖的服务方越来越多,同时依赖服务方的故障因素也会越来越多的会影响到闲鱼的上层业务的稳定。


例如在闲鱼主推商品流的业务场景中,商品中台数据库的抖动会造成主推商品流的卡顿或者页面显示空窗现象,个性化算法中台向量集群的扩容也会造成推荐内容延时被拖到非常长,后面还有可能依赖其他的业务中台,作为上层业务如何保证依赖的中台越来越多的情况下,还能保证服务的稳定性运行呢?

业界主流溜一遍

根据日常解决问题的经验,不能直接解决业务问题本身,可以折中解决业务问题也是一个不错的办法。上述业务问题中,当业务出现问题的时候,可以折中提前置备好所需的业务数据返回给业务,也是一个不错的办法。在闲鱼主推商品流的业务场景中,对可靠性要求非常高,因为推荐商品失败,用户看到推荐页出现空窗,业务所需的数据量大概是 5 页的推荐商品数据流,大概为 3M 左右。在实际解决问题中,笔者从业务所需的数据量级、可靠性要求级别等角度调研了业界一些通用解决办法。


null

为了给用户良好的业务体验,笔者主要使用服务端数据冗余、客户端数据冗余、熔断机制等方法,来确保用户对闲鱼 App 流畅的业务体验。笔者主要服务端数据冗余聊聊本地缓存,根据笔者在阿里断网演练的经验,断网演练时,某个区域的所有服务不可用,所以笔者在技术选型的时候没有考虑分布式缓存 Redis,Memcache 之类等。目前就业界本地缓存库有 Guava、Caffeine、Ehcache、Cache2K、ConcurrentHashMap、Varnish、JackRabbit 等,笔者选取了几个性能比较优越的缓存库比较,下面笔者从功能上、性能上、易用性、集群能力、可视化报表上等分别比较。


null

笔者对照目前业务需求对比了上述四个组件,在定时失效策略能力上,除了 ConcurrentHashMap 都是使用定时失效能力,并且三个组件时间复杂度都是 O(n)。在集群能力上,Ehcache 依赖自身网络协议保证集群数据一致性,不能使用现有集团内部组件保证数据一致性。在本地缓存能力上,Caffeine 的写能力优于 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 在本地缓存大小


根据上述业务能力,整体流程图如下所示

null

集群本机 Cache 组件的整体结构类图如下:


null


  • AbstractCacheLoader 重写父类 CacheLoader 的 reload 方法,添加异步加载能力

  • LocalCacheManager 管理所有实现 AbstractCacheConfig 的子类,并上报各自本地缓存大小。

  • 实现 AbstractCacheConfig 的业务配置子类,例如 CurrentCacheConfig 等,调用 invalidate 方法时,会通知集群本机 Cache 中 Key 消息。


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


接下来笔者介绍使用集群本机 Cache 组件能力的典型案例:自动置备兜底组件。

典型栗子:自动置备兜底组件

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


兜底自动置备组件原理如下:


null


  • 使用定时任务 scheduleX2 定时触发服务集群中的一台服务器,执行兜底置备,更新 tair 缓存内容,失效本地缓存,即失效集群 server 的本地缓存。

  • 当业务请求获取 key 时,会获取 tair 中最新内容,并缓存到本地,再次请求,直接本地获取。

详细业务请求流程图如下所示

null

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

null

展望

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


References

[1] Halodoc Caching Analysis: https://blogs.halodoc.io/in-process-cache-2


本文转载自:闲鱼技术(ID:XYtech_Alibaba)

原文链接:闲鱼如何一招保证推荐流稳如泰山

2021-02-21 07:001361

评论

发布
暂无评论
发现更多内容

再不解决延迟不当,小心你的内存被打爆

华为云开发者联盟

线程 延迟 内存 并发 Sleep

手把手带你体验 Amazon Graviton2 的高性价比!文末有惊喜

亚马逊云科技 (Amazon Web Services)

Django 之路由篇

若尘

django Python编程 路由 5月日更

打造生态“朋友圈”,英特尔以生态之道培育AI创新“大气候”

E科讯

5G掀起工业互联网浪潮,水泥厂智能管理模式收效颇丰

一只数据鲸鱼

数据可视化 工业互联网 智慧工厂 水泥厂 智能工厂

提高建模效率:自动化机器学习之贝叶斯优化综述

索信达控股

机器学习 自动化 金融科技 贝叶斯公式 产品建模

将模型转为NNIE框架支持的wk模型第一步:tensorflow->caffe

华为云开发者联盟

tensorflow caffe NNIE框架 wk模型 mxnet

驾云驭能,云科技点燃制造创新之旅!

亚马逊云科技 (Amazon Web Services)

NUCLEO-L432KC实现ADC配置(STM32L432KC)

不脱发的程序猿

嵌入式 单片机 NUCLEO-L432KC STM32L432KC 光敏电阻传感器

iOS 面试策略之经验之谈-架构的选择

iOSer

ios 架构

强劲性能释放释放:联想消费新品笔记本震撼发布

E科讯

探索专有领域的端到端ASR解决之道

华为云开发者联盟

端到端 ASR 自动语音识别 语境偏移 专有领域

详解RS232、RS485、RS422、串口和握手

不脱发的程序猿

串口 通信总线 RS232、RS485、RS422 握手通信

iOS 面试策略之经验之谈-面向协议的编程

iOSer

ios swift 面试 面向协议protocol编程 面向协议编程

阿里P9架构师力荐:Java面试必刷的17套一线大厂真题(含答案)

Java架构追梦

Java 阿里巴巴 架构 腾讯 面试

iOS 面试策略之经验之谈- App的测试和上架

iOSer

ios 面试 app上架 app测试

农产品区块链溯源平台建设解决方案,健全食品安全体系

源中瑞-龙先生

区块链 溯源 食品安全

GitHub开源的10个超棒后台管理面板

不脱发的程序猿

GitHub 开源 后台管理面板

☕【JVM 技术之旅】深入JVM原理分析synchronized

洛神灬殇

synchronized 重量级锁 5月日更 同步锁 ObjectMontior

Cilium 1.10 重磅发布!】支持 Wireguard, BGP, Egress IP 网关, XDP 负载均衡, 阿里云集成

公众号:云原生Serverless

云原生 cilium cni

不同数据库模式下DATE类型的行为解析

华为云开发者联盟

MySQL oracle GaussDB(DWS) TD DATE类型

详解 WebRTC 高音质低延时的背后 — AGC(自动增益控制)

阿里云CloudImagine

阿里云 WebRTC 3A算法 音频技术 视频云

字节、美团等客户与华为联合创新DCI智能控制器,共筑互联网基础设施新生态

屏幕共享的实现与应用

anyRTC开发者

音视频 WebRTC RTC sdk

“零信任产业标准工作组”再度升级,持续促进国内零信任产业的协同发展

助力秋招第二弹:Java并发编程知识梳理

北游学Java

Java 面试 秋招

一文通关苦涩难懂的Java泛型

程序猿阿星

泛型 java基础 Java泛型

☕【JVM 技术之旅】攻克技术盲点之“JVM常量池们“

洛神灬殇

JVM 5月日更 字符串常量池 静态常量池 运行时常量池

全新F1洞察精彩亮相,帮你理解赛道上的瞬间决定!

亚马逊云科技 (Amazon Web Services)

iOS面试大全从面试的准备和流程到算法和数据结构以及计算机基础知识

iOSer

ios 面试 面向协议protocol编程 iOS 知识体系

强化基于位置的4种营销策略

郑州埃文科技

IP 营销 ISP

闲鱼如何一招保证推荐流稳如泰山_架构_闲鱼技术_InfoQ精选文章