线上救急-AWS限频
线上救急-AWS限频
问题
在一个天气炎热的下午,我正喝着可口可乐,悠闲地看着Cursor生成代码,忽然各大群聊中出现了加急@全体的消息,当时就心里一咯噔,点开一看,果然,线上服务出问题,多个能源统计接口报错未返回数据。
排查
首先排查线上ES日志,查询能源统计接口的日志中存在大量报错,报错提示如下:
GetEnergyAnalysisRpc err:error: code = 1083 reason = erdr: code = 10083 reason = error: code = 10003 reason = ThrottlingException: Request rate limit exceeded
日志显示得很清楚了,报错原因是AWS Timestream限频了。我们能源相关的数据都是时序的,技术选型的时候时序数据库采用了Timestream,Timestream的查询吞吐量是有限制的,会根据购买的TCU(查询容量单位)来计费和分配,每个TCU会提供一定量的查询资源(包括CPU、内存、存储和网络带宽)。
而当应用发起的查询请求频率或复杂度超过当前购买的TCU配额时,Timestream就会通过返回TooManyRequests
或 ThrottlingException
等错误来限制后续请求。一般在短时间内大量并发查询、复杂查询(涉及大范围时间跨度、高基数的聚合操作或为未命中索引的查询),可能会导致TCU配额被快速耗尽。
解决
紧急措施
首先必须保证线上服务正常运行,因此决定对Timestream进行扩容,购买的一个TCU对应的资源是4个CPU和16GB的memory,这次紧急扩容了64个TCU,提供了更多的计算资源配额,支持更多并发、复杂以及高频次的查询,暂时解决了这个问题,能源统计数据得以正常显示。
追根溯源
解决了线上问题,但是不能直接结束,按照之前预测应该不会出现限频的问题,数据查询方面应该存在一定的问题,需要进一步排查,首先看一下主流的优化方案。
主流优化方案
- SQL执行日志记录与AI分析
- 开启SQL日志记录:在AWS Timestream配置中启用详细日志,记录SQL语句、执行时间等,并将日志存储至Amazon CloudWatch Logs中。
- AI统计分析:通过AWS Glue或Amazon SageMaker构建模型,对高频查询、执行时长等进行分析,识别低效SQL并分类优化。
在TimeStream对控制台上有一个新的功能,叫queryInsight,可以辅助查询优化调优。
- 高频接口缓存优化
ElastiCache应用:针对高频查询接口,采用Amazon ElastiCache(Redis或Memcached)缓存数据,降低数据库的直接查询压力。
缓存策略设计:写操作后立即更新缓存,读操作设置动态过期时间(如变化频繁数据设置过期时间,低频数据设置长过期时间)
- 数据分片与读写优化
- 分片策略:按时间、地理位置或用户ID分片,分散读写负载,例如时间序列数据按天/周分片存储
- 分区键优化:在user_id等具有唯一性的字段设置分区键(决定数据如何分布到不同分片),提升查询效率并减少TCU消耗
- 资源扩容与配置调整
- 扩展TCU:根据监控临时提升集群的Query Limit或升级TCU配置以应对高并发
- 调整热数据存储时间:延长Memory Retention时间(如12小时延长到30小时),扩大热数据缓存范围,优化查询性能
- SQL优化
- 避免全表扫描:精确指定时间范围,减少扫描数据量
- 合并宽表存储:将多条数据合并为宽表,降低I/O压力和存储成本
最终实行方案
原先我们的表没有进行分区,会导致每次数据查询都会扫全表进行查询,从而浪费大量计算资源,因此决定从数据分区进行修改。
分片策略制定
根据数据特征选择分片维度:
- Meature name分片(度量名称): 适用于时间序列数据
- 自定义Partitionkey(特定业务字段): 使用特定业务场景使用
缺点:分区键需在建表时定义,无法直接修改现有表结构,因为修改分片键需重新分配所有数据到新分片上,会导致系统长时间不可用或性能严重下降
分区键优化
在查询高频字段(如user_id等)上设置分区键,提升查询效率并降低TCU消耗,在经过多字段比较后,统一使用用户id作为分区键,以用户维度作为数据多分区查询字段。
具体方案
- 方案一:使用双写方式,新数据同时写入新旧数据表中,数据查询到时候根据数据分布情况查不同表,如果数据范围仅在旧表或仅在新表中,则分别查询对应的旧表或者新表,如果数据同时存在新表和旧表中,则使用union语句跨两张表进行查询。
- 方案二:使用双写方式,新数据同时写入新旧数据表中,同时作数据迁移。
方案对比:
方案 改动代码 数据迁移 对线上服务影响 综合对比 建议 双写+Union兼容 是 否 union查询跨新旧表时有影响,
但新表有分区键,影响是可控的1. 不需要迁移数据
2. 不需要确认数据保留时长
3. 对线上数据影响很小
4. 符合用户数据使用场景,一般用户只会查询当天最新数据,这些数据都会在新表中。采纳 双写+数据迁移 是 是 迁移数据时会影响查询 1. 需要迁移数据
2. 需要确认保留时间
3. 会影响线上服务查询
4. 迁移后数据都查询新表需要迁移数据,还需要确认数据保留时间,比较麻烦 最后综合来看,选择了方案一来进一步解决这个问题。
展望
一期方案通过分区键来进行解决,最终经测试验证,用户48小时内的最新数据查询效率提升48%,效果显著。不过为了类似问题不再发生,我们制定了二期优化方案-AWS Timestream Redis缓存。
高频接口筛选的AI分析方法
数据来源:从 Timestream 的 SQL 执行日志中提取查询接口的执行频次、响应时间、资源消耗等指标。
AI分析逻辑:
特征提取:通过日志分析工具(如 AWS CloudWatch Logs、Amazon Kinesis Data Analytics)提取查询接口的类型(如 SELECT、INSERT)、时间分布、参数模式等特征。
模式识别:利用机器学习模型(如 AWS SageMaker 的分类算法或序列模型)识别高频接口的模式,
每秒查询率(QPS)超过阈值(如 100 QPS)的接口。
响应延迟超过业务容忍值(如 200ms)的接口。
频繁访问相同或相似数据的接口(如固定时间窗口的查询)。
优先级排序:根据接口的 QPS、延迟敏感度和资源消耗,生成需要优先缓存的接口列表。
工具支持:AWS 提供的 CloudWatch Logs、Amazon Athena(日志分析)或第三方日志分析工具(如 Splunk)可用于数据提取和初步分析。
缓存引擎
缓存选型
AWS ElastiCache 提供两种引擎:Redis 和 Memcached。选型需基于业务场景需求:
引擎 | 适用场景 | 优势 | 局限性 |
---|---|---|---|
Redis | 需要支持复杂数据结构(如哈希表、列表、集合等)或需要高读写性能的场景。例如: 需要存储结构化数据(如用户会话、设备状态) ,需要原子操作(如计数器、队列管理) | 支持丰富数据类型和持久化;高并发读写性能(百万级 QPS)。 | 内存占用较高;配置复杂度略高于 Memcached。 |
Memcached | 仅需简单键值对存储且并发访问量极高(如每秒数万次请求)的场景。例如: 高频访问的静态数据(如配置信息、简单元数据) ,需要极简配置的分布式缓存 | 内存效率高;极简设计支持极高并发性能。 | 仅支持简单键值存储;无数据结构扩展;默认不支持持久化。 |
综合以上对比,Redis明显更加适合复杂业务的使用,因此计划选择Redis作为缓存引擎。
缓存策略设计:写后更新机制
核心目标:确保缓存数据与 Timestream 中的数据强一致性。
实现机制
同步更新流程:
- 应用层执行 写操作(如 INSERT、UPDATE)到 Timestream。
- 写操作成功后,触发 缓存更新事件(可通过 AWS Lambda 或应用层代码实现)。
- 立即更新 Redis/Memcached 中的对应缓存键值,覆盖旧数据。
一致性保证:
避免缓存与数据库数据不一致导致的“脏读”问题。
需确保缓存更新操作与 Timestream 写操作在事务层面的顺序性(如通过分布式锁或队列保证)。
[!WARNING]
- 写延迟风险:同步更新机制会延长写操作的总耗时,需在业务允许范围内平衡一致性与性能。
- 失败处理:若缓存更新失败(如网络中断),需设计补偿机制(如重试、异步队列处理)。
- 适用范围:仅适用于写操作与读操作强关联的场景(例如需要实时展示最新数据的仪表盘)。
分级过期策略
背景:时间序列数据的访问模式通常存在波动,分级过期策略通过动态管理缓存生命周期,平衡性能与资源占用。
分级过期策略设计
高频变化数据(TTL:5-30分钟):
- 适用场景:数据频繁更新且业务需要实时性(如传感器实时数据)。
- 实现:为这类数据设置短过期时间(TTL),确保缓存中的数据不会过时太久。
- 优势:减少因数据过期引发的缓存缺失(Cache Miss),同时避免陈旧数据被访问。
低频变化数据(TTL:24小时):
适用场景:数据更新周期较长但访问频率高(如用户配置、静态元数据)。
实现:设置较长的 TTL,延长数据在缓存中的存活时间。
优势:提高命中率,降低 Timestream 的查询压力。
主动预热机制
定义:在业务高峰前(如促销活动、每日早高峰),通过分析历史访问模式,将热点数据提前加载到缓存中。
实现步骤:
- 数据分析:通过 AWS CloudTrail 或应用日志分析历史热点数据(如高频查询的时间范围、设备 ID、用户 ID 等)。
- 触发条件:利用 AWS Lambda 或计划任务(如 cron job)在高峰前启动预热。
- 数据加载:执行批量查询(如 SELECT 语句)将数据写入缓存,并设置合适的 TTL。
实际优化中的注意事项
缓存命中率监控
监控指标:在 AWS CloudWatch 中监控以下指标:
命中率(Cache Hit Ratio):衡量缓存是否有效减少 Timestream 查询量。
缓存请求延迟:确保读取缓存的性能满足业务要求。
缓存大小与内存使用率:避免因缓存过大导致内存溢出或交换(Swap)。
告警阈值:
当命中率低于 85% 时触发告警,可能原因包括:
TTL 设置不当:热点数据过早失效。
缓存未命中策略:缓存未覆盖高频查询接口。
数据更新频率过高:导致缓存频繁失效。
Redis缓存与Timestream热数据时间调整方案的配合
Timestream 的存储分层:
Timestream 默认将数据分为 热数据(Hot Storage) 和 冷数据(Cold Storage),其中热数据存储在内存中,查询性能更高。
可通过配置调整热数据的保留时间(默认为 1 天),延长保留时间可减少冷数据访问频率,但会增加热存储成本。
优化组合:
Redis 缓存:通过缓存高频查询结果,进一步减少 Timestream 的查询压力。
热数据时间延长:确保低频但需长期保留的热点数据仍保留在热存储层,避免冷数据查询的高延迟。
实施要求:
间隔执行变更:例如:
先调整 Timestream 的热数据保留时间,观察指标(如查询延迟、成本)变化。
再实施 Redis 缓存优化,单独评估其性能提升效果。
目的:避免两个策略的效果相互干扰,便于分析优化方案的独立贡献。
最佳实践
缓存键设计:
使用有意义的键名(如 device:123:status),方便按业务维度管理缓存生命周期。
对于复杂查询,可采用 Query Caching(将 SQL 表达式哈希为键)或 Query Pattern Caching(缓存查询模式而非具体数据)。
分布式缓存:
数据一致性:Memcached 的分布式缓存基于哈希分片,需确保写操作同步到所有节点(若使用集群模式)。
缓存雪崩/击穿:采用 随机过期时间(如在基础 TTL 上随机加 0-5 分钟)和 互斥锁(如 Redis 的 Redlock 算法)缓解这些问题。
成本优化:
结合 Timestream 的按需付费模式,通过缓存减少查询量可显著降低 Timestream 费用。
Redis 的持久化(如 RDB、AOF)需谨慎配置,避免额外 I/O 开销。
线上救急-AWS限频的更多相关文章
- HBase工程师线上工作经验总结----HBase常见问题及分析
阅读本文可以带着下面问题:1.HBase遇到问题,可以从几方面解决问题?2.HBase个别请求为什么很慢?你认为是什么原因?3.客户端读写请求为什么大量出错?该从哪方面来分析?4.大量服务端excep ...
- (转)HBase工程师线上工作经验总结----HBase常见问题及分析
阅读本文可以带着下面问题:1.HBase遇到问题,可以从几方面解决问题?2.HBase个别请求为什么很慢?你认为是什么原因?3.客户端读写请求为什么大量出错?该从哪方面来分析?4.大量服务端excep ...
- 如何有效的跟踪线上 MySQL 实例表和权限的变更
介绍 从系统管理员或 DBA 的角度来讲, 总期望将线上的各种变更限制在一个可控的范围内, 减少一些不确定的因素. 这样做有几点好处: . 记录线上的库表变更; . 对线上的库表变更有全局的了解; . ...
- 性能提速:debounce(防抖)、throttle(节流/限频)
debounce与throttle是用户交互处理中常用到的性能提速方案,debounce用来实现防抖动,throttle用来实现节流(限频).那么这两个方法到底是什么(what)?为何要用(why-解 ...
- 简述C#中IO的应用 RabbitMQ安装笔记 一次线上问题引发的对于C#中相等判断的思考 ef和mysql使用(一) ASP.NET/MVC/Core的HTTP请求流程
简述C#中IO的应用 在.NET Framework 中. System.IO 命名空间主要包含基于文件(和基于内存)的输入输出(I/O)服务的相关基础类库.和其他命名空间一样. System.I ...
- DBAplus社群线上分享----Sharding-Sphere之Proxy初探
功能 Cobar Mycat Heisenberg Shark TDDL Sharding-JDBC 是否开源 开源 开源 开源 开源 部分开源 开源 架构模型 Proxy架构 Proxy架构 Pro ...
- Jedis线上的一个小坑:Redis有并发访问的数据错乱的问题
问题现象: 业务数据有错乱,A的一些数据有好几个都是B的数据 这些业务数据在保存在Redis缓存中,怀疑是并发情况下Jedis错乱的问题 原因分析: JedisUtil里面在使用完Jedis 后释放资 ...
- 线上应用接入sentinel的第一个流控规则
sentinel接入第1个应用A以及控制台,已经上线一段时间了,本周接入了第2个应用B: 因为测试同学只有几个,没有压测团队.测试平台.. 各接口能承载的最大qps不确定 ,接入的应用暂时都没有配置规 ...
- 线上SpringCloud网关调用微服务跨机房了,咋整?
1.前言 公司内考虑到服务器资源成本的问题,目前业务上还在进行服务的容器化改造和迁移,计划将容器化后的服务,以及一些中间件(MQ.DB.ES.Redis等)尽量都迁移到其他机房. 那你们为什么不用阿里 ...
- 线上服务的FGC问题排查,看这篇就够了!
线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力.同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验. 过去半年时间里,我们的广告 ...
随机推荐
- 从一指禅到无重复字符:最长子串问题的优雅解法|LeetCode 3 无重复字符的最长子串
LeetCode 3 无重复字符的最长子串 点此看全部题解 LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中) 生活中的算法 你是否玩过"一指禅"游戏?就是沿 ...
- 第一!天翼云领跑中国边缘云laaS市场!
近日,弗若斯特沙利文(Frost & Sullivan,简称"沙利文")联合头豹研究院发布<2023年中国边缘云市场报告>,天翼云在2023H1中国边缘云Iaa ...
- mac 安装ActiveMQ
1.http://activemq.apache.org/activemq-5154-release.html 选gz 2.cd apache-activemq-5.15.4/bin/macosx 3 ...
- Luogu P7735 NOI2021 轻重边 题解 [ 紫 ] [ 树链剖分 ] [ 线段树 ]
轻重边:小清新树剖题. 思路 我们可以给每一个赋重边的操作看做给这些点盖上一个时间戳,那么显然一条边是重边,当且仅当这条边两端的点的时间戳相等.因为一个点如果被后面的时间戳覆盖之后他相邻的边都会被波及 ...
- deepseek等AI工具是程序员技能发展的双刃剑
2025年,全球已有73%的程序员日常使用AI编码工具(Gartner 2025Q1数据).当我们惊叹于GitHub Copilot生成完整功能模块仅需10秒时,也需要警惕一个现象:新一代程序员在ID ...
- Markdown语法基础教学
Markdown语法基础教学 简介 Markdown是一种轻量级的标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成结构化的HTML.它的目标是实现"易读易写",并且 ...
- JavaScript 滚动条滚动到底部才触发按钮是否可用
应用代码片段: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- FANUC发那科工业机器人减速器维修小细节
在现代工业生产中,FANUC发那科机器人已成为不可或缺的一部分.然而,随着时间的推移,发那科机械手减速器可能会出现故障,影响机器人的正常工作. 一.了解减速器的结构与工作原理 在开始FANUC发那科机 ...
- 附039.Kubernetes_v1.32.2高可用部署架构二
部署组件 该 Kubernetes 部署过程中,对于部署环节,涉及多个组件,主要有 kubeadm .kubelet .kubectl. kubeadm介绍 Kubeadm 为构建 Kubernete ...
- 一种基于虚拟摄像头、NDI、OBS以及yolo的多机视觉目标检测方案
一种基于虚拟摄像头.NDI.OBS以及yolo的多机视觉目标检测方案 绪论 近来为了实现某种实时展示效果,笔者希望通过一套方案实现在两台主机上分别运行仿真平台以及视觉深度学习算法.透过对当下较为流行的 ...