ES 慢上游响应问题优化在用户体验场景中的实践

在抖音亿级日活流量的情况下,每天收到的用户反馈也是大量的,而用户反馈对于产品的发展与未来是至关重要的,因此用户体验管理平台(简称VoC)就应运而生,VoC 平台旨在通过技术平台化的方式,结合反馈驱动的机制,以产品化、数据化的手段从反馈中挖掘出对抖音系产品留存、增长或口碑提升的可能点,推动体验问题治理改进,提升产品体验。同时也为公司各业务线提供通用和定制化的体验数据总览、用户原声分析以及体验专项、实验专项等看板或专项管理能力。由其定位可知 VoC 平台需要具备实时大数据处理能力和高性能、高效能的指标计算能力,同时也需要保证足够的准确性与稳定性。

下面简要介绍本文优化实践涉及到 VoC 平台的主要功能,和在平台业务发展中产生的痛点问题的优化实践,由于篇幅有限本篇将主要对 ES 慢上游响应场景的优化实践进行介绍,下篇文章将主要介绍针对 ES 引擎局限性的优化实践及经过优化后整体的收益分析。

体验数据总览

体验数据总览主要是帮助运营、产品同学快速掌握反馈数据的整体情况。包括关键指标、反馈重点问题、全渠道反馈词频等重点模块。

  • 关键指标-反馈量级:快速掌握反馈数据量级;

  • 关键指标-反馈变化趋势:直观感受反馈趋势变化,初步定位原因;

  • 反馈重点问题:场景&问题维度掌握反馈,进一步深挖反馈量级变化的原因。

用户原声分析

用户原声分析主要是帮助运营、产品同学按照自己感兴趣的特定场景分析全渠道用户反馈并生成对应的用户画像分析,同时支持用户按照特定维度对比反馈变化趋势,细化分析维度,直击用户心声。其中,对比维度分为两种:一种是有固定数量、固定枚举值的,例如手机系统有 iOS、Android,这种对比维度的枚举数量有限且枚举值已知,趋势图展示会展示全部枚举值下聚合的趋势线;一种是数量、枚举值数量大于 10 或不固定的,例如 App 小版本号等,这种对比维度的枚举值无法预先掌握,趋势图展示仅展示均值 TOP 10 枚举的趋势线。

性能痛点

伴随着 VoC 平台上线以来的业务线横向拓宽、数据逐步积累到亿数量级以及分析能力拓展,平台所采用的 ES 搜索引擎逐渐暴漏出查询慢、OOM 等问题,严重影响了用户操作平台的使用体验。同时,VoC 对各业务线提供了一定范围内的标签整合能力,方便业务整合业务场景进行数据分析,但该能力承载在另外一个数据反馈和风控平台(SkyNet)中提供统一标签配置能力,由于历史遗留问题存在一定程度的性能问题,且由于标签是 VoC 平台相关数据统计的最基本条件,标签获取的慢响应会拖慢所有查询接口的响应。能否解决以上两个问题,是现阶段我们提升用户体验与维护平台口碑的关键。

痛点一:上游性能局限性

VoC 平台目前已完成公司大部分业务线的数据接入,为了能够保证平台数据的时效性和有效性,需要实时地对接公司多个平台获取相关信息。由于每个上游平台的复杂度以及请求承载能力不同,VoC 平台在频繁请求众多上游接口的过程中经常出现响应时间过长甚至超时的问题,严重地损害了平台自身的稳定性。

目前 VoC 上游请求响应最慢和稳定性最差的接口主要集中在数据反馈和风控平台(SkyNet)标签映射这一部分,这部分主要是提供整合业务原始标签便于业务进行指标看板分析的映射标签的能力,显然这种标签树融合配置、映射与反映射的功能会存在大量的递归、剪枝等复杂逻辑,所以这部分上游接口的响应速度很慢。同时,标签作为 VoC 平台的基础查询条件,上游接口的慢响应会影响每一个接口的响应速度,如何在有限的条件下降低上游接口响应慢带来的影响,是性能优化着重要考虑的问题。

目前 VoC 平台指标接口流程如下所示:

痛点二:ES 引擎局限性

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,VoC 平台的用户反馈数据均通过 ES 进行存储与查询,而上文提到的 VoC 功能中反馈变化趋势、反馈重点问题、反馈趋势维度对比,本质上都是围绕在时间、标签或是其他一些数据筛选项维度上的 ES 聚合或嵌套聚合。同时,ES 提供的聚合是一种 Bucket 聚合算法,Bucket 聚合按照一定的规则,将文档分配到不同的桶中,达到分类的目的,Bucket 聚合支持嵌套,也就是在桶里再次分桶。然而,ES 为了保证自身在面对海量数据与复杂查询条件时也能够稳定的运行,针对 Bucket 聚合设置了 max_bucket_size 限制,一旦本次查询生成的桶数目超出了该限制,ES 会立刻终止本次聚合并抛出异常,以免桶数过多超出内存限制最终触发 OOM。

我们可以来计算这样一个场景,统计周期为 6 个月、小时时间粒度下的标签对比维度反馈量趋势中一共有多少个桶:仅按时间相关的限制我们可以得到 6 个月、小时粒度的点共有 6*30*24=4320个,标签如果按 100 个计算,我们需要 ES 提供的聚合桶数就是 43.2 万个,但是实际上目前我们 ES 集群限制的聚合桶数仅仅只有 2 万个、标签数目也远不止 100 个。这就意味着大时间区间、小时间粒度、多对比维度这三个条件,任意一个足够极端时,我们的接口都有可能出现查询慢、ES 触发 Bucket 超限甚至 OOM 的异常情况。

上游性能局限性

虽然我们没有办法改变上游的接口性能,但由于 VoC 平台所依赖的上游数据绝大多数是变动不频繁的,我们可以通过设计针对上游接口的缓存方案,来降低上游性能对 VoC 平台接口性能的影响。本文基于数据反馈和风控平台(SkyNet) 标签映射接口阐述缓存方案的设计。

优化措施一:按请求参数缓存

按请求参数缓存是 B/S 架构下服务端最为常用的一种缓存方案,考虑到上游性能问题,这里不仅要对 VoC 自身接口做缓存也要对上游接口的响应做缓存。在上文的痛点中提过,映射标签到原始标签的转换因为上游性能问题成为瓶颈,针对该问题添加缓存后的方案流程如下:

添加请求参数缓存后的标签映射转换效率得到一定程度提升,但是这个提升仅局限在高频使用场景,这个原因是:上游接口的请求参数是一个映射标签列表,而 VoC 平台是支持用户自由的选择标签来过滤数据查看分析的,所以这里的请求参数可能性无限多,当且仅当按照同样的标签过滤条件查看页面时,这个上游缓存才能生效,换句话说就是高频使用场景性能提升更为明显。如何提升低频使用场景的缓存覆盖是后续方案设计着重要解决的问题。

优化措施二:按标签维度缓存

针对请求参数可能性无限多的问题,我们没有办法将全部的可能性全部加到缓存中,重新审视标签映射转换流程可以发现,标签映射相关接口请求上游的目的是完成映射标签到原始标签的转换,用于后续 ES 查询请求的构建,这个过程中最细的粒度是一个映射标签到多个原始标签的映射,这个转换流程如下所示:

不难看出,当前流程每一次查询都将前端请求中的映射标签参数全部透传到上游请求中,多次请求中很容易出现同一映射标签,同一映射标签在上游中的重复计算会造成不必要的开销。同时映射标签数目目前是万数量级的,我们没有办法把所有标签的排列组合全部加入预缓存,但却可以将每一个映射标签加入预缓存。综上,标签维度的缓存可以进一步提升缓存的覆盖面积,优化后的转换流程如下所示:

  • 通过 Faas 定时异步刷新全量标签缓存,基本能够保证 VoC 平台全部接口大部分时间内都不会再请求上游,而是通过 Redis Pipeline 去获取缓存中已有的标签映射信息,仅在上游标签映射版本改动时才会调用上游获取最新的标签映射信息。

  • 处理待转换的映射标签时,先分类出其中缓存中已有与缓存中暂无的映射标签,仅将未命中缓存的部分作为请求参数请求上游,降低上游计算量,提升响应速度。

标签维度的缓存与预缓存逻辑,将每个接口都需要进行的上游请求,转化为 Faas 中异步进行的缓存刷新,提升了缓存对于低频使用场景的覆盖,极大地降低了上游响应慢带来的影响,大范围提升了 VoC 平台的接口响应速度。

最终方案总览

综上,针对数据反馈和风控平台(SkyNet)为例的上游性能局限性解决方案为:

  • 请求参数缓存:用户高频使用场景性能有保障;

  • 标签维度缓存:用户低频使用场景能够复用历史标签映射转换结果,尽可能降低低频场景对于上游的依赖;

  • 高频场景预缓存与刷新缓存:通过分析一段时间的埋点数据,对请求参数缓存进行了高频场景的预缓存,尽最大可能保证进入平台以及高频场景使用的第一感受,同时消除缓存失效引起的性能骤降;

  • 标签映射预缓存与刷新缓存:定期刷新全量标签映射,将 99% 时间的上游请求都收拢到 Faas 任务中异步执行,整体避免上游依赖。

收益分析

在 VoC 平台的关键指标中用户进入平台首先看到的就是关键指标中的两个指标:反馈总量和反馈变化趋势,这里的性能分析是屏蔽了请求参数缓存进行的,目的是在于测试非高频场景下的性能优化结果:

反馈总量接口响应随着时间周期的增大性能提升更为明显,且基本稳定在 3.2s 左右;反馈趋势接口性能优化接近 80%,提升显著,但是当时间周期增加到 6 个月时性能会发生劣化,推测和 Filters 聚合的过滤条件下沉有关,这一部分还需要在后面的实践中进一步分析确认。

第二个痛点问题针对 ES 引擎局限性的性能优化将在下篇继续为大家介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/379229.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验七:图像的复原处理

一、实验目的 熟悉常见的噪声及其概率密度函数。熟悉在实际应用中比较重要的图像复原技术,会对退化图像进行复原处理。二、实验原理 1. 图像复原技术,说简单点,同图像增强那样,是为了以某种预定义的方式来改进图像。在具体操作过程中用流程图表示,其过程就如下面所示: 2…

达梦数据库的系统视图v$sqltext

达梦数据库的系统视图v$sqltext 在达梦数据库(DM Database)中,V$SQLTEXT 是一个系统视图,用于显示当前正在执行或最近执行的SQL语句的文本信息。这个视图对于监控和分析数据库中的SQL活动非常有用,尤其是在需要调试性…

Android TabLayout+ViewPager2如何优雅的实现联动详解

一、介绍 Android开发过程中,我们经常会遇到滑动导航栏的做法,之前的做法就是我们通过ViewGroup来转动,然后通过大量的自定义来完成,将导航栏item与viewpage 滑动,达到业务需求 二、现实方案 通过介绍,我…

SwiftUI 6.0(Xcode 16)新 PreviewModifier 协议让预览调试如虎添翼

概览 用 SwiftUI 框架开发过应用的小伙伴们都知道,SwiftUI 中的视图由各种属性和绑定“扑朔迷离”的缠绕在一起,自成体系。 想要在 Xcode 预览中泰然处之的调试 SwiftUI 视图有时并不是件容易的事。其中,最让人秃头码农们头疼的恐怕就要数如…

滑动窗口题目

题目描述&#xff1a; 计算两个字符串str1和str2在给定的含有n个元素的字符串数组strs中出现的最短距离。 详细解释&#xff1a; 定义整数变量n&#xff0c;用于存储字符串数组strs的长度。定义一个vector<string>类型的变量strs&#xff0c;用于存储输入的字符串。定义…

前端开发日记——在MacBook上配置Vue环境

前言 大家好&#xff0c;我是来自CSDN的寄术区博主PleaSure乐事。今天是开始学习vue的第一天&#xff0c;我使用的编译器是vscode&#xff0c;浏览器使用的是谷歌浏览器&#xff0c;后续会下载webstorm进行使用&#xff0c;当前学习阶段使用vscode也是可以的&#xff0c;不用担…

ctfshow-web入门-php特性(web127-web131)

目录 1、web127 2、web128 3、web129 4、web130 5、web131 1、web127 代码审计&#xff1a; $ctf_show md5($flag); 将 $flag 变量进行 MD5 哈希运算&#xff0c;并将结果赋值给 $ctf_show。 $url $_SERVER[QUERY_STRING]; 获取当前请求的查询字符串&#xff08;que…

防御笔记第七天(时需更新)

1.防火墙的可靠性&#xff1a; 因为防火墙不仅需要同步配置信息&#xff0c;还需要同步状态信息&#xff08;会话表等&#xff09;&#xff0c;所以防火墙不能像路由器那样单纯靠动态协议来进行切换&#xff0c;还需要用到双击热备技术。 双机---目前双机技术仅仅支持两台防火…

Python Linux环境(Centos8)安装minicoda3+jupyterlab

文章目录 安装miniconda安装python环境启动 最近服务器检查&#xff0c;我下面的服务器有漏洞&#xff0c;不得已重装了&#xff0c;正好记录下怎么从零到python写代码。 安装miniconda miniconda是anconda的精简版&#xff0c;就是管理python环境的得力助手。 # 创建一个名…

微服务

微服务 SpringCloud的五大组件 eureka服务注册和发现 nacos的工作流程 nacos和eureka的区别 负载均衡 ribbon负载均衡策略 如何自定义负载策略 服务雪崩 服务熔断 为服务端监控 项目中的限流 seata xa模式 AT模式 tcc模式 分布式服务接口幂等 分布式任务调度

linux服务器配置conda环境安装教程

1 软件准备 1.1 软件下载 https://repo.anaconda.com/archive/index.html 根据官网选择自己需要的版本。 这里下载的是 Anaconda3-2023.03-1-Linux-x86_64.sh 或者直接在linux中输入 wget -c https://repo.anaconda.com/archive/Anaconda3-2023.03-1-Linux-x86_64.sh 1.…

WebSocket实现群聊功能、房间隔离

引用WebSocket相关依赖 <dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.1</version></dependency><dependency><groupId>org.springframework</grou…

安全防御:智能选路

目录 一、智能选路 1.1 就近选路 1.2 策略路由 1.3 虚拟系统---VRF 二、全局选路策略 1&#xff0c;基于链路带宽进行负载分担 2&#xff0c;基于链路质量进行负载分担 3&#xff0c;基于链路权重的负载分担 4&#xff0c;根据链路优先级的主备备份 DNS透明代理 一、…

Java学习高级四

JDK8开始&#xff0c;接口新增了三种形式的方法 接口的多继承 内部类 成员内部类 静态内部类 局部内部类 匿名内部类 import javax.swing.*; import java.awt.event.ActionEvent;public class Test {public static void main(String[] args) {// 扩展 内部类在开发中的真实使用…

STM32的TIM1之PWM互补输出_死区时间和刹车配置

STM32的TIM1之PWM互补输出_死区时间和刹车配置 1、定时器1的PWM输出通道 STM32高级定时器TIM1在用作PWM互补输出时&#xff0c;共有4个输出通道&#xff0c;其中有3个是互补输出通道&#xff0c;如下&#xff1a; 通道1&#xff1a;TIM1_CH1对应PA8引脚,TIM1_CH1N对应PB13引…

‍我想我大抵是疯了,我喜欢上了写单元测试

前言 大家好我是聪。相信有不少的小伙伴喜欢写代码&#xff0c;但是对于单元测试这些反而觉得多此一举&#xff0c;想着我都在接口文档测过了&#xff01;还要写什么单元测试&#xff01;写不了一点&#xff01;&#xff01; 由于本人也是一个小小程序猿&#x1f649;&#xf…

nginx代理缓存

在服务器架构中&#xff0c;反向代理服务器除了能够起到反向代理的作用之外&#xff0c;还可以缓存一些资源&#xff0c;加速客户端访问&#xff0c;nginx的ngx_http_proxy_module模块不仅包含了反向代理的功能还包含了缓存功能。 1、定义代理缓存规则 参数详解&#xff1a; p…

【前端】ikun-qrcode:极简的二维码生成组件,使用view而非canvas避免层级问题

文章目录 背景ikun-qrcode界面效果如何发布一款自己的插件到uniapp市场。&#xff08;5分钟搞定&#xff09; 背景 之前在uniapp上100行搞定二维码生成&#xff0c; 现在封装为vue组件分享出来&#xff1a; 下载地址&#xff1a; https://ext.dcloud.net.cn/plugin?id19351 …

【MySQL篇】Percona XtraBackup工具备份指南:常用备份命令详解与实践(第二篇,总共五篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

jenkins系列-01.docker安装jenkins

进入官网&#xff1a;https://www.jenkins.io/ 使用LONG term support版本&#xff1a;2.387.1 docker pull jenkins/jenkins:2.387.1-lts 拉取镜像&#xff1a; 编写docker-compose文件&#xff1a; 启动jenkins: 查看启动日志&#xff1a; 默认生成的密码&#xff1a;…