首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

线上救急-AWS限频

  • 25-04-23 04:41
  • 4430
  • 12935
juejin.cn

线上救急-AWS限频

问题

在一个天气炎热的下午,我正喝着可口可乐,悠闲地看着Cursor生成代码,忽然各大群聊中出现了加急➕@全体的消息,当时就心里一咯噔,点开一看,果然,线上服务出问题,多个能源统计接口报错未返回数据。

排查

首先排查线上ES日志,查询能源统计接口的日志中存在大量报错,报错提示如下:

yaml
代码解读
复制代码
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,提供了更多的计算资源配额,支持更多并发、复杂以及高频次的查询,暂时解决了这个问题,能源统计数据得以正常显示。

追根溯源

解决了线上问题,但是不能直接结束,按照之前预测应该不会出现限频的问题,数据查询方面应该存在一定的问题,需要进一步排查,首先看一下主流的优化方案。

主流优化方案
  1. SQL执行日志记录与AI分析
  • 开启SQL日志记录:在AWS Timestream配置中启用详细日志,记录SQL语句、执行时间等,并将日志存储至Amazon CloudWatch Logs中。
  • AI统计分析:通过AWS Glue或Amazon SageMaker构建模型,对高频查询、执行时长等进行分析,识别低效SQL并分类优化。

在TimeStream对控制台上有一个新的功能,叫queryInsight,可以辅助查询优化调优。

  1. 高频接口缓存优化

ElastiCache应用:针对高频查询接口,采用Amazon ElastiCache(Redis或Memcached)缓存数据,降低数据库的直接查询压力。

缓存策略设计:写操作后立即更新缓存,读操作设置动态过期时间(如变化频繁数据设置过期时间,低频数据设置长过期时间)

  1. 数据分片与读写优化
  • 分片策略:按时间、地理位置或用户ID分片,分散读写负载,例如时间序列数据按天/周分片存储
  • 分区键优化:在user_id等具有唯一性的字段设置分区键(决定数据如何分布到不同分片),提升查询效率并减少TCU消耗
  1. 资源扩容与配置调整
  • 扩展TCU:根据监控临时提升集群的Query Limit或升级TCU配置以应对高并发
  • 调整热数据存储时间:延长Memory Retention时间(如12小时延长到30小时),扩大热数据缓存范围,优化查询性能
  1. SQL优化
  • 避免全表扫描:精确指定时间范围,减少扫描数据量
  • 合并宽表存储:将多条数据合并为宽表,降低I/O压力和存储成本
最终实行方案

原先我们的表没有进行分区,会导致每次数据查询都会扫全表进行查询,从而浪费大量计算资源,因此决定从数据分区进行修改。

  1. 分片策略制定

    根据数据特征选择分片维度:

    • Meature name分片(度量名称): 适用于时间序列数据
    • 自定义Partitionkey(特定业务字段): 使用特定业务场景使用

    缺点:分区键需在建表时定义,无法直接修改现有表结构,因为修改分片键需重新分配所有数据到新分片上,会导致系统长时间不可用或性能严重下降

  2. 分区键优化

    在查询高频字段(如user_id等)上设置分区键,提升查询效率并降低TCU消耗,在经过多字段比较后,统一使用用户id作为分区键,以用户维度作为数据多分区查询字段。

  3. 具体方案

    • 方案一:使用双写方式,新数据同时写入新旧数据表中,数据查询到时候根据数据分布情况查不同表,如果数据范围仅在旧表或仅在新表中,则分别查询对应的旧表或者新表,如果数据同时存在新表和旧表中,则使用union语句跨两张表进行查询。
    • 方案二:使用双写方式,新数据同时写入新旧数据表中,同时作数据迁移。

    方案对比:

    方案改动代码数据迁移对线上服务影响综合对比建议
    双写+Union兼容是否union查询跨新旧表时有影响, 但新表有分区键,影响是可控的1. 不需要迁移数据 2. 不需要确认数据保留时长 3. 对线上数据影响很小 4. 符合用户数据使用场景,一般用户只会查询当天最新数据,这些数据都会在新表中。采纳
    双写+数据迁移是是迁移数据时会影响查询1. 需要迁移数据 2. 需要确认保留时间 3. 会影响线上服务查询 4. 迁移后数据都查询新表需要迁移数据,还需要确认数据保留时间,比较麻烦

    最后综合来看,选择了方案一来进一步解决这个问题。

展望

一期方案通过分区键来进行解决,最终经测试验证,用户48小时内的最新数据查询效率提升48%,效果显著。不过为了类似问题不再发生,我们制定了二期优化方案-AWS Timestream Redis缓存。

高频接口筛选的AI分析方法

  • 数据来源: 从 Timestream 的 SQL 执行日志中提取查询接口的执行频次、响应时间、资源消耗等指标。
  • AI分析逻辑:

    1. 特征提取: 通过日志分析工具(如 AWS CloudWatch Logs、Amazon Kinesis Data Analytics)提取查询接口的类型(如 SELECT、INSERT)、时间分布、参数模式等特征。
    1. 模式识别: 利用机器学习模型(如 AWS SageMaker 的分类算法或序列模型)识别高频接口的模式,

      • 每秒查询率(QPS)超过阈值(如 100 QPS)的接口。
      • 响应延迟超过业务容忍值(如 200ms)的接口。
      • 频繁访问相同或相似数据的接口(如固定时间窗口的查询)。
    1. 优先级排序: 根据接口的 QPS、延迟敏感度和资源消耗,生成需要优先缓存的接口列表。
  • 工具支持: AWS 提供的 CloudWatch Logs、Amazon Athena(日志分析)或第三方日志分析工具(如 Splunk)可用于数据提取和初步分析。

缓存引擎

缓存选型

AWS ElastiCache 提供两种引擎:Redis 和 Memcached。选型需基于业务场景需求:

引擎适用场景优势局限性
Redis需要支持复杂数据结构(如哈希表、列表、集合等)或需要高读写性能的场景。例如: 需要存储结构化数据(如用户会话、设备状态) ,需要原子操作(如计数器、队列管理)支持丰富数据类型和持久化;高并发读写性能(百万级 QPS)。内存占用较高;配置复杂度略高于 Memcached。
Memcached仅需简单键值对存储且并发访问量极高(如每秒数万次请求)的场景。例如: 高频访问的静态数据(如配置信息、简单元数据) ,需要极简配置的分布式缓存内存效率高;极简设计支持极高并发性能。仅支持简单键值存储;无数据结构扩展;默认不支持持久化。

综合以上对比,Redis明显更加适合复杂业务的使用,因此计划选择Redis作为缓存引擎。

缓存策略设计:写后更新机制

核心目标: 确保缓存数据与 Timestream 中的数据强一致性。

实现机制

  • 同步更新流程:

    1. 应用层执行 写操作(如 INSERT、UPDATE)到 Timestream。
    2. 写操作成功后,触发 缓存更新事件(可通过 AWS Lambda 或应用层代码实现)。
    3. 立即更新 Redis/Memcached 中的对应缓存键值,覆盖旧数据。
  • 一致性保证:

    • 避免缓存与数据库数据不一致导致的“脏读”问题。
    • 需确保缓存更新操作与 Timestream 写操作在事务层面的顺序性(如通过分布式锁或队列保证)。
  • 写延迟风险:同步更新机制会延长写操作的总耗时,需在业务允许范围内平衡一致性与性能。
  • 失败处理:若缓存更新失败(如网络中断),需设计补偿机制(如重试、异步队列处理)。
  • 适用范围:仅适用于写操作与读操作强关联的场景(例如需要实时展示最新数据的仪表盘)。

分级过期策略

背景: 时间序列数据的访问模式通常存在波动,分级过期策略通过动态管理缓存生命周期,平衡性能与资源占用。

分级过期策略设计
  • 高频变化数据(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 的查询压力。
    • 热数据时间延长:确保低频但需长期保留的热点数据仍保留在热存储层,避免冷数据查询的高延迟。
  • 实施要求:

    • 间隔执行变更:例如:

      1. 先调整 Timestream 的热数据保留时间,观察指标(如查询延迟、成本)变化。
      1. 再实施 Redis 缓存优化,单独评估其性能提升效果。
    • 目的:避免两个策略的效果相互干扰,便于分析优化方案的独立贡献。

最佳实践

  1. 缓存键设计:

    • 使用有意义的键名(如 device:123:status),方便按业务维度管理缓存生命周期。
    • 对于复杂查询,可采用 Query Caching(将 SQL 表达式哈希为键)或 Query Pattern Caching(缓存查询模式而非具体数据)。
  1. 分布式缓存:

    • 数据一致性:Memcached 的分布式缓存基于哈希分片,需确保写操作同步到所有节点(若使用集群模式)。
    • 缓存雪崩/击穿:采用 随机过期时间(如在基础 TTL 上随机加 0-5 分钟)和 互斥锁(如 Redis 的 Redlock 算法)缓解这些问题。
  1. 成本优化:

    • 结合 Timestream 的按需付费模式,通过缓存减少查询量可显著降低 Timestream 费用。
    • Redis 的持久化(如 RDB、AOF)需谨慎配置,避免额外 I/O 开销。
注:本文转载自juejin.cn的LemonDu的文章"https://juejin.cn/post/7495532653219790875"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top