AWS代付、代实名
阿里云国际 | 腾讯云国际

亚马逊云科技图数据库Neptune与开源Neo4j基于Pokec社交数据的性能测试和场景总结

AWS账单代付阅读(58)

亚马逊AWS官方博客

亚马逊云科技图数据库Neptune与开源Neo4j基于Pokec社交数据的性能测试和场景总结

一.概述

在当今数据驱动的时代,图数据库已成为处理复杂关系数据的关键技术。本文基于Pokec社交网络数据集(包含163万用户和3062万关系边),对市场上主流的图数据库解决方案进行了全面的性能测试和对比分析。我们选择了Amazon Neptune(OpenCypher和Gremlin两种查询语言)、Neo4j作为测试对象,通过严格控制的测试环境和方法,从吞吐量、响应时间、并发扩展性等多个维度进行了深入评估。

本次测试旨在为企业在选择图数据库时提供客观、全面的参考依据,帮助技术决策者根据自身业务场景选择最适合的图数据库解决方案。测试结果显示,不同的图数据库在各种查询场景下表现各异,需要根据具体应用场景和需求进行选择。

二.压测环境和压测方式

2.1.压测环境配置

所有测试均在AWS云平台上进行,为确保公平对比,我们为每个数据库使用了相同逻辑的测试脚本,所有测试基于单节点,且所有的数据全都缓存到内存内进行测试比对,仅在连接方式和查询语法上进行了必要的适配,以确保环境一致性和可重复性:

|

类别

|

规格

|

CPU

|

内存

|

其他

|

压测机器

|

c6in.16xlarge

|

64vCPU

|

128GB

|

Neo4j压测脚本

|

压测机器

|

c6in.16xlarge

|

64vCPU

|

128GB

|

Neptune压测脚本

|

Neo4j

|

r8g.4xlarge

|

16vCPU

|

128GB

|

Neo4j版本5.15.0社区开源版,数据存储在100GB的gp2 EBS

|

Neptune

|

r8g.4xlarge

|

16vCPU

|

128GB

|

Neptune版本1.4.5.1

2.2.压测方法

  • 数据集:Pokec社交网络数据,包含163万用户和3062万关系边,来自学术资源库SNAP(Stanford Network Analysis Project)
  • 并发线程:16线程
  • 测试时长:每轮测试持续3分钟
  • 查询类型:从0跳到5跳加上统计类查询的7种关系查询,覆盖从简单到复杂的各种场景
  • 查询权重分布:单点查询25%,1跳20%,2跳18%,3跳15%,4跳10%,5跳7%,统计类查询5%
  • 测试指标:QPS、平均响应时间、P95响应时间、P99响应时间、成功率等
  • 三.压测对比和分析

    3.1.核心性能对比结果

|

指标

|

Neptune OpenCypher

|

Neo4j

|

Neptune Gremlin

|

QPS

|

439.3

|

396.8

|

124.8

|

平均响应时间

|

32.50ms

|

37.02ms

|

119.60ms

|

P95响应时间

|

28.93ms

|

106.86ms

|

186.91ms

|

P99响应时间

|

34.75ms

|

143.65ms

|

221.45ms

|

成功率

|

91.67%

|

100%

|

100%

|

总查询数

|

86,269

|

71,450

|

22,490

从核心性能指标来看,Neptune OpenCypher吞吐量和响应时间方面表现最为出色,QPS达到439.3,比Neo4j高出约10.7%,比Neptune Gremlin高出约252%。对应,在极端情况下的处理上,3s超时的情况下Neptune OpenCypher在目标测试集上超时的情况下会有8.33%存在超时的情况。

总体而言,Neptune OpenCypher在整体核心性能上查询的稳定性性比较高,其中平均响应时间,p95 和 p99都是三种方式中最低的且比较接近,Neo4j的p95 和 p99 响应时间会超出平均响应时间接近两倍。

3.2.不同跳数查询的响应时间对比

|

跳数

|

Neptune OpenCypher

|

Neo4j

|

Neptune Gremlin

|

0跳(单点)

|

32.65ms

|

9.03ms

|

107.58ms

|

1跳

|

28.39ms

|

50.40ms

|

125.25ms

|

2跳

|

36.06ms

|

57.64ms

|

132.13ms

|

3跳

|

35.24ms

|

43.49ms

|

121.39ms

|

4跳

|

31.98ms

|

35.71ms

|

115.67ms

|

5跳

|

32.41ms

|

24.24ms

|

111.79ms

在不同跳数的测试比对中,可以看出Neptune OpenCypher 在5跳以内查询性能比较稳定。

四.技术架构对比分析

三种图数据库在技术架构上存在显著差异:

4.1.连接方式对比

|

连接方式

|

Remark

|

Neptune

|

采用HTTP短连接方式,通过HTTPS协议和AWS SigV4认证机制进行通信。

|

这种连接方式特别适合高并发场景,因为它不会长期占用服务器资源,但每次查询都需要重新建立连接,因此存在一定的连接开销。在大规模分布式环境中,这种方式能够支持更多的并发连接,但可能会增加单次查询的延迟。

|Neptune

Gremlin

|使用WebSocket长连接技术,通过WSS协议和AWS SigV4认证保障通信安全。

|长连接模式建立后可持续使用,显著降低了连续查询的延迟,特别适合需要频繁交互的应用场景。然而,由于每个连接会占用服务器资源,其并发能力相对受限,在高并发环境下可能需要额外的连接池管理策略。

|

Neo4j

|采用专有的Bolt长连接协议,结合用户名密码的认证方式,提供了稳定可靠的连接体验。

|

Bolt协议经过专门优化,能够高效处理图数据传输,且由于是本地可控的连接机制,用户可以根据实际需求灵活调整连接参数,在性能和安全性之间取得平衡。

4.2.查询语言对比

|

查询语言

|

Remark

|

Neptune

|

Neptune OpenCypher基于OpenCypher规范实现,采用声明式SQL类语法,使得从关系型数据库迁移的用户能够快速上手。

|

其查询优化器经过AWS专门调优,能够高效处理复杂的图模式匹配操作,学习成本相对较低,适合快速开发和原型设计。

|

Neptune

|

Neptune Gremlin基于Apache TinkerPop

|

这种方式提供了更细粒度的查询控制,但学习曲线较陡峭,需要开发者对图遍历概念有深入理解。虽然优化程度中等,但在某些特定场景下可以通过手动优化获得更好性能。

|

Neo4j

|

Neo4j的原生Cypher语言是最成熟的图查询语言之一,采用声明式SQL类语法,结合了直观的图模式表达方式。

|

Neo4j对Cypher进行了深度优化,能够高效处理各种复杂查询模式,且有丰富的学习资源和社区支持,使得学习门槛相对较低。

这些架构和语言特性的差异直接影响了各数据库在不同应用场景中的表现。Neptune OpenCypher的HTTP短连接模式虽然有连接开销,但在云环境和高并发系统中表现出色;Neo4j的Bolt协议在稳定性和可控性方面具有明显优势;而Neptune Gremlin的WebSocket长连接则在需要复杂图遍历的专业应用中提供了更精确的控制能力和更低的持续交互延迟。

4.3.横向扩展特性对比

|

扩展特性

|

Neptune

|

Neptune在横向扩展方面具有显著的云原生优势。它支持1个写节点配合最多15个读副本的集群架构,能够实现真正的读写分离。

AWS托管的读副本端点提供自动负载均衡功能,将查询请求智能分发到各个读副本节点。

更重要的是,Neptune支持弹性扩展,可以根据业务负载动态添加或删除读副本,整个扩展过程对正在运行的业务完全无影响。所有节点共享同一个存储层,数据一致性完全由AWS底层架构保障,无需用户干预。

|

Neo4j

|

Neo4j开源版本在扩展能力上存在明显限制。开源版本仅支持单实例部署,无法实现读写分离,这意味着所有读写操作都必须在同一个节点上处理。

当面临高并发访问时,Neo4j开源版主要依靠垂直扩展(提升单机硬件配置)来提升性能,这种方式不仅成本高昂,而且存在明显的性能天花板。

五.性能总结

Neptune OpenCypher在高并发Web应用中表现卓越,QPS达到439.3,分别比Neo4j和Neptune Gremlin高出10.7%和252%。其HTTP短连接模式天然适配云环境的大规模访问,查询稳定性优异,平均响应时间、p95和p99指标均为最低且数值接近,性能波动小。优化的查询引擎在复杂多跳关系查询中表现稳定,特别适合高并发Web应用(QPS > 400)、需要频繁执行复杂关系查询的实时系统,以及云原生架构的图数据应用。需要注意的是,在3秒超时设置下,约8.33%的查询可能超时,需在高可用系统设计中预留容错机制。

Neo4j凭借成熟的架构和专有Bolt协议确保了企业级的稳定性和可靠性。其查询缓存和优化机制提供一致的性能体验,拥有完整的企业级部署选项和管理工具,以及丰富的生态系统和社区支持。Neo4j特别适合关键业务系统(要求100%可靠性)、以单点查询为主的应用、传统企业环境(特别是对数据安全性和操作透明度有严格要求的场景),以及需要本地部署控制的环境。但需要注意的是,在高负载下p95和p99响应时间可能达到平均响应时间的两倍,存在一定性能波动。

Neptune Gremlin的命令式查询模型在复杂图算法实现中具有独特优势。其WebSocket长连接模式确保连续操作的低延迟,细粒度操作能力支持精确遍历控制,与TinkerPop生态系统完全兼容,扩展性强。虽然QPS表现相对较低,但在图数据科学和复杂分析应用、需要实现自定义图算法的场景、对查询执行过程需要精确控制的应用,以及要求极高稳定性的连续操作系统中,其灵活性和控制能力无可替代。对于特定的图算法实现和需要精确遍历控制的场景,Neptune Gremlin是理想的选择。

六.场景建议

6.1.1000+ QPS高负载场景

在面对1000+ QPS的高负载需求时,Neptune OpenCypher展现出显著的扩展效率优势。基于16 vCPU单节点439.3 QPS的性能基准,Neptune OpenCypher仅需要约3-4个实例即可满足1000+ QPS的业务需求,而Neo4j需要约4-5个实例,Neptune Gremlin则需要约10-12个实例才能达到相同的吞吐量水平。这种差异在成本控制和资源利用率方面具有重要意义,特别是对于需要快速扩展的互联网应用而言。

值得注意的是,Neo4j开源版本在高负载场景下面临严重的扩展瓶颈,无法进行水平扩容,只能通过升级单机硬件配置或采用成本更高的企业版本来解决性能问题。这种架构限制使得Neo4j在处理大规模并发访问时缺乏灵活性,而Neptune OpenCypher的云原生架构天然支持弹性扩展,可以根据业务负载动态调整实例数量。

6.2.低延迟场景

在对响应时间要求严格的低延迟场景中,Neptune OpenCypher平均响应时间为32.5ms,且性能表现稳定可预测。相比之下,Neo4j在单点查询时可以满足低延迟要求,但在复杂多跳关系查询中往往难以维持稳定的低延迟表现。Neptune Gremlin由于平均响应时间高达119.6ms,在严格的低延迟场景中难以满足业务需求。

需要注意的是,在3秒超时设置下,Neptune OpenCypher约有8.33%的查询可能出现超时情况,这在设计高可用系统时需要预留相应的容错机制。尽管如此,其整体的性能稳定性和扩展能力仍然使其成为高并发图数据库应用的首选方案,特别适合需要在云环境中快速部署和扩展的现代Web应用架构。

七.结语

本文基于Pokec社交网络数据的图数据库性能测试,全面评估了Neo4j、Neptune OpenCypher和Neptune Gremlin三种主流图数据库解决方案的性能特点。Neptune OpenCypher在高并发云原生场景和低延时场景中展现出卓越的性能优势和扩展能力,特别适合现代Web应用的弹性架构需求。

随着数据规模的持续增长和业务复杂度的不断提升,图数据库技术将继续演进。企业在进行技术选型时,应综合考虑当前业务需求、未来扩展规划、团队技术能力以及总体拥有成本等多个维度,选择最适合自身发展阶段和业务特点的图数据库解决方案。同时,建议在正式部署前进行充分的概念验证测试,以确保所选方案能够满足实际业务场景的性能和功能要求。

八.参考资料

  • SNAP: Network datasets: Pokec social network – https://snap.stanford.edu/data/soc-Pokec.html
  • Amazon Neptune 官方文档 – https://docs.aws.amazon.com/neptune/
  • Neo4j 性能优化指南 – https://neo4j.com/developer/guide-performance-tuning/
  • Graph Database Benchmarks – https://www.arangodb.com/2018/02/nosql-performance-benchmark-2018-mongodb-postgresql-orientdb-neo4j-arangodb/
  • AWS Database Blog: Performance best practices for Amazon Neptune – https://aws.amazon.com/blogs/database/
  • Gremlin: A Graph Traversal Language – https://tinkerpop.apache.org/gremlin.html
  • OpenCypher Project – https://www.opencypher.org/
  • *前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。


使用大模型技术构建机票分销领域人工智能客服助手

AWS账单代付阅读(69)

亚马逊AWS官方博客

使用大模型技术构建机票分销领域人工智能客服助手

一. 需求背景

1.1 行业痛点

在机票分销领域,大型票务代理是供应链的中转枢纽,他们上游对接各大航空公司,下游对接各中小型票务代理、OTA(Online Travel Agency在线旅行社)或者旅行社等。大型票务代理通常会部署虚拟客服系统,来应对其下游生态圈企业的机票查询、预定和退改签等咨询业务。然而由于传统虚拟客服在技术上的局限性,用户经常遭遇“听不懂”、“答不准”或者“答非所问”等尴尬。

随着人工智能技术的飞速发展,利用大语言模型等技术,实现更准确更聪明的人工智能客服助手成为了可能。然而,对于大型票务代理来说,这件事并不简单。

构建机票分销领域人工智能客服助手的难点主要体现在以下几个方面:

知识分散且零散:文档种类多样,且分散在不同地方保存; 知识专业性强:机票销售领域知识,与通用知识存在很大的差异性; 提问方式较随意:客户提问时口语化、随意化,且经常夹杂行业“黑话”; 常规方案准确率低:具体表现在不能正确理解问题,回答错误或者胡编乱造(幻觉)。

1.2 项目目标

本项目的目标是构建一套机票分销领域人工智能客服助手,主要实现以下功能:

集中存储行业知识:零散分布的行业领域文档,如机票分销基础知识、航司近期活动、运营政策等,经过预处理后,将向量化知识分块集中存储和管理; 准确理解用户意图:从自然语言中准确识别用户的意图,例如询问的是运营政策、退改签政策,还是近期某航司是否有活动等; 精准检索行业知识:能够从知识库中准确找到指定信息,例如某航司团队票是否可以按散客票出票; 生成标准答案:能够从检索到的知识中加工并处理成大型票务代理预期的正确答案; 高容错性:能够处理不同的口语化表达,并识别行业内才能听懂的“黑话”,例如“出配置”、“打配置”、“本地没牌”等。

二. 方案概述

2.1 系统架构

系统总体架构如下图所示,与标准RAG(Retrieval-Augmented Generation检索增强生成)架构基本一致但稍有区别。由数据预处理、知识库存储、查询解析、检索、文本生成、用户交互界面等模块组成。各个模块分别执行独立的任务,并与其他模块进行配合,形成完成的处理流程。

2.2 系统核心模块

2.2.1 数据预处理

数据预处理是构建高质量问答系统的关键环节,主要目的是将原始知识内容转换成适合检索和生成使用的格式,其主要功能包括:

  • 文本清洗与格式统一:例如去除无用符号、空格、换行、标点符号、无用信息,将文本格式整理为统一格式等;
  • 分段与结构化拆分:将长文本按照段落或语义切分为不同分段(Chunk)或问答对等;
  • 词嵌入(Embedding)向量化准备:去除不适合向量化的内容。
  • 2.2.2 知识库存储

知识库存储提供了各类文档存储和管理的功能,其主要功能包括:

知识内容管理:支持存储各种类型的文本,并对内容进行管理; 向量化索引支持:将文本内容进行词嵌入(Embedding)向量化,并构建向量索引; 关键词索引支持:支持关键词级别的高效查询; 提供检索接口:提供支持多种检索方式的接口,供RAG框架调用。

2.2.3 查询解析

查询解析模块借助大语言模型,对用户输入进行解析,精准识别用于意图。主要功能包括:

意图识别:识别用户提问的意图,如询问退改签政策、运营政策、航司活动等不同诉求; 关键词提取:提取用户提问中的关键实体、词汇,例如X航、XX航空等; 上下文理解:多轮对话场景中,当前问题结合历史上下文(聊天记录)进行解析; 行业“ 黑话”:对只在机票分销领域出现的专有名词进行识别和解析,例如“出配置”、“大配置”、“本地没牌”等。

2.2.4 混合检索

向量检索

向量检索模块是构建知识库系统的核心技术之一,它通过将文本信息编码成向量,再进行相似度计算,实现用户提问与知识库内容的匹配,其主要功能包括:

文本向量化**:通过词嵌入(Embedding)模型将文档转换为向量,便于计算机处理; **相似度计算**:通过算法找到与用户输入最相似的知识库内容; **支持模糊表达**:用户表达可能是口语化、不完整,或者同义词,向量检索可以支持这种模糊表达,识别其含义。 **关键词检索

关键词检索通过匹配用户查询中的关键词,实现高效、精准的内容定位和快速召回,其主要功能为:

快速定位精确匹配内容**:精准命中包含关键词的文本片段、标题或字段; **补充向量检索盲点**:对专有名词难以向量化的关键词进行补充检索,提升召回率; **实现混合检索**:在向量检索后,可能出现多段内容相似,此时通过关键词检索再次进行过滤,更精准的找到所需知识库内容。 **混合检索

本项目中,我们将向量检索和关键词检索结合使用,这么做的优势有如下几点:

  • 先广后精,保证召回质量 + 补充覆盖率;
  • 提升重要关键词的召回优先级;
  • 增加参考信息的多样性,利于生成更完整回答。
  • 2.2.5 文本生成

文本生成模块通过调用大语言模型回答用户提问,实现智能问答,其主要功能包括:

基于检索内容生成自然语言回答:将检索到的知识,结合用户提问,生成语句通顺、语义完整、有针对性的回答; 补全知识内容中的语义空白:当检索或表达不完整时,大模型可以通过推理来构建完整的逻辑链条,以此来提高问答的完整性; 提升多轮对话的上下文连贯性:在用户多轮提问的场景下,结合上下文形成连贯自然的回答。

2.2.6 用户交互界面

用户交互界面提供简单易用的人机交互方式,用户输入自然语言提问,系统可以检索知识并返回自动生成的答案。其主要功能包括:

用户输入处理:提供交互窗口,接受用户的自然语言输入,为后续处理做准备。 结果展示:直观展示生成的答案(文本内容),供用户查看并等待用户下一步指令; 错误处理:如果系统运行中报错,将错误信息直观展示给用户供其故障排查; 用户反馈:如果用户对系统生成的答案不满意,可以在界面上进行反馈。

三. 技术实现

3.1 数据处理

根据经验,将数据按照不同组织形式进行针对性处理,会有效提高知识库问答准确率。数据预处理这一步骤主要的作用是将原始文档按照不同文本形式拆分并转换后,再合并成新的处理后的文档,之后将其内容注入向量数据库,并提取关键词注入关键词数据库,如下图所示:

以下是原始文档处理后的Markdown格式问答对:

以下是原始文档处理后的包含多个Json串的表:

3.2 知识库存储

知识库存储由向量数据库和关键词数据库两部分组成,分别用于向量检索和关键词检索。

3.2.1 向量数据库

经过评估,我们选择了DocArrayInMemorySearch作为向量数据库,其作为内存型向量数据库,有以下优势:

开箱即用、无需部署数据库:直接使用Python引入即可使用,不需要额外部署; 支持多模态数据结构:支持多模态数据的表示与检索;内置DocArray文档结构,字段灵活,支持带元数据、标签的检索; 支持嵌套结构与批量操作:支持嵌套文档结构(如带上下文的QA对),方便组织复杂文档;提供批量插入、批量检索等常用API,简单易用。

向量数据库创建的部分代码如下:

3.2.2 关键词数据库

关键词数据库,我们选择了defaultdict,它具有以下优势:

自动为关键词初始化:defaultdict 可以自动为每个关键词初始化一个空列表,避免手动判断关键词是否存在; 结构简单、访问速度快:本质是哈希表,适合快速匹配关键词,速度快、延时低; 方便与RAG 系统结合使用:可以作为向量检索的补充;支持一对多映射。

关键词数据库创建的部分代码如下:

3.3 查询解析

查询解析模块,我们调用大语言模型来理解用户输入,识别用户意图并提取关键信息。

3.3.1 大语言模型选型

大语言模型的选择直接影响到知识库系统的整体性能和用户体验。Amazon Bedrock Claude非常适合作为知识库系统的大语言模型底座来使用,其主要有三大优势:

强大的长文本理解能力:Claude 3系列支持长上下文窗口(最高128 K Tokens),非常适合处理大型文档和多段引用内容; 出色的语言理解和推理能力:Claude 3在多轮对话理解、模糊提问解析和知识归纳方面表现优秀,尤其适合复杂问句和多轮对话式问答; 企业级托管+ 合规性保障:Amazon Bedrock提供无需部署模型的全托管服务,按需调用,免维护;同时满足数据私有、本地加密、权限管控等企业级合规保障。

3.3.2 系统提示词设计

在本项目中,用户提问时,可能使用航司名称,也可能会使用航司代码(AA、BB);系统要自动识别这些代码并转换为知识库中对应的航司名称,可以外挂一个航司代码列表来实现,但这种做法后续维护不便;更好的做法是使用Amazon Bedrock Claude大模型来自动识别。

以下是查询解析模块对应的代码:

3.4 混合检索

3.4.1 Embedding模型选型

经过评估,我们选择了BAAI/bge-large-zh-v1.5作为Embedding模型,主要基于以下考虑:

成熟且应用广泛:开源中最稳定、社区应用最多的中文Embedding模型; 为中文优化,语义理解能力强:专为中文语义检索任务训练,更好地理解中文表达; 支持查询增强:原生支持带指令的查询嵌入(Embedding),能显著提升模型对检索场景的理解力和效果。

3.4.2 Embedding模型配置

Embedding模型配置的部分代码如下:

from langchain.docstore.document import Document

from langchain_community.vectorstores import DocArrayInMemorySearch

from langchain_community.embeddings.huggingface import HuggingFaceBgeEmbeddings

设置词嵌入(Embedding)模型

modelPath = “BAAI/bge-large-zh-v1.5”

model_kwargs = {‘device’:’cuda’}

encode_kwargs = {‘normalize_embeddings’: True}

embeddings = HuggingFaceBgeEmbeddings(

model_name=modelPath,

model_kwargs=model_kwargs,

encode_kwargs=encode_kwargs,

query_instruction=”为这个句子生成表示以用于检索相关文章:”

)

embeddings.query_instruction = “为这个句子生成表示以用于检索相关文章:”

创建向量数据库

vector_db = DocArrayInMemorySearch.from_documents(db_documents, embeddings)

3.4.3 混合检索实现

混合检索的优势我们前文已经描述,这部分实现的代码如下:

3.5 指令生成

使用Amazon Bedrock Claude回答用户问题,除了用户Query外,还需要提供三部分信息:航司代码对照表、相关知识片段、客户业务知识。客户业务知识是基于客户提供的补充语料整理出的内容,主要对其中出票相关的规则再次进行了梳理,使这部分规则更明确清楚,目的是让大模型可以识别行业“黑话”。指令生成我们主要使用标准大语言模型,通过附加定制的提示词的方式来实现。

以下是提示词部分的参考代码:

3.6 用户交互

Gradio 是一个快速构建和分享机器学习 Web 应用的 Python 工具,支持一行代码创建交互式界面。本项目中我们使用Gradio来搭建用户交互界面。以下是部分代码:

四、实现效果

经过前期多轮沟通与调优后,最终版本在客户测试后,问答准确率达到了91.9%,此结果已超过客户测试前的预期(此前客户要求准确率在80%以上)。测试结果统计如下:

|A

|B

|C

|D

|1

|问题总数

|完全正确

|部分正确

|准确率

|2

|37

|34

|3

|91.90%

部分测试用例和测试结果如下:

五、总结与展望

本项目我们成功使用大模型和RAG技术构建了一套机票分销领域人工智能客服助手,该系统可以接收并准确理解用户输入的自然语言提问,自动从知识库中查找与提问相关的行业知识,并生成与之匹配的回答。

5.1 目前成果

听得懂:系统能够准确理解各种复杂的自然语言提问,包括口语化表达、行业“黑话”; 找得准:通过大语言模型和RAG技术构建行业知识库,基于向量检索+关键词检索实现混合检索策略,系统能够准确找到存储在知识库中的知识; 答得对:对大语言模型进行精确调教,系统能够按照客户预期进行答案生成。

5.2 未来展望

  • 提升问答准确率:持续优化迭代,在更多的知识、更复杂的场景下,保持并持续提高问答准确率;
  • 与企业在线聊天工具集成:将系统集成到在线聊天工具,以提升人工客服工作效率,释放更多的生产力;
  • 与运营系统集成:通过海量数据训练和场景覆盖,未来期望这套系统更深入的理解机票分销业务,集成到运营系统后,成为机票分销产品运营的左膀右臂。

通过这个项目,我们展示了大模型技术在机票分销量领域的应用潜力。随着生成式AI等技术的不断发展,我们期待与大型票务代理继续深入合作,让人工智能在航线规划、动态定价、运营专家系统等方面发挥更大的作用,共同为最终用户提供更优质、更高效的服务。

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。


Redshift性能调优 1 – 并发扩展(Concurrency-Scaling)

AWS账单代付阅读(75)

亚马逊AWS官方博客

Redshift性能调优 1 – 并发扩展(Concurrency-Scaling)

Amazon Redshift 作为云端数据仓库,凭借其强大的并行处理能力和分布式架构,能够有效支持高并发查询场景。同时,Redshift 提供并发扩展(Concurrency Scaling)功能以应对突发的查询负载激增的情况。该功能可以自动扩展计算资源,确保用户并发请求的性能稳定,特别适用于电商大促、财务月末报表生成等场景。当并发请求超过主集群处理能力时,系统会在数秒内创建临时扩展集群处理额外负载,并在需求下降后自动释放资源,此过程无需人工干预。

本篇博客将着重介绍该功能的开启方法,计价模式,监控方法等。

为特定工作负载开启&关闭并发扩展(Concurrency Scaling)功能

通过选择为特定的WLM队列开启并发扩展功能,来控制哪些用户请求/工作负载是可以被发送至并发扩展集群。

首先,在开启并发扩展之前,请借助

WLMQueueLength指标来找到队列最长的 WLM队列: CloudWatch -> Redshift -> ClusterIdentifier, QueueName -> MLMQueueLength

比如在下面的示例中,

ETL队列的 WLMQueueLength 指标最大,因此该 ETL队列是开启并发扩展功能的首要选择。

具体的开启方法:

Amazon Redshift console -> Configurations -> Workload management,找到该队列,将 Concurrency scaling mode设置成 auto(默认是 off)。

以上操作就完成为ETL队列开启并发扩展功能。

监控并发扩展(Concurrency Scaling)事件

当上述的ETL队列出现了队列增加的情况时,并发扩展功能会被自动触发,符合条件的请求将被自动路由到并发扩展集群执行,而无需在主集群队列中等待。

注意:

  • 并发扩展功能支持以下操作:数据操作语句,包括 `COPY`、`INSERT`、`DELETE`、`UPDATE` 、 `CREATE TABLE AS` (CTAS),以及手动刷新物化视图(MVs) ;
  • 并发扩展功能不支持以下操作:其他数据操作语言(DML)语句和数据定义语言(DDL)语句。

监控扩展集群的扩展事件,在Amazon Redshift console,选择目标集群,点击“

查询监控(Query monitoring)“标签页,选择” 工作负载并发(Workload concurrency)“选项。

也可以通过

CloudWatch -> Redshift -> Aggregated by Cluster -> ConcurrencyScalingActiveClusters指标来监控。

请注意以下具体的指标说明:

ConcurrencyScalingActiveClusters:正在运行的并发扩展集群。如果该指标的值小于1(例如5),可能是CloudWatch中指标的聚合方式导致的。例如,如果查询的时间范围内扩展集群并非全程活跃,计算平均值时可能会出现小数(比如:在5分钟内,扩展集群运行了2.5分钟,该指标的平均值就是0.5)。 MaxConfiguredConcurrencyScalingClusters:该集群配置允许的醉倒并发扩展集群数量,即系统允许同时允许的Concurrency Scaling集群的上限值,默认值是1。

可以在Amazon Redshift console ->

Configurations -> Workload management 页面上查看和修改参数max_concurrency_scaling_clusters 的值。

该ETL队列的WLMQueueLength指标在并发扩展功能被开启之后有大幅下降。

监控和控制并发扩展(Concurrency Scaling)成本

主集群每运行24小时便会累积1小时的并发扩展集群免费额度(每天最多可获得1小时的免费额度,且相关额度需先完成累积后才能被同一集群使用)。超出免费额度后,系统将按秒计费(仅当并发扩展集群实际处理查询时收费),每秒的按需费率取决于主集群的节点类型和数量。

每日1小时免费额度:

例如,以下的示例中并发扩展的总时长是40分钟(1小时),因此未额外收费。

在Amazon Cost Explorer中也可以确认未额外收费(CNN1-CSFreeUsage:ra3.4xlarge)。

超出免费额度时按秒计费:

当并发扩展的总时长超过免费额度的时候,则将按照主集群每小时费用计算出每秒的费用,乘以超出免费并发扩展额度的时长,再乘以扩展集群的数量。

具体的扩展集群的计费可以在Amazon Cost Explorer中查看:

配置使用上限:

在Amazon Redshift集群层面上,可以配置

Concurrency Scaling Usage Limit的来监控、控制费用。

在 Amazon Redshift 控制台上,进行以下操作:

1.选择所需调整的Redshift集群;

2.从 “操作”(Actions)下拉菜单中,选择 “管理使用限制”(Manage usage limit);

3.要为并发扩展配置使用限制,在 “并发扩展使用限制”(Concurrency scaling usage limit)中选择 “配置使用限制”(Configure usage limit)。

4.从Time period 下拉菜单中选择时间周期(每日、每周或每月)。

5.在Usage limit (hh:mm)中配置期望的使用限制值(例如,如果不想为此功能额外付费,可以设置该值为1)。

6.在Action下拉菜单中,选择要执行的操作(Alert – 发生警报、Log to system table – 记录到系统表或者Disable feature – 禁用该功能)。

注意事项

该并发扩展也有一定的使用限制,除了上述提到的不支持数据定义语言(DDL)语句以外,也有其他的受限情况。具体的内容请参见该Concurrency scaling官方文档。

如果已经为特定队列开启了并发扩展功能,但是此队列中的语句的执行性能依然未提升,那么请检查该队列中的请求是否未被并发扩展功能所支持。

可以通过以下脚本来检查scaling status (status = 1 代表语句成功运行在扩展集群上):

以上脚本执行结果如下:

在上述的示例中,成功运行在扩展集群上的语句仅有268条。绝大部分的语句未被并发扩展支持。如果您遇到类似的情况,请提供该语句的运行结果,联系Support 团队来做具体的检查。

结束语

本篇博客介绍了并发扩展(Concurrency Scaling)的概述信息,包括如何开启、监控、定价、和使用的注意事性。请您结合具体的场景和需求,合理的配置和使用该功能以获得更好的性能体验。

参考链接

https://docs.aws.amazon.com/redshift/latest/dg/concurrency-scaling.html

https://aws.amazon.com/blogs/big-data/manage-and-control-your-cost-with-amazon-redshift-concurrency-scaling-and-spectrum/

https://www.amazonaws.cn/en/redshift/pricing/

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。


中国区部署Smokeping构建轻量化网络监控及告警平台小指南

AWS账单代付阅读(72)

1. 概述

1.1 背景需求

在亚马逊云科技中国区,由于缺乏托管的网络监控管理服务如Network Synthetic Monitor,客户在以下场景中面临监控挑战:

  • 专线(Direct Connect)网络质量监控
  • Overlay 网络可达性监控
  • 跨区域服务访问性能监控
  • 关键业务端口和服务可用性监控

一些主流的监控方案如 Prometheus blackbox-exporter + Grafana 虽然功能强大,但部署和维护成本较高,需要较多的计算资源和体系化的运维能力。有些客户在特定场景需要一个轻量级但功能完备的网络监控方案,可以在单台小型实例(如 t3.small)上运行,同时提供直观的可视化界面。

1.2 方案介绍

本方案采用 SmokePing 作为核心监控工具。SmokePing 是一个轻量级但功能强大的网络延迟监测工具,具有以下特点:

核心优势:

  • 部署简单:基于 Docker 容器化部署,最小化依赖
  • 资源占用低:适合在小型实例上运行
  • 配置灵活:支持多种监控协议和探测方式
  • 可视化友好:提供直观的网络性能趋势图表

主要功能:

  • 精确的延迟测量:同时监控数据包丢失和延迟变化
  • 多协议支持:包括 ICMP、TCP、DNS、HTTP 等
  • 告警机制:可配置多级告警规则
  • 历史数据存储:使用 RRD 数据库高效存储监控数据,方便溯源和提供故障发生时的证据。
  • 支持 Master/Slave 架构:可以部署多个 Slave 节点分布在不同AZ或者区域

本篇内容会通过step by step的指南,让客户可以快速搭建起一个轻量级但实用的网络监控系统,实现对关键网络链路和服务的持续监控。本方案还支持通过SMTP或者与 Amazon SNS 集成以及第三方API,及时推送告警通知,帮助运维团队快速发现和响应网络问题。

2.安装前准备

本方案的部署环境要求和准备工作如下:

2.1 准备EC2 访问密钥对(用于 SSH 登录)

2.2 准备一个安全组配置(需开放SSH以及监控页面访问端口,默认 8888)

2.3 EC2 IAM 角色(用于访问亚马逊云科技服务)

这个Role根据以下原则去构建:

  • 如果需要使用自建的ECR作为镜像源,需要ECR相关权限,如下代码示例:
  • 中国区部署Smokeping构建轻量化网络监控及告警平台小指南

{

“Version”: “2012-10-17”,

“Statement”: [

{

“Effect”: “Allow”,

“Action”: [

“ecr:GetAuthorizationToken”,

“ecr:BatchCheckLayerAvailability”,

“ecr:GetDownloadUrlForLayer”,

“ecr:BatchGetImage”

],

“Resource”: “*”

}

]

}

  • 如果需要使用告警的能力,比如使用SNS发送通知,或者通过Lambda触发一个自定义告警脚本,则需要SNS及Lambda相关权限。
  • 2.4 (可选)如果这个EC2部署的subnet没有互联网访问,则需要部署ECR, SNS, Lambda等需要的服务的VPC endpoint。

    3.安装smokeping

    3.1 (可选)通过ECR构建最新的image。

因为linuxserver/docker-smokeping的官方镜像下载可能会遇到网络问题,所以推荐将Image下载,更新组件以后打包更新到ECR, 方便后续使用。

3.2 由于官方的dockerfile没有安装python, 无法使用自定义的python脚本作为告警方式,因此如果需要自定义告警推荐使用这个repo: mengchen-tam/docker-smokeping.

需要使用python脚本实现SNS, lambda或者自己的API去告警:

git clone https://github.com/mengchen-tam/docker-smokeping

使用SMTP方式告警则可以直接使用官方的repo:

git clone https://github.com/linuxserver/docker-smokeping

3.3 使用如下bash脚本构建ECR 镜像,更新参数以后直接执行即可。

!/bin/bash

set -e

默认参数

ECR_ACCOUNT=””

ECR_REGION=””

ECR_REPO_NAME=””

TAG=”latest”

DOCKER_DIR=”/xxxx/docker-smokeping”

构建完整的 ECR 仓库 URL

ECR_URL=”${ECR_ACCOUNT}.dkr.ecr.${ECR_REGION}.amazonaws.com.cn”

ECR_REPO=”${ECR_URL}/${ECR_REPO_NAME}”

FULL_IMAGE_NAME=”${ECR_REPO}:${TAG}”

echo “===== SmokePing Docker 构建和推送脚本 =====”

echo “ECR 账号: $ECR_ACCOUNT”

echo “ECR 区域: $ECR_REGION”

echo “ECR URL: $ECR_URL”

echo “仓库名称: $ECR_REPO_NAME”

echo “镜像标签: $TAG”

echo “目标镜像: $FULL_IMAGE_NAME”

进入 docker-smokeping 目录

cd “$DOCKER_DIR”

构建 Docker 镜像

echo “正在构建 Docker 镜像…”

docker build \

–no-cache \

–pull \

-t “$FULL_IMAGE_NAME” .

登录到 ECR

echo “正在登录到 ECR…”

aws ecr get-login-password –region $ECR_REGION | docker login –username AWS –password-stdin $ECR_URL

检查仓库是否存在,如果不存在则创建

if ! aws ecr describe-repositories –repository-names $ECR_REPO_NAME –region $ECR_REGION &> /dev/null; then

echo “创建 ECR 仓库 $ECR_REPO_NAME…”

aws ecr create-repository –repository-name $ECR_REPO_NAME –region $ECR_REGION

fi

推送镜像到 ECR

echo “正在推送镜像到 ECR…”

docker push “$FULL_IMAGE_NAME”

echo “===== 完成! =====”

echo “镜像已成功构建并推送到: $FULL_IMAGE_NAME”

3.4 Launch一台 Ubuntu 24 EC2 (默认Ubuntu AMI),推荐使用small以上机型。

3.5 附加在步骤2中准备好的key和SG

3.6 Metadata response hop limit需要设置为2

3.7 Launch EC2以后Modify IAM role, 添加准备好的EC2 Role。

3.8 登录EC2, 安装软件

sudo snap install aws-cli –classic

sudo apt update

sudo apt upgrade

sudo apt install docker.io docker-compose

3.9 安装一次smokeping docker,并且copy出配置文件

第1步:将当前用户添加到 docker 组(执行后需要重新登录或运行 newgrp docker)

sudo usermod -aG docker $USER

newgrp docker

第2步:设置环境变量

export AWS_ACCOUNT_ID=””

export AWS_REGION=””

export REPO_NAME=””

export ECR_REGISTRY=”${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com.cn”

export IMAGE_TAG=”latest”

第3步:ECR登录

aws ecr get-login-password –region ${AWS_REGION} | docker login –username AWS –password-stdin ${ECR_REGISTRY}

第4步:拉取和标记镜像

docker pull ${ECR_REGISTRY}/${REPO_NAME}:${IMAGE_TAG}

docker tag ${ECR_REGISTRY}/${REPO_NAME}:${IMAGE_TAG} smokeping:${IMAGE_TAG}

第5步:首次运行容器

docker run –name smokeping -d –rm -p 8888:80 -e TZ=Asia/Shanghai smokeping:${IMAGE_TAG}

第6步:准备数据目录

sudo mkdir -p /data/smokeping

sudo chown -R $USER:$USER /data/smokeping

第7步:复制初始配置文件到EC2文件系统中

docker cp smokeping:/data/ /data/smokeping/

docker cp smokeping:/config/ /data/smokeping/

第8步:停止临时容器

docker stop smokeping

第9步:尝试挂载本地文件,启动smokeping

docker run –name smokeping -d \

–restart unless-stopped \

-p 8888:80 \

-e TZ=Asia/Shanghai \

-v ~/smokeping/data:/data \

-v ~/smokeping/config:/config \

smokeping:${IMAGE_TAG}

3.10 到这里安装工作就完成了。我们来看一下/data/smokeping的目录结构:

smokeping/

├── config/ # 配置文件目录

│ ├── Alerts # 告警配置文件,定义告警规则和触发条件

│ ├── Database # 数据库配置文件,定义 RRD 数据库存储参数

│ ├── General # 通用配置文件,包含基本设置如所有者信息、网站标题等

│ ├── Presentation # 展示配置文件,定义网页显示相关参数

│ ├── Probes # 探测器配置文件,定义不同类型的监控探测方式

│ ├── Slaves # 从节点配置文件,用于分布式监控设置

│ └── Targets # 监控目标配置文件,定义要监控的主机和服务

└── data/ # 数据存储目录

├── DNS/ # DNS监控相关的数据目录

├── DNSProbes/ # DNS探测器的数据目录

3.11 其中Targets, Alerts是最重要的。其他的内容可以保持默认。现在我们需要自己替换EC2里/data/smokeping/config里面的内容,自定义需要监控的内容。让我们做一个属于自己的监控目标,例如:

* Targets *

probe = FPing

menu = Top

title = AWS China Network Latency

remark = AWS中国区网络延迟监控

+ Console

menu = 控制台

title = AWS控制台监控

remark = AWS中国区控制台访问监控

++ BeijingConsole

menu = 北京控制台

title = AWS北京区控制台

host = console.amazonaws.cn

++ NingxiaConsole

menu = 宁夏控制台

title = AWS宁夏区控制台

host = cn-northwest-1.console.amazonaws.cn

+ Storage

menu = 存储服务

title = AWS存储服务监控

remark = AWS中国区存储服务监控

probe = TCPPing

++ BeijingS3

menu = 北京S3

title = AWS北京区S3

host = s3.cn-north-1.amazonaws.com.cn

port = 443

++ NingxiaS3

menu = 宁夏S3

title = AWS宁夏区S3

host = s3.cn-northwest-1.amazonaws.com.cn

port = 443

+ DNS

menu = DNS服务

title = AWS DNS服务监控

remark = AWS中国区DNS服务器监控

++ DNS_115

menu = DNS-115

title = AWS DNS Server 115

host = ns-intl-115.awsdns-cn-07.com

port = 53

++ DNS_1457

menu = DNS-1457

title = AWS DNS Server 1457

host = ns-1457.awsdns-cn-27.net

port = 53

3.12 新增一个docker-compose配置

cd /data/smokeping/

cat > docker-compose.yml << 'EOF'

version: ‘3’

services:

smokeping:

container_name: smokeping

image: smokeping

ports:

  • “8888:80”

environment:

  • PUID=1000
  • PGID=1000
  • TZ=Asia/Shanghai

volumes:

  • /data/smokeping/data:/data
  • /data/smokeping/config:/config

restart: unless-stopped

EOF

3.13 使用docker compose启动docker

docker stop smokeping

docker remove smokeping

cd /data/smokeping/

docker-compose up -d

4. 使用smokeping

4.1 到这里我们就用可以http::8888访问smokeping 网页端了, 由于默认probe间隔是300s,所以要等5分钟以上才会有监控数据。

4.2 如果需要更换端口可以修改/data/smokeping/docker-compose.yml

4.3 接下来就需要根据自己的需求定义监控目标,参考9的内容和官方文档,在EC2 里修改/data/smokeping/config/下面的配置,然后docker-compose restart即可。

4.4 历史监控数据是保留在/data/smokeping/data中。修改配置或者更新image不会导致数据丢失,数据是通过rdd文件保存在/data/smokeping/data/”一级目录名字+“/”二级目录名字++”/保存的,如:

├── data

│ ├── Console

│ │ ├── BeijingConsole.rrd

│ │ └── NingxiaConsole.rrd

4.5 如需看历史数据,或者某个时间段的监控,可以点击对应的图标,进入详细监控页面:

4.6 从这一层页面再点击某个监控图,就可以使用自定义的时间段去检查监控。可以通过在图形上拖选一个时间段,或者指定time range来查看特定时间段的监控。

5. 设置告警

5.1 在/data/smokeping/config/Alerts里面定义alert类型,和通知方式:

  • 有SMTP的环境可以使用配置conf,然后to可以是收告警的邮箱。
  • 比如:to = [已去除邮箱]
  • 如果是内网环境,可以通过触发一个脚本,脚本里面去call lambda或者SNS服务
  • 如果需要自己定义alert类型,可以参考官方文档。
  • * Alerts *

to = |/config/alertsns.py

from = [已去除邮箱]

+someloss

type = loss

in percent

pattern = >0%,*12*,>0%,*12*,>0%

comment = loss 3 times in a row

+hostdown

type = loss

in percent

pattern = >60%

edgetrigger = yes

comment = Massive loss for 5 mins

5.2 在config/Targets里的目录级别或者host级别配置alert。示例如下:这样会对Demo_Monitor这层下面所有的target都开启someloss和hostdown两个类型的alerts。

+ Demo_Monitor

menu = Monitor Demo (Demo using fake IP)

title = Monitor Demo (Demo using fake IP)

alerts = someloss,hostdown

这样就会在这个1级目录下面所有监控项开启两种监控

这样就会在这个1级目录下面所有监控项开启两种监控

5.3 SNS 告警脚本示例:

!/usr/bin/env python3

导入必要的库

import sys # 用于处理命令行参数

import time # 用于时间戳生成

import boto3 # AWS SDK for Python

import requests # 用于发送 HTTP 请求

import json # 用于 JSON 数据处理

from datetime import datetime # 用于日期时间处理

def get_imdsv2_token():

“””

获取 EC2 实例元数据服务 V2 版本的 token

这是 AWS 推荐的安全实践,用于防止 SSRF 攻击

Returns:

str: IMDSv2 token,用于后续请求

“””

token_url = “http://169.254.169.254/latest/api/token”

headers = {

“X-aws-ec2-metadata-token-ttl-seconds”: “21600”

}

token = requests.put(token_url, headers=headers).text

return token

def get_credentials():

“””

从 EC2 实例元数据服务获取临时安全凭证

Returns:

dict: 包含 AccessKeyId, SecretAccessKey 和 Token 的凭证信息

“””

首先获取 IMDSv2 token

token = get_imdsv2_token()

headers = {

“X-aws-ec2-metadata-token”: token

}

获取 IAM 角色名称

role_name_url = “http://169.254.169.254/latest/meta-data/iam/security-credentials/”

role_name = requests.get(role_name_url, headers=headers).text

使用角色名称获取临时凭证

credentials_url = f”http://169.254.169.254/latest/meta-data/iam/security-credentials/{role_name}”

credentials = requests.get(credentials_url, headers=headers).json()

return credentials

def send_sns(topic_arn, message):

“””

发送消息到 AWS SNS 主题

Args:

topic_arn (str): SNS 主题的 ARN

message (str): 要发送的消息内容

Returns:

dict: SNS 发布响应

None: 发送失败时返回

“””

获取临时凭证

credentials = get_credentials()

初始化 SNS 客户端

sns = boto3.client(

‘sns’,

region_name=’cn-north-1′, # AWS 中国北京区域

aws_access_key_id=credentials[‘AccessKeyId’],

aws_secret_access_key=credentials[‘SecretAccessKey’],

aws_session_token=credentials[‘Token’]

)

try:

发布消息到 SNS 主题

response = sns.publish(

TopicArn=topic_arn,

Message=message

)

print(f”Message published successfully: {response[‘MessageId’]}”)

return response

except Exception as e:

print(f”Failed to publish message: {str(e)}”)

return None

def main():

“””

主函数:处理命令行参数并发送告警

命令行参数格式:

alertname target losspattern rtt hostname

“””

验证命令行参数数量

if len(sys.argv) != 6:

print(“Usage: {} alertname target losspattern rtt hostname”.format(sys.argv[0]))

sys.exit(1)

解析命令行参数

alertname = sys.argv[1] # 告警名称

target = sys.argv[2] # 监控目标

losspattern = sys.argv[3] # 丢包模式

rtt = sys.argv[4] # 往返时间

hostname = sys.argv[5] # 主机名

生成当前时间戳并记录日志

current_time = datetime.now().strftime(“%Y-%m-%d %H:%M:%S”)

log_message = f”””

{current_time}: Received parameters:

alertname: {alertname}

target: {target}

losspattern: {losspattern}

rtt: {rtt}

hostname: {hostname}

“””

print(log_message)

构建告警消息(管道分隔格式)

alert_message = f”SMOKEPING_ALERT|{int(time.time())}|{alertname}|{target}|{losspattern}|{rtt}|{hostname}”

print(alert_message)

构建格式化的 SNS 消息

sns_message = f”””

SmokePing Alert Details:

Alert Name: {alertname}

Target: {target}

Loss Pattern: {losspattern}

RTT: {rtt}

Hostname: {hostname}

Time: {current_time}

“””

发送到 SNS 主题

注意:需要替换实际的 AWS 账号和主题名

topic_arn = “arn:aws-cn:sns:cn-north-1::”

send_sns(topic_arn, sns_message)

if __name__ == “__main__”:

main()

5.4 如果需要使用alert SNS功能,还需要检查:

  • 在Target里定义哪些目标需要触发alert。(步骤2);
  • EC2必须能通过公网或者VPC endpoint访问SNS;
  • 这里SNS也可以换成其他的API比如发送短信的第三方API,需要对python脚本做一些修改。
  • SNS告警示例如下图:
  • 6.结语

在本文中,我们详细介绍了如何在亚马逊云科技上部署开源软件SmokePing 网络监控系统。这个方案不仅实现了基础的网络性能监控,还包含了告警功能的扩展实现。本方案适合没有现有网络监控平台可用的客户,可以快速构建一个轻量化的,针对一些关键服务,比如DX的底层网络,或者某些外部依赖服务的监控及告警平台。

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者


亚马逊云科技 AD Insight Hub,全链路解决方案解决辅助驾驶开发过程中的数据挑战

AWS账单代付阅读(63)

亚马逊AWS官方博客

亚马逊云科技 AD Insight Hub,全链路解决方案解决辅助驾驶开发过程中的数据挑战

智能驾驶加速演进,数据成为核心驱动力

当前,全球汽车行业正经历从“电动化” 向 “智能化” 的深度转型,辅助驾驶作为智能汽车的核心功能,已成为车企差异化竞争的关键赛道。L2 + 级辅助驾驶车型渗透率持续提升,消费者对高阶辅助驾驶(如高速 NOA、城区 NOA)的需求日益迫切。然而,辅助驾驶技术的研发过程中,数据处理效率、场景覆盖广度等核心问题,始终制约着技术迭代速度与商业化落地进程。

一方面,智能驾驶车辆搭载的激光雷达、毫米波雷达、摄像头等多传感器,每天可产生40-80TB 的原始数据,海量数据的存储、筛选、标注与应用成为研发痛点;另一方面,真实道路中的危险场景(如极端天气、突发事故)难以大量采集,且实地测试成本高、周期长,无法满足辅助驾驶系统对 “亿级公里” 测试里程的需求。在此背景下,亚马逊云科技凭借在云计算、生成式人工智能、大数据领域的技术积累,为辅助驾驶企业提供全链路解决方案,助力突破研发瓶颈。

辅助驾驶研发的核心挑战:数据与场景的双重困境

辅助驾驶研发围绕 “数据 – 模型 – 仿真” 展开,每个环节的痛点均需通过高效数据处理能力解决,而传统方式难以满足需求,具体表现为:

Bounding Box** **标注:人工效率低、成本高,无法匹配数据增长速度

感知模型训练需大量目标检测标注(如车辆、行人的 Bounding Box),传统人工标注需上大量标注人员并行推进,面对日均 PB 级新增数据,标注效率远低于数据产生速度;同时,人工标注需反复校验,管理成本高,难以支撑核心模型的并行训练需求。

场景标注:语义信息缺失,人工补标周期长

模型训练不仅需目标标注,还需 “环境 – 行为 – 风险” 等语义标签(如 “雨天 + 城市道路 + 车辆急刹”),传统人工标注仅能完成目标框绘制,语义标签需额外投入人力补充,单段视频语义标注耗时长,且标签维度不统一,无法快速适配多模型训练需求。

场景搜索:关键数据难找,研发效率受困

辅助驾驶模型优化需聚焦边缘场景(如暴雨天无保护左转、暴雪天车辆打滑),这类场景在真实数据中占比较低,传统基于人工标签的检索方式,无法精准匹配相似场景,工程师查找目标数据需耗时数天,严重拖慢模型迭代节奏。

仿真场景生成:危险场景复现难,传统工具效率低

极端天气(团雾、冻雨)、突发事故(多车追尾、道路塌陷)等危险场景,实地测试无法主动触发,传统仿真工具需手动搭建场景,单一场景生成耗时超 24 小时,且难以模拟真实物理规律,生成场景与实车测试差异大,模型验证效果不佳。

亚马逊云科技 AD Insight Hub 解决方案

针对辅助驾驶研发的核心流程,亚马逊云科技 AD Insight Hub 以多模态大模型为核心,解决辅助驾驶开发过程中的数据挑战。

基于多模态大模型的 Bounding Box 自动标注

针对人工标注效率低、成本高的痛点,AD Insight Hub 依托 Amazon Bedrock 多模态大模型,模型通过学习海量标注数据,可自动识别图像 / 视频中的车辆、行人、交通标识、障碍物等目标,实现目标检测场景的 Bounding Box 自动生成。

Amazon Nova作为AWS原生的多模态大模型,专门针对图像和视频理解进行了深度优化,具备出色的视觉感知能力,能够精准识别和定位自动驾驶场景中的各类关键目标。Nova模型经过大规模多模态数据训练,对车辆、行人、交通标识等交通场景元素具有深度理解能力,不仅能够准确识别目标类别,还能精确生成边界框坐标,大幅提升标注精度和一致性。

基于多模态大模型的场景标注

针对语义标签人工补标周期长、维度不统一的问题,AD Insight Hub 利用多模态大模型的场景理解能力,模型可同时分析图像 / 视频的静态信息(天气、道路类型、交通设施)与动态信息(车辆运动轨迹、行人动作),并根据要求生成描述或语义标签。

基于多模态 Embedding 的场景智能搜索:快速定位关键数据,突破检索瓶颈

针对边缘场景难找、检索效率低的痛点,AD Insight Hub 将数据池中的图像、视频转为特征向量,用户可通过三种方式发起检索:①输入自然语言描述(如 “傍晚雨天行人横穿马路”);②上传参考图像(如某一角度的车辆侧翻场景);③输入标签组合(如 “高速 + 团雾 + 货车变道”),模型将查询内容转为向量后,与数据池向量快速比对,返回相似场景结果。

基于 NVIDIA Cosmos 的仿真视频生成:大模型驱动场景生成,破解仿真困境

针对危险场景复现难、传统仿真效率低的痛点,AD Insight Hub 结合基于NVIDIA Cosmos ,用户通过 AD Insight Hub 前端输入场景描述(如“晴天的杭州西湖湖边”),然后Amazon Bedrock 中的大模型将简单描述优化为细节丰富的提示词,最后借助NVIDIA Cosmos世界模型,生成符合真实物理规律的场景视频。

NVIDIA Cosmos的核心原因在于其作为专门针对物理世界建模的世界模型,能够生成符合真实物理规律且时序连贯的仿真场景,特别是在自动驾驶领域具备专业的场景理解能力,能够安全地重现现实中难以复现的危险驾驶情况。

在AWS平台上运行这一解决方案带来了显著优势,AWS基础设施的弹性扩展能力,可以根据需求动态调配GPU计算资源和存储空间。与Amazon Bedrock中大模型的无缝协作,实现从简单文本描述到详细提示词的智能优化。通过这种云端部署方式,AD Insight Hub能够充分发挥大模型的理解能力和Cosmos的专业建模能力,为自动驾驶测试提供高质量、大规模的仿真场景生成服务。

解决方案架构图

亚马逊云科技 AD Insight Hub 解决方案架构遵循 “模块化、可扩展” 原则,以多模态大模型为核心,依托 AWS 核心服务构建,贴合辅助驾驶研发数据流转逻辑。

1、

前端交互与内容分发:数据工程师通过静态页面访问系统,请求首先经过Amazon CloudFront进行内容分发,然后连接到Amazon S3托管的网站,确保高效快速的前端交互体验,提供统一的用户界面用于提交自动标注、场景搜索和仿真生成等请求。

2、

API统一管理层:Amazon API Gateway作为系统的统一入口点,负责处理所有来自前端的请求,实现请求路由、身份验证和流量管理。API Gateway与Amazon Cognito集成实现身份认证,通过Amazon CloudWatch进行监控,同时连接Amazon ECR和DynamoDB以支持容器化部署和数据存储。

3、

核心处理逻辑层:在虚拟私有云(VPC)环境内,系统部署了多组Lambda函数,包括Datasets API、Models API、Batch API和Tasks API,这些函数共同构成AD Insight Hub的核心业务逻辑处理单元,负责数据集管理、模型调用、批处理任务和任务状态追踪等功能。

4、

工作流协调层:AWS Batch与Amazon SQS(简单队列服务)协同工作,AWS Batch负责管理计算资源和运行批处理作业,而Amazon SQS确保消息的可靠传递,共同实现工作负载的高效协调和资源优化分配,保证大规模处理任务的可靠执行。

5、

数据存储与管理层:系统采用多个Amazon S3存储桶分别存储不同类型的数据:输出结果存放在Output Buckets、视频帧存储在Frame Buckets、原始视频保存在Source Video Buckets。同时,Amazon DynamoDB提供了高性能的数据库服务,用于存储和查询元数据和处理状态信息。

6、

实时推理服务层:实时推理层由三个强大的AI服务组成:Amazon Bedrock提供多模态大模型能力,支持自然语言处理和视觉理解;Amazon SageMaker AI提供完整的机器学习模型开发和部署环境, 可以支持Cosmos等相关模型的部属与管理;Amazon Nova提供高性能计算能力。这些服务共同支持Bounding Box自动标注、场景智能标注、语义搜索和仿真视频生成等核心功能。

大模型驱动辅助驾驶提升研发效率

亚马逊云科技 AD Insight Hub 通过多模态大模型技术,精准对应辅助驾驶研发四大核心痛点,实现全链路效率跃升与成本优化。针对Bounding Box标注效率瓶颈,Amazon Nova多模态大模型实现自动化目标检测标注,显著降低标注成本并确保一致性和准确性;针对场景语义标注周期长的困境,多模态大模型能够同时解析静态环境信息和动态行为特征,、大幅提升标准化程度;针对边缘场景检索难题,基于多模态Embedding的智能搜索系统支持多种检索方式,大幅提升检索准确率;针对危险场景仿真复现难点,NVIDIA Cosmos与Amazon Bedrock的协同方案将传统需要超长时间的单场景手动构建优化为分钟级的智能化生成,生成场景数量大幅提升且物理规律一致性显著优于传统仿真工具。

该解决方案凭借AWS的技术优势,为辅助驾驶行业带来革命性变革。AWS云原生架构提供的弹性扩展能力和全球化部署支持,让企业能够灵活应对大规模数据处理挑战,实现成本可控的敏捷研发;Amazon Bedrock多模态大模型的深度融合,突破了传统单一模态处理的局限性,为复杂驾驶场景的智能化理解和生成奠定了坚实基础;端到端的完整解决方案架构消除了数据孤岛和集成复杂性,构建了从数据处理到模型验证的无缝研发链路。

展望未来,随着生成式AI技术的持续演进和边缘计算能力的深度融合,AD Insight Hub将进一步优化多模态处理能力,拓展更多智能化应用场景,助力企业在从L2+向更高级别自动驾驶的技术跃迁中保持领先优势。这一创新解决方案不仅重新定义了辅助驾驶的研发模式,更为整个智能汽车产业的可持续发展提供了强有力的技术支撑,推动行业向更安全、更智能的未来加速迈进。

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。


利用 CloudWatch AIOps 实现智能化根因分析与故障排查

AWS账单代付阅读(57)

主题概述

在当今复杂的云环境中,运维团队面临着前所未有的挑战。随着微服务架构、容器化应用和无服务器计算的普及,系统组件之间的依赖关系变得越来越复杂,故障排查的难度也随之增加。当生产环境出现问题时,运维人员通常需要在海量的日志、指标和事件中寻找故障的根本原因,这不仅耗时耗力,还可能导致业务中断时间延长,造成严重的经济损失。

传统的运维方法已经难以应对这种复杂性。运维人员需要同时监控多个系统、分析各种指标、查看不同的日志,并尝试将这些信息关联起来以找出问题的根源。这个过程不仅繁琐,而且容易受到人为因素的影响,导致分析结果不准确或不完整。

AWS CloudWatch AIOps 应运而生,它利用人工智能和机器学习技术,自动化根因分析过程,帮助运维团队快速定位和解决问题。本文将深入探讨 CloudWatch AIOps 的功能和优势,并通过实际案例展示其如何改变传统的运维方式,提高故障排查效率。

背景

CloudWatch AIOps 的产品定位

CloudWatch AIOps 是 Amazon CloudWatch 的一项高级功能,专为解决云环境中的复杂故障排查问题而设计。它将人工智能和机器学习技术与 AWS 的可观测性服务相结合,提供自动化的根因分析能力。CloudWatch AIOps 的核心目标是减少平均故障排除时间(MTTR),提高系统可靠性,并降低运维团队的工作负担。

CloudWatch AIOps 不仅仅是一个监控工具,它是一个智能分析平台,能够理解应用程序和基础设施之间的复杂关系,自动识别异常模式,并提供有针对性的解决方案建议。

主要功能

1. 智能根因分析(Root Cause Analysis, RCA):

自动分析告警和异常事件,识别潜在的根本原因

利用机器学习算法检测异常模式和关联性

提供可视化的问题影响路径,帮助理解故障传播

2. 多种入口点:

CloudWatch 告警:直接从触发的告警进入分析流程

Amazon Q:通过自然语言交互方式启动分析

CloudWatch 控制台:从监控面板直接进入分析

3. 广泛的服务集成:

支持多种 AWS 服务,包括 EC2、Lambda、RDS、DynamoDB、API Gateway 等

完整支持列表参见:CloudWatch AIOps 支持的服务

4.上下文感知分析:

自动收集相关的日志、指标和事件

考虑资源之间的依赖关系和最近的配置变更

分析时间序列数据,识别异常趋势和模式

5. 可操作的建议:

提供具体的修复建议和最佳实践

生成详细的调查报告,便于团队协作和知识共享

支持自定义修复工作流程

方案:可观测性与 CloudOps 的协同作用

可观测性的三大支柱

有效的故障排查需要建立在强大的可观测性基础上。可观测性通常包括三个关键支柱:

1.指标(Metrics):

数值化的系统性能和健康状态指标

CloudWatch 提供了丰富的内置指标和自定义指标功能

支持高精度监控和异常检测

2. 日志(Logs):

详细记录系统和应用程序的行为和事件

CloudWatch Logs 集中存储和分析各种日志数据

支持实时处理和结构化查询

3. 追踪(Traces):

跟踪请求在分布式系统中的完整路径

AWS X-Ray 提供端到端的请求追踪能力

可视化服务依赖关系和性能瓶颈

CloudWatch AIOps 将这三个支柱的数据整合在一起,提供全面的系统视图,使故障排查变得更加高效和准确。

CloudOps 关联产品的协同作用

CloudWatch AIOps 不是孤立运行的,它与多个 AWS CloudOps 产品协同工作,形成完整的运维解决方案:

1.AWS CloudTrail:

记录 AWS 账户中的所有 API 调用和资源变更

提供审计跟踪,帮助识别配置变更导致的问题

CloudWatch AIOps 自动分析 CloudTrail 日志,检测可能导致故障的配置变更

2.AWS Config:

持续监控和记录 AWS 资源配置

评估资源配置是否符合最佳实践

CloudWatch AIOps 利用 Config 数据了解资源的历史状态和变更

3.Amazon EventBridge:

处理来自各种 AWS 服务和应用程序的事件

实现事件驱动的自动化响应

CloudWatch AIOps 分析 EventBridge 事件,识别系统变更和异常行为

4.AWS Systems Manager:

提供集中化的系统管理功能

自动执行运维任务和修复操作

CloudWatch AIOps 可以触发 Systems Manager 自动化工作流进行修复

5. Amazon DevOps Guru:

提供基于机器学习的运维洞察

预测潜在的运维问题

与 CloudWatch AIOps 协同工作,提供更全面的分析

这些产品的协同作用创建了一个闭环的运维流程:监控 → 检测 → 分析 → 修复 → 验证,大大提高了运维效率和系统可靠性。

理论基础:可观测性与 CloudOps 的协同效应

从监控到可观测性的演进

传统的监控方法主要关注预定义的指标和阈值,这种方法在简单系统中可能有效,但在复杂的云环境中显得力不从心。可观测性则采取了更全面的方法,不仅关注”系统是否正常运行”,还关注”为什么系统会出现这种行为”。

可观测性的核心理念是:系统的内部状态可以通过其外部输出来推断。通过收集和分析指标、日志和追踪数据,运维团队可以构建系统行为的完整视图,即使面对未预见的问题也能快速定位根因。

CloudWatch AIOps 的工作原理

CloudWatch AIOps 基于以下理论基础运作:

1. 因果推理:

建立系统组件之间的因果关系模型

分析事件序列,识别潜在的触发因素

区分症状和根本原因

2. 异常检测:

学习系统的正常行为模式

识别偏离正常模式的异常情况

考虑时间相关性和季节性变化

3.关联分析:

发现不同指标和事件之间的相关性

构建资源依赖关系图

追踪问题的传播路径

4.知识图谱:

整合 AWS 服务的专业知识和最佳实践

应用领域特定的故障排查逻辑

持续学习和改进分析能力

根因分析的自动化流程

当系统触发告警或用户启动调查时,CloudWatch AIOps 执行以下步骤:

1. 数据收集:

自动收集相关的指标、日志和追踪数据

获取资源配置和最近的变更记录

确定受影响资源的范围

2.上下文构建:

分析资源之间的依赖关系

考虑时间相关性和事件顺序

构建问题的完整上下文

3. 模式识别:

应用机器学习算法识别异常模式

比较当前情况与历史案例

检测潜在的根本原因

4. 影响分析:

评估问题对系统各部分的影响

确定关键路径和瓶颈

预测问题的潜在发展

5. 解决方案生成:

提供针对根本原因的具体修复建议

推荐预防类似问题的最佳实践

生成详细的调查报告

这种自动化的根因分析流程大大减少了手动排查的时间和精力,使运维团队能够更快地解决问题,提高系统可靠性。

操作演示:使用 CloudWatch AIOps 排查 S3 权限问题

为了展示 CloudWatch AIOps 的实际应用,我们将使用一个简单的演示应用程序,该应用程序由 API Gateway、Lambda 函数和 S3 存储桶组成。我们将模拟一个常见的运维问题:S3 存储桶策略变更导致的应用程序故障,并使用 CloudWatch AIOps 进行根因分析。

演示应用架构

我们的演示应用是一个简单的图片服务,其架构如下:

1. API Gateway:提供 REST API 接口,接收客户端请求

2. Lambda 函数:处理请求,从 S3 存储桶中随机获取图片

3. S3 存储桶:存储图片文件

4. Bedrock Lambda:使用 Amazon Bedrock 生成图片并存储到 S3 存储桶

应用正常工作时,用户可以通过 API 获取随机图片。我们将通过修改 S3 存储桶策略,模拟一个权限问题,然后使用 CloudWatch AIOps 进行故障排查。

步骤 1:部署演示应用

首先,我们使用 CloudFormation 模板部署演示应用:

您需要将下面的 Cloudformation Template 存储到本地。

AWSTemplateFormatVersion: '2010-09-09'
Description: 'AIOps Integration Test - Image Service'
Resources:
# S3 Bucket
S3BucketAIOpsIntegration:
Type: 'AWS::S3::Bucket'
DeletionPolicy: Delete
UpdateReplacePolicy: Retain
Properties:
BucketName: !Join
- ''
- - 'aiops-image-bucket-'
- !Select [0, !Split ["-", !Select [2, !Split ["/", !Ref "AWS::StackId"]]]]
CleanupLambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
Policies:
- PolicyName: S3CleanupPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 's3:ListBucket'
- 's3:DeleteObject'
- 's3:DeleteObjectVersion'
Resource:
- !Sub 'arn:aws:s3:::${S3BucketAIOpsIntegration}'
- !Sub 'arn:aws:s3:::${S3BucketAIOpsIntegration}/*'
# Cleanup Lambda used to empty contents of S3 Bucket
CleanupLambda:
Type: 'AWS::Lambda::Function'
DependsOn:
- CleanupLambdaRole
- S3BucketAIOpsIntegration
Properties:
FunctionName: !Sub '${AWS::StackName}-cleanup-lambda'
Handler: 'index.lambda_handler'
Role: !GetAtt CleanupLambdaRole.Arn
Code:
ZipFile: |
import boto3
import cfnresponse
def lambda_handler(event, context):
try:
if event['RequestType'] == 'Delete':
s3 = boto3.resource('s3')
bucket = s3.Bucket(event['ResourceProperties']['BucketName'])
bucket.objects.all().delete()
print(f"Cleaned up bucket {event['ResourceProperties']['BucketName']}")
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
print(f"Error: {str(e)}")
cfnresponse.send(event, context, cfnresponse.FAILED, {})
Runtime: python3.13
Timeout: 300
MemorySize: 128
S3BucketCleanup:
Type: 'Custom::S3BucketCleanup'
DependsOn:
- CleanupLambda
- BedrockLambda
- TriggerCustomResource
Properties:
ServiceToken: !GetAtt CleanupLambda.Arn
BucketName: !Ref S3BucketAIOpsIntegration
# SSM Parameter for Bucket Name
BucketNameParameter:
Type: 'AWS::SSM::Parameter'
Properties:
Name: !Sub '/${AWS::StackName}/bucket-name'
Type: 'String'
Value: !Ref S3BucketAIOpsIntegration
Description: 'S3 Bucket name for AIOps Integration Test'
# Lambda Role for Bucket Policy Update
BucketPolicyLambdaRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub '${AWS::StackName}-bucket-policy-lambda-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
Policies:
- PolicyName: !Sub '${AWS::StackName}-bucket-policy-lambda-policy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:PutBucketPolicy
Resource: !GetAtt S3BucketAIOpsIntegration.Arn
# Lambda Function for Bucket Policy Update
BucketPolicyLambda:
Type: 'AWS::Lambda::Function'
Properties:
FunctionName: !Sub '${AWS::StackName}-bucket-policy-lambda'
Handler: 'index.lambda_handler'
Role: !GetAtt BucketPolicyLambdaRole.Arn
Code:
ZipFile: |
import boto3
import json
import os
def lambda_handler(event, context):
try:
s3 = boto3.client('s3')
bucket_name = os.environ['BUCKET_NAME']
role_arn = os.environ['LAMBDA_ROLE_ARN']
bucket_policy = {
"Version": "2012-10-17",
"Id": "Policy[已去除电话]",
"Statement": [{
"Sid": "DenyBucketAccess",
"Effect": "Deny",
"Principal": {
"AWS": role_arn
},
"Action": "s3:ListBucket",
"Resource": f"arn:aws:s3:::{bucket_name}"
}, {
"Sid": "DenyObjectAccess",
"Effect": "Deny",
"Principal": {
"AWS": role_arn
},
"Action": "s3:GetObject",
"Resource": f"arn:aws:s3:::{bucket_name}/*"
}]
}
s3.put_bucket_policy(
Bucket=bucket_name,
Policy=json.dumps(bucket_policy)
)
return {
'statusCode': 200,
'body': 'Bucket policy updated successfully'
}
except Exception as e:
print(f"Error: {str(e)}")
return {
'statusCode': 500,
'body': f"Error updating bucket policy: {str(e)}"
}
Runtime: python3.13
Timeout: 30
MemorySize: 128
Environment:
Variables:
BUCKET_NAME: !Ref S3BucketAIOpsIntegration
LAMBDA_ROLE_ARN: !GetAtt LambdaRoleAIOpsIntegration.Arn
LambdaTriggerBucketPolicyAlarm:
Type: 'AWS::CloudWatch::Alarm'
Properties:
AlarmName: !Sub '${AWS::StackName}-lambda-trigger-alarm'
AlarmDescription: 'Alarm when Lambda is triggered 3 or more times'
MetricName: 'Invocations'
Namespace: 'AWS/Lambda'
Dimensions:
- Name: FunctionName
Value: !Ref LambdaAIOpsIntegration
Statistic: 'Sum'
Period: 60
EvaluationPeriods: 1
Threshold: 3
ComparisonOperator: 'GreaterThanOrEqualToThreshold'
TreatMissingData: 'notBreaching'
AlarmActions:
- !GetAtt BucketPolicyLambda.Arn
# Lambda Permission for CloudWatch Alarm
BucketPolicyLambdaPermission:
Type: 'AWS::Lambda::Permission'
Properties:
FunctionName: !Ref BucketPolicyLambda
Action: 'lambda:InvokeFunction'
Principal: 'lambda.alarms.cloudwatch.amazonaws.com'
SourceAccount: !Ref 'AWS::AccountId'
SourceArn: !Sub 'arn:aws:cloudwatch:${AWS::Region}:${AWS::AccountId}:alarm:${AWS::StackName}-lambda-trigger-alarm'
BedrockLambdaRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub '${AWS::StackName}-bedrock-lambda-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/CloudWatchLambdaApplicationSignalsExecutionRolePolicy'
Policies:
- PolicyName: !Sub '${AWS::StackName}-bedrock-lambda-policy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: logs:CreateLogGroup
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*'
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${AWS::StackName}-bedrock-lambda:*'
- Effect: Allow
Action:
- s3:PutObject
Resource: !Sub '${S3BucketAIOpsIntegration.Arn}/*'
- Effect: Allow
Action:
- bedrock:InvokeModel
Resource: '*'
- Effect: Allow
Action:
- xray:PutTraceSegments
- xray:PutTelemetryRecords
Resource: '*'
- Effect: Allow
Action:
- ssm:GetParameter
Resource: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${AWS::StackName}/bucket-name'
# Bedrock Lambda Function
BedrockLambda:
Type: 'AWS::Lambda::Function'
Properties:
FunctionName: !Sub '${AWS::StackName}-bedrock-lambda'
Handler: 'index.lambda_handler'
Role: !GetAtt BedrockLambdaRole.Arn
Code:
ZipFile: |
import boto3
import base64
import json
import os
def get_bucket_name():
ssm = boto3.client('ssm')
parameter_name = os.environ['BUCKET_NAME_PARAMETER']
response = ssm.get_parameter(Name=parameter_name)
return response['Parameter']['Value']
def lambda_handler(event, context):
try:
# Initialize S3 and Bedrock clients
s3 = boto3.client('s3')
bedrock = boto3.client('bedrock-runtime')
# Get bucket name from Parameter Store
bucket_name = get_bucket_name()
print(f"Using bucket: {bucket_name}")
print("Generating images using Bedrock...")
# Prepare request body for Bedrock
request_body = {
"taskType": "TEXT_IMAGE",
"textToImageParams": {
"text": "Provide me images of different breeds of Dogs with Sunglasses",
"negativeText": "Dont include cats"
},
"imageGenerationConfig": {
"numberOfImages": 5,
"height": 1024,
"width": 1024,
"cfgScale": 8.0,
"seed": 0
}
}
# Call Bedrock to generate image
response = bedrock.invoke_model(
modelId="amazon.titan-image-generator-v1",
contentType="application/json",
accept="application/json",
body=json.dumps(request_body)
)
# Parse response and save image to S3
response_body = json.loads(response['body'].read())
for idx, image in enumerate(response_body['images']):
# Decode base64 image
image_data = base64.b64decode(image)
# Upload to S3
file_name = f"generated_image_{idx}.jpg"
s3.put_object(
Bucket=bucket_name,
Key=file_name,
Body=image_data,
ContentType='image/jpeg'
)
print("Images generated and stored in S3")
return {
'statusCode': 200,
'body': json.dumps({'message': 'Images generated successfully'})
}
except Exception as e:
print(f"Error: {str(e)}")
return {
'statusCode': 500,
'body': json.dumps({'message': 'Internal Server Error - HTTP 500'})
}
Runtime: python3.13
Timeout: 300
MemorySize: 1024
Environment:
Variables:
BUCKET_NAME_PARAMETER: !Sub '/${AWS::StackName}/bucket-name'
TracingConfig:
Mode: Active
# Custom Resource Lambda Role
TriggerLambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
Policies:
- PolicyName: InvokeBedrockLambda
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: 'lambda:InvokeFunction'
Resource: !GetAtt BedrockLambda.Arn
# Custom Resource Lambda
TriggerLambda:
Type: 'AWS::Lambda::Function'
Properties:
FunctionName: !Sub '${AWS::StackName}-trigger-lambda'
Handler: 'index.lambda_handler'
Role: !GetAtt TriggerLambdaRole.Arn
Code:
ZipFile: |
import boto3
import cfnresponse
def lambda_handler(event, context):
try:
if event['RequestType'] == 'Create':
lambda_client = boto3.client('lambda')
response = lambda_client.invoke(
FunctionName=f"{event['ResourceProperties']['StackName']}-bedrock-lambda",
InvocationType='Event'
)
print("Successfully triggered Bedrock Lambda")
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
else:
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
print(f"Error: {str(e)}")
cfnresponse.send(event, context, cfnresponse.FAILED, {})
Runtime: python3.13
Timeout: 30
MemorySize: 128
TriggerCustomResource:
Type: 'Custom::TriggerBedrock'
DependsOn:
- S3BucketAIOpsIntegration
- BedrockLambda
Properties:
ServiceToken: !GetAtt TriggerLambda.Arn
StackName: !Ref 'AWS::StackName'
# Updated Lambda Role with SSM permissions
LambdaRoleAIOpsIntegration:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub '${AWS::StackName}-lambda-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/CloudWatchLambdaApplicationSignalsExecutionRolePolicy'
Policies:
- PolicyName: !Sub '${AWS::StackName}-lambda-policy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: logs:CreateLogGroup
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*'
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
- Effect: Allow
Action:
- s3:GetObject
- s3:ListBucket
Resource:
- !GetAtt S3BucketAIOpsIntegration.Arn
- !Sub '${S3BucketAIOpsIntegration.Arn}/*'
- Effect: Allow
Action:
- xray:PutTraceSegments
- xray:PutTelemetryRecords
Resource: '*'
- Effect: Allow
Action:
- ssm:GetParameter
Resource: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${AWS::StackName}/bucket-name'
# Updated Lambda Function with SSM parameter for S3 Bucket
LambdaAIOpsIntegration:
Type: 'AWS::Lambda::Function'
Properties:
FunctionName: !Sub '${AWS::StackName}-aiops-lambda'
Handler: 'index.lambda_handler'
Role: !GetAtt LambdaRoleAIOpsIntegration.Arn
Code:
ZipFile: |
import boto3
import random
import base64
import os
import json
def get_bucket_name():
ssm = boto3.client('ssm')
parameter_name = os.environ['BUCKET_NAME_PARAMETER']
response = ssm.get_parameter(Name=parameter_name)
return response['Parameter']['Value']
def lambda_handler(event, context):
try:
# Initialize S3 client
s3 = boto3.client('s3')
# Get bucket name from Parameter Store
bucket_name = get_bucket_name()
print(f"Using bucket: {bucket_name}")
# List all objects
response = s3.list_objects_v2(Bucket=bucket_name)
if 'Contents' not in response:
return {
'statusCode': 404,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
'body': '{"message": "No images found"}'
}
# Filter for both .jpg and .jpeg files
image_files = [obj for obj in response['Contents']
if obj['Key'].lower().endswith(('.jpg', '.jpeg'))]
if not image_files:
return {
'statusCode': 404,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
'body': '{"message": "No JPG/JPEG images found"}'
}
# Select random image
random_image = random.choice(image_files)
print(f"Selected image: {random_image['Key']}")
# Get the image
image = s3.get_object(
Bucket=bucket_name,
Key=random_image['Key']
)
# Get image data
image_data = image['Body'].read()
# Return binary response for API Gateway
return {
'statusCode': 200,
'headers': {
'Content-Type': 'image/jpeg'
},
'body': base64.b64encode(image_data).decode('utf-8'),
'isBase64Encoded': True
}
except Exception as e:
print(f"Error: {str(e)}")
return {
'statusCode': 500,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({
"message": "Internal Server Error"
})
}
Runtime: python3.13
Timeout: 60
MemorySize: 128
Environment:
Variables:
BUCKET_NAME_PARAMETER: !Sub '/${AWS::StackName}/bucket-name'
TracingConfig:
Mode: Active
# API Gateway Role
ApiGatewayRoleAIOpsIntegration:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub '${AWS::StackName}-apigw-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: apigateway.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs'
# API Gateway Account Settings
ApiGatewayAccountConfig:
Type: 'AWS::ApiGateway::Account'
Properties:
CloudWatchRoleArn: !GetAtt ApiGatewayRoleAIOpsIntegration.Arn
# REST API Gateway
ApiGatewayAIOpsIntegration:
Type: 'AWS::ApiGateway::RestApi'
Properties:
Name: !Sub '${AWS::StackName}-api'
Description: 'API for random image service'
EndpointConfiguration:
Types:
- REGIONAL
BinaryMediaTypes:
- 'image/jpeg'
- '*/*'
# API Resource
ApiResourceRandom:
Type: 'AWS::ApiGateway::Resource'
Properties:
RestApiId: !Ref ApiGatewayAIOpsIntegration
ParentId: !GetAtt ApiGatewayAIOpsIntegration.RootResourceId
PathPart: 'random'
# API Method
ApiMethodGet:
Type: 'AWS::ApiGateway::Method'
Properties:
RestApiId: !Ref ApiGatewayAIOpsIntegration
ResourceId: !Ref ApiResourceRandom
HttpMethod: GET
AuthorizationType: NONE
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaAIOpsIntegration.Arn}/invocations'
# Enable CORS
ApiMethodOptions:
Type: 'AWS::ApiGateway::Method'
Properties:
RestApiId: !Ref ApiGatewayAIOpsIntegration
ResourceId: !Ref ApiResourceRandom
HttpMethod: OPTIONS
AuthorizationType: NONE
Integration:
Type: MOCK
IntegrationResponses:
- StatusCode: 200
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
method.response.header.Access-Control-Allow-Origin: "'*'"
ResponseTemplates:
application/json: ''
MethodResponses:
- StatusCode: 200
ResponseParameters:
method.response.header.Access-Control-Allow-Headers: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Origin: true
# API Deployment
ApiDeployment:
Type: 'AWS::ApiGateway::Deployment'
DependsOn:
- ApiMethodGet
- ApiMethodOptions
Properties:
RestApiId: !Ref ApiGatewayAIOpsIntegration
# API Stage
ApiStage:
Type: 'AWS::ApiGateway::Stage'
DependsOn: ApiGatewayAccountConfig
Properties:
DeploymentId: !Ref ApiDeployment
RestApiId: !Ref ApiGatewayAIOpsIntegration
StageName: 'prod'
Description: 'Production Stage'
TracingEnabled: true
MethodSettings:
- ResourcePath: '/*'
HttpMethod: '*'
MetricsEnabled: true
DataTraceEnabled: true
LoggingLevel: INFO
# Lambda Permission
LambdaPermission:
Type: 'AWS::Lambda::Permission'
Properties:
Action: 'lambda:InvokeFunction'
FunctionName: !Ref LambdaAIOpsIntegration
Principal: apigateway.amazonaws.com
SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayAIOpsIntegration}/*'
# API Gateway 5XX Error Alarm
ApiGateway5XXAlarm:
Type: 'AWS::CloudWatch::Alarm'
Properties:
AlarmName: !Sub '${AWS::StackName}-api-5xx-error-alarm'
AlarmDescription: 'Alarm when API Gateway returns 5XX errors'
MetricName: '5XXError'
Namespace: 'AWS/ApiGateway'
Dimensions:
- Name: ApiName
Value: !Sub '${AWS::StackName}-api'
- Name: Stage
Value: 'prod'
Statistic: 'Sum'
Period: 300
EvaluationPeriods: 1
Threshold: 1
ComparisonOperator: 'GreaterThanOrEqualToThreshold'
TreatMissingData: 'notBreaching'
Outputs:
S3BucketName:
Description: 'Name of the created S3 bucket'
Value: !Ref S3BucketAIOpsIntegration
LambdaFunctionName:
Description: 'Name of the created Lambda function'
Value: !Ref LambdaAIOpsIntegration
BedrockLambdaName:
Description: 'Name of the Bedrock Lambda function'
Value: !Ref BedrockLambda
TriggerLambdaName:
Description: 'Name of the Trigger Lambda function'
Value: !Ref TriggerLambda
BucketPolicyLambdaName:
Description: 'Name of the Bucket Policy Lambda function'
Value: !Ref BucketPolicyLambda
CloudWatchAlarmName:
Description: 'Name of the CloudWatch Alarm'
Value: !Ref LambdaTriggerBucketPolicyAlarm
ApiGateway5XXAlarmName:
Description: 'Name of the API Gateway 5XX Error Alarm'
Value: !Ref ApiGateway5XXAlarm
ApiEndpoint:
Description: 'API Gateway Endpoint URL'
Value: !Sub 'https://${ApiGatewayAIOpsIntegration}.execute-api.${AWS::Region}.amazonaws.com/prod/random'

创建堆栈的时候请注意将下面命令行的 参数 `

–template-body` 中的文件路径和文件名匹配到您当前的文件存储位置和文件名。

# 创建 CloudFormation 堆栈
aws cloudformation create-stack \
--stack-name aiops-demo \
--template-body file:///【您的文件路径】/【您的文件名】.yaml \
--capabilities CAPABILITY_NAMED_IAM

部署完成后,我们可以测试 API 是否正常工作:

# 获取 API 端点
API_ENDPOINT=$(aws cloudformation describe-stacks \
--stack-name aiops-demo \
--query "Stacks[0].Outputs[?OutputKey=='ApiEndpoint'].OutputValue" \
--output text)
# 测试 API
curl -v $API_ENDPOINT

此时,API 应该能够正常返回一张随机图片。

我們可以透過 x-ray 查看部署的 service map

!trace_map

步骤 2:触发故障场景

为了模拟故障场景,我们将触发 CloudWatch 告警,该告警会自动调用 Lambda 函数修改 S3 存储桶策略,阻止 Lambda 函数访问 S3 存储桶:

# 获取 Lambda 函数名称
LAMBDA_FUNCTION=$(aws cloudformation describe-stacks \
--stack-name aiops-demo \
--query "Stacks[0].Outputs[?OutputKey=='LambdaFunctionName'].OutputValue" \
--output text)
# 多次调用 Lambda 函数触发告警
for i in {1..5}; do
aws lambda invoke \
--function-name $LAMBDA_FUNCTION \
--payload '{}' \
/dev/null
echo "Invocation $i completed"
sleep 2
done

这将触发 CloudWatch 告警,进而调用修改 S3 存储桶策略的 Lambda 函数。策略修改后,主 Lambda 函数将无法访问 S3 存储桶,导致 API 返回错误。

步骤 3:验证故障

几分钟后,我们再次测试 API:

# 测试 API
curl -v $API_ENDPOINT

此时,API 应该返回 500 错误,表明应用程序出现了故障。

!500_error

步骤 4:使用 CloudWatch AIOps 进行根因分析

现在,我们将使用 CloudWatch AIOps 来分析和解决这个问题。

方法 1:通过 CloudWatch 告警进行分析

1. 登录 AWS 管理控制台,导航到 CloudWatch 服务

2. 在左侧导航栏中,选择”告警”

3. 找到触发的 API Gateway 5XX 错误告警

!step1.1

4. 点击”调查”按钮启动 CloudWatch AIOps 分析

!step1.4

输入一个 investigation title, 並且点击”开始调查”

!investigation-details

CloudWatch AIOps 提供一个引导式的问题排查流程,在右侧会显示排查结果,我们可以通过 Accept 或 Decline 按钮,决定是否采纳该结果作为问题的根本原因分析依据。

CloudWatch AIOps 将自动收集相关数据并开始分析。分析完成后,它会显示一个调查报告,包括:

问题概述:API Gateway 返回 5XX 错误

修复建议:恢复 S3 存储桶策略的正确配置

根本原因:S3 存储桶策略变更阻止了 Lambda 函数访问 S3 存储桶

影响范围:分析受影响的资源和服务

时间线:问题发生的时间和相关事件

相关证据:CloudTrail 日志显示的 S3 策略变更事件

查看S3 存储桶的 event record

方法 2:通过 Amazon Q 进行分析

1. 在 AWS 管理控制台中,打开 Amazon Q

2. 输入自然语言查询,例如:”我的 API Gateway 返回 500 错误,请帮我分析原因”

3. Amazon Q 将启动 CloudWatch AIOps 分析,并提供类似的调查报告

步骤 5:解决问题

根据 CloudWatch AIOps 的建议,我们可以修复 S3 存储桶策略:

# 获取 S3 存储桶名称
S3_BUCKET=$(aws cloudformation describe-stacks \
--stack-name aiops-demo \
--query "Stacks[0].Outputs[?OutputKey=='S3BucketName'].OutputValue" \
--output text)
# 删除错误的存储桶策略
aws s3api delete-bucket-policy --bucket $S3_BUCKET
修复后,我们再次测试 API:

bash

利用 CloudWatch AIOps 实现智能化根因分析与故障排查

curl -v $API_ENDPOINT

“`

此时,API 应该恢复正常,能够返回随机图片。

分析结果解读

CloudWatch AIOps 的分析报告提供了以下关键信息:

1. 问题识别:

API Gateway 5XX 错误率突然增加

Lambda 函数出现 AccessDenied 错误

2. 根因确定:

CloudTrail 日志显示 S3 存储桶策略在问题发生前被修改

新策略明确拒绝了 Lambda 执行角色访问 S3 存储桶

3. 影响路径:

S3 策略变更 → Lambda 无法访问 S3 → API Gateway 返回 500 错误

4. 时间相关性:

问题开始时间与 S3 策略变更时间高度一致

没有其他相关的配置变更或系统事件

5. 修复建议:

恢复 S3 存储桶策略

实施更严格的权限控制和变更管理

添加更详细的监控和告警

这个演示展示了 CloudWatch AIOps 如何快速识别配置变更导致的问题,并提供明确的修复建议,大大减少了故障排查时间。

未来展望:全程自动化的智能运维

随着云计算和人工智能技术的不断发展,我们可以展望一个更加自动化和智能化的运维未来。CloudWatch AIOps 只是这一发展方向的开始,未来的智能运维系统将实现更高级别的自动化和预测能力。

资源的自动创建与管理

未来的智能运维系统将能够:

1. 自动化基础设施部署:

基于应用需求自动设计和部署最佳架构

持续优化资源配置,平衡性能和成本

自动扩展和收缩资源,适应负载变化

2. 智能配置管理:

自动生成符合最佳实践的配置

预测配置变更的潜在影响

防止有风险的配置变更

3. 自我修复能力:

检测到问题后自动启动修复流程

学习和改进修复策略

在问题影响用户之前解决潜在问题

告警的自动生成与优化

传统的告警配置通常是静态的,需要人工设置和维护。未来的智能运维系统将实现:

1. 自适应告警阈值:

基于历史数据和季节性模式自动调整阈值

考虑业务上下文和重要性

减少误报和漏报

2. 异常检测告警:

自动识别异常模式,无需预定义阈值

学习系统的正常行为

检测复杂的多维异常

3. 预测性告警:

预测潜在问题,在问题发生前发出警告

估计问题的严重性和影响范围

提供预防措施建议

自动化问题解决流程

未来的智能运维系统将不仅能够发现问题,还能自动解决问题:

1. 自动化修复工作流:

根据根因分析结果自动执行修复操作

验证修复效果,必要时回滚

记录和学习修复经验

2. 智能事件管理:

自动分类和优先级排序

智能路由到合适的团队或系统

协调复杂问题的解决流程

3. 持续学习和改进:

从每次事件中学习

改进分析和修复策略

预防类似问题再次发生

运维角色的转变

随着智能运维系统的发展,运维人员的角色将发生重大转变:

1. 从执行者到设计者:

设计自动化策略和工作流

定义运维最佳实践和策略

创建和优化自动化模板

2. 从被动响应到主动预防:

分析趋势和模式,预测潜在问题

实施预防措施,提高系统弹性

持续优化系统架构和配置

3. 从技术专家到业务伙伴:

将技术洞察转化为业务价值

参与战略决策和规划

推动技术创新和业务转型

总结

CloudWatch AIOps 代表了运维领域的一次重大变革,它将人工智能和机器学习技术应用于复杂系统的故障排查,大大提高了运维效率和系统可靠性。通过自动化根因分析,CloudWatch AIOps 帮助运维团队快速定位和解决问题,减少平均故障排除时间,提高用户满意度。

本文探讨了 CloudWatch AIOps 的核心功能和工作原理,并通过一个实际案例展示了它如何帮助排查 S3 权限问题。我们还展望了智能运维的未来发展方向,包括资源的自动创建与管理、告警的自动生成与优化,以及自动化问题解决流程。

随着云计算和人工智能技术的不断发展,智能运维将成为企业数字化转型的关键推动力。CloudWatch AIOps 只是这一发展方向的开始,未来的智能运维系统将实现更高级别的自动化和预测能力,彻底改变传统的运维方式。

对于企业来说,现在是时候开始探索和采用这些智能运维技术,为未来的数字化转型做好准备。通过结合 CloudWatch AIOps 和其他 AWS CloudOps 产品,企业可以构建一个全面的智能运维平台,提高系统可靠性,降低运维成本,加速业务创新。

参考资源

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者


Lightsail流量监控与自动扩容方案

AWS账单代付阅读(65)

亚马逊AWS官方博客

Lightsail流量监控与自动扩容方案

引言

Amazon Lightsail 以其简洁的界面和可预测的固定月费,成为了许多开发者和小型企业的首选云服务。用户期望的是一笔清晰固定的月度开销,然而在实际使用中,许多用户都曾遇到一个令人困惑的难题:尽管业务流量看似平稳,月底却收到了远超预期的账单,其主要原因来自数据传输(流量)的超额费用。本文将介绍一种方案来监控和自动扩容Lightsail来避免流量超出导致的额外账单。

Lightsail流量计算规则

  • Lightsail每台累计流量单独计算
  • 所有Lightsail产生的流量会均分到区域已启动的所有相同的Lightsail作为累计流量
  • 任意一台流量累计超过限额则会产生费用
  • 删除/停机无法避免流量继续累计
  • 流量周期为自然月
  • Lightsail实例按包月价格平均到小时收费
  • 监控思路

  • 基于产生流量均分的规则,Lightsail流量相当于一个区域级别的流量池,扩容可以减少流量对于每台Lightsail的累计速度
  • 监控需要根据每个月的时间进度对比流量使用进度来进行预警和扩容,这样是最安全可靠的方式
  • 计算当月运行时长最久实例的剩余流量 x 区域相同lightsail的数量 = 当月剩余流量池
  • 自动扩容逻辑:当月运行时长最久实例的剩余流量 x (区域相同lightsail的数量 +扩容数量)= 当月剩余流量池
  • 扩容的机器可以只启动不使用,可以避免业务上的修改配置
  • 监控部署在Lambda,输出可选email/短信/电话/im机器人消息等各种灵活渠道
  • 推荐监控周期,一天 2~6次(基于预测,不需要太过密集,也可以提高监控频率)
  • 监控流程图

    方案架构

这个方案架构较为简单,直接使用Event Bridge来进行定时任务触发,使用Lambda来进行逻辑检测和自动扩容逻辑,使用SNS来进行通知

告警输出&可选参数

  • 告警输出可以根据需要,编写各种渠道的报警,比如短信、邮件、IM的告警 (一般IM都会有机器人,开放一个公开的api来使用)
  • 在监控流程中,调整缓冲流量大小,可以最大程度的避免流量超出费用,比如当月时间已过50%,这时候流量使用了流量池的45%,这时候也启动扩容,避免后续出现风险
  • 也可以每日都输出一个报表,报告流量使用的进度,同时证明这个监控在运行
  • 场景示例一

  • 月初$5 bundle的Lightsail 有100台,这时候流量池供100T
  • 15日监控检测到使用了55T,时间进度为50%,流量进度为55%,每台Lightsail剩余流量45T
  • 触发告警和自动扩容
  • 预测该月剩余时长使用55T,需要扩容 (55T/0.45T) -100 = 23台
  • 流量损耗(0.55T*23) = 12.65T
  • 场景示例二

  • 月初$5 bundle的Lightsail 有300台,这时候流量池供300T
  • 5日检测使用流量60T,时间进度为1/6,流量进度为1/5. 每台Lightsail剩余流量8T
  • 触发告警和自动扩容
  • 预测该月剩余时长使用300T流量,需要扩容(300T/0.8T)-300 = 75台
  • 流量损耗2T*75 = 15T
  • 总结

本方案核心逻辑是根据流量使用的进度和自然月时间流逝的进度对比来预测流量是否够用。通过进度来进行预测监控,可以更早发现进度异常进行监控和自动扩容,最大程度的避免流量超出。月中扩容会有一定的流量损耗,但根据按小时计费的规则,如果按进度来监控,实际损失不大。


PCB智能视觉质检: 轻松上手SageMaker训练YOLO并部署到Lambda

AWS账单代付阅读(56)

引言

PCB印刷电路板(PCB)的质量是电子产品可靠性的关键。然而,随着PCB设计日益复杂,传统的人工目检或基础AOI(自动化光学检测)在效率、精度和成本控制上面临严峻挑战,难以满足现代制造业的需求。检测速度慢、易出错、漏检误报率高成为了生产中的常见痛点。人工智能(AI)视觉技术为此提供了强大的解决方案。利用深度学习,我们可以训练模型自动、快速且准确地识别PCB上的各种缺陷,大幅提升质检效率和一致性。

本篇博客将向你展示如何在AWS利用一套高效的云技术栈,轻松构建PCB智能视觉质检系统。我们将重点介绍:

YOLO (You Only Look Once): 一种领先的实时目标检测算法,擅长快速定位和分类PCB上的缺陷。

Amazon SageMaker: AWS提供的一站式机器学习平台,它极大地简化了YOLO模型的训练、调优过程。

AWS Lambda: 一种无服务器计算服务,用于经济高效地部署训练好的模型,实现弹性伸缩的在线推理。

接下来,我们将带你一步步实践,从数据准备到模型训练,最终将智能检测模型部署上线。

关键步骤

数据准备

在AI视觉项目中,数据质量就是生命线。“Garbage In, Garbage Out” —— 模型的性能上限完全取决于训练数据的质量和代表性。因此,为PCB缺陷检测精心准备数据至关重要。

核心要点:

  • 高质量数据:高质量、多样化的数据是训练出强大泛化能力模型的基础。在此投入时间是值得的。数据最好是源于生产线的真实缺陷数据
  • 精确标注:对于YOLO模型,我们需要为每个缺陷绘制边界框 (Bounding Box) 并指定类别标签 (Class Label)。标注必须精确且标准一致。
  • 数据集划分与格式:将数据分为训练集、验证集(用于调优)和测试集(用于最终评估),常见比例为70/20/10或80/10/10。确保标注文件符合YOLO要求的格式

在本文中,为了便于测试验证,采用网上公开数据集来进行验证。

模型训练与调优

对于YOLO这种模型的训练较为简单,我们使用Sagemaker笔记本直接进行训练。先创建一个Sagemaker笔记本实例,我这里使用的实例型号是ml.g4dn.xlarge,然后创建训练脚本,训练脚本示例如下:

%pip install sagemaker

%pip install ultralytics

%pip install datasets

from datasets import Dataset

from ultralytics import YOLO

!pip install roboflow

from roboflow import Roboflow

rf = Roboflow(api_key=”xxx”)

project = rf.workspace(“xxx”).project(“xxxxx”)

version = project.version(1)

dataset = version.download(“yolov11”)

from IPython.display import display, Image

!yolo task=detect mode=train model=/home/ec2-user/SageMaker/yolo11m.pt data=/home/ec2-user/SageMaker/PCB_defect-1/data.yaml epochs=150 imgsz=800 plots=True

这里的训练数据使用的是roboflow平台上的pcb公开的数据集格式用于测试和验证,生产中需要使用实际生产的图片和标注数据。此外这里模型路径使用的是绝对路径,也可以忽略路径自动下载基础模型。训练结束后,会在笔记本目录里生成新的模型文件,可以下载下来或者上传到S3以便后续部署。

无服务器部署:将YOLO模型部署至AWS Lambda (对应Lambda部署)

在上一个步骤最后训练得到了最终的权重模型后,使用这个模型来部署在lambda进行推理,这里选用python镜像部署的方式

Python依赖如下

opencv-python-headless

ultralytics

Pillow

Lambda示例代码如下:

import base64

import os

import cv2

from ultralytics import YOLO

from PIL import Image

import io

PCB智能视觉质检: 轻松上手SageMaker训练YOLO并部署到Lambda

MODEL_LOCAL_PATH = os.path.join(os.environ[‘LAMBDA_TASK_ROOT’], ‘models/best.pt’)

model = YOLO(MODEL_LOCAL_PATH)

缺陷名称映射

defect_names_map = {

0: “Missing hole”,

1: “Mouse bite”,

2: “Open circuit”,

3: “Short”,

4: “Spur”,

5: “Supurious copper”

}

def lambda_handler(event, context):

image_data = event.get(‘file_data’)

“””处理图像并进行缺陷检测”””

image_bytes = base64.b64decode(image_data)

转换为PIL图像

img = Image.open(io.BytesIO(image_bytes))

预测

results = model.predict(img)

处理结果

boxes = results[0].boxes

将图像转换为OpenCV格式以便绘制

plotted_img = results[0].plot()

将绘制后的图像编码为base64

_, buffer = cv2.imencode(‘.jpg’, plotted_img)

plotted_base64 = base64.b64encode(buffer).decode(‘utf-8’)

提取缺陷信息

defects = []

if len(boxes) > 0:

defect_indices = boxes.cls.cpu().numpy()

confidences = boxes.conf.cpu().numpy()

for i, cls_idx in enumerate(defect_indices):

cls_idx = int(cls_idx)

if cls_idx in defect_names_map:

defects.append({

“type”: defect_names_map[cls_idx],

“confidence”: float(confidences[i])

})

计算缺陷摘要

defect_summary = {}

for defect in defects:

defect_type = defect[“type”]

if defect_type in defect_summary:

defect_summary[defect_type] += 1

else:

defect_summary[defect_type] = 1

return {

“processed_image”: plotted_base64,

“defects”: defects,

“defect_count”: len(defects),

“defect_summary”: defect_summary

}

实战演示:端到端的智能质检流程

通过容器部署lambda后,就可以使用这个函数来进行缺陷检测了,输入为图片的base64格式,输出检测的结果和图片的缺陷标注

图片的缺陷标注如下图,图中通过标注框指出了可能是短路缺陷的部分

总结与展望

本文介绍了一套高效的方案来构建PCB缺陷检测程序,通过Sagemaker笔记本高效训练模型,然后通过AWS Lambda无服务器快速部署推理。使用这套方案可以快速进行业务上的验证和演示,以及一些低负载的生产场景。对于一些高并发场景的缺陷检测或者视频场景的缺陷检测,部署到AWS的GPU实例会是更具性能优势的选择。同时数据的质量也决定了最终模型的效果,在生产中,最推荐的是使用实际生产的数据来进行数据标注然后训练模型,这样准确度会更高。

本篇作者


守护数据安全:Aurora最短停机时间迁移到私有子网的终极攻略

AWS账单代付阅读(67)

亚马逊AWS官方博客

守护数据安全:Aurora最短停机时间迁移到私有子网的终极攻略

随着企业增强其关键业务数据库和账户的安全性,将数据库此类关键资源隔离在私有子网中的需求日益凸显。在AWS上管理关键业务数据库时,安全和合规性要求也经常需要将Amazon Aurora实例从公有子网迁移到私有子网。降低迁移过程中的停机时间至关重要,因为企业要求对其服务的干扰降到最低。在本文中,我们将展示如何在保持停机时间绝对最小化的前提下,将Aurora集群中的实例从公有子网迁移到私有子网。

概览

Amazon Aurora 目前不提供在同一VPC内直接更改数据库实例子网组的选项,但您可以通过此文中的方法实现相同的效果。我们将通过“修改数据库子网组”和“故障转移”结合的方式,实现在最短停机时间内将Amazon Aurora实例从公有子网安全转移到私有子网。

方案主要优势:

  • 最大限度减少停机时间
  • 保留端点配置不变
  • 实现方式

    前置条件

1.您Aurora数据库实例所处的VPC中已有私有子网。例如下图中蓝色点呈现的子网为此VPC中的所有私有子网。

2.Aurora数据库实例目前在公有子网中。例如,目前在

us-east-2b的公有子网

subnet-02186a2ba75cb35b0中,并且使用的子网组为

Demo-subnet-group。

添加私有子网到数据库所用的子网组中

1.勾选数据库当前使用的子网组后,点击“编辑“。

2.添加私有子网到子网组中。

3.除数据库节点当前所在使用的公有子网外,删除其余公有子网。

创建在私有子网中的数据库只读节点

1.勾选Aurora数据库集群,点击“操作”后,选择“添加读取器”,创建数据库只读节点。

2.选择子网中只有私有子网的可用区。例如本试验环境中,目前主节点在

us-east-2b的公有子网

subnet-02186a2ba75cb35b0中,这里选择

us-east-2a。

3.添加读取器。

通过“故障转移”,将处于私有子网中的只读节点提升为主节点

等待只读节点创建完成,点击“操作”,选择“故障转移”。

确定进行故障转移后,大约花费秒级故障切换完成。切换完成后,可见实例已经转为“写入器实例”。

删除新的只读节点(原主节点)

在“操作”菜单中,选择“删除”,删除原数据库节点。

彻底删除数据库子网组中的公有子网

待原数据节点删除后,再次修改数据子网组。删除最后一个公有子网,仅留下私有子网组。

总结

巧妙结合”修改数据库子网组”与”故障转移”的方式,让您能以最短的服务中断时间将Aurora实例从公有子网安全转移到私有子网。整个过程中您的数据库端点配置保持不变,无需更新应用程序连接字符串,既最大限度减少了停机时间,又保留了原有端点配置,确保业务平稳过渡。


AWS Generative AI Use Cases:“开箱即用的企业级生成式AI应用平台”

AWS账单代付阅读(73)

亚马逊AWS官方博客

AWS Generative AI Use Cases:“开箱即用的企业级生成式AI应用平台”

从零开始构建企业级生成式AI应用面临诸多技术挑战:模型选择与集成复杂、安全合规要求严格、开发周期长、维护成本高。AI应用开发需要深厚的机器学习背景、复杂的基础设施搭建,以及大量的前端开发工作。

为解决这些痛点,2023年AWS Japan的志愿者团队开发并开源了Generative AI Use Cases(简称GenU)项目。作为”客户生成式AI活用促进支持”的重要组成部分,GenU是一个基于Amazon Bedrock构建的企业级生成式AI应用解决方案。

GenU的诞生背景:

  • 2023年初:启动项目,旨在提供“立即可用的生成式AI用例集”
  • 持续进化:紧跟Amazon Bedrock新功能,不断扩充新用例
  • 2024年11月:发布“用例构建器”,实现无代码AI应用开发
  • 全球影响:从日本本土项目扩展为全球开源项目,获得1.1k+ stars
  • 多语言版本:最新版本已经支持中日英语言

GenU提供14种开箱即用的AI用例,涵盖对话、文档处理、多媒体生成、业务自动化等场景。特别是Use Case Builder无代码开发环境,让非技术人员也能创建定制AI应用。

[Gen用例]

产品特性与架构

丰富的AI用例库 基础对话类Chat:支持多轮对话的智能聊天,可快速响应各种业务咨询 RAG Chat:基于企业内部文档的检索增强生成,实现知识库问答 Agent Chat:通过API集成外部系统,执行复杂的业务任务 Voice Chat:双向语音对话,支持实时中断和角色设定(英语对话)

[智能聊天]

内容处理类Summarize:智能文档摘要和关键信息提取 Translation:多语言翻译,支持上下文和专业术语 Writing:写作辅助和文档校对 Text Generation 生成商务文档,包括文章、报告和电子邮件 Video Analysis:通过摄像头分析视频内容

[写作助手]

多媒体生成类Image Generation:基于文本描述生成图像 Video Generation:文本到视频的内容创作 Diagram Generation:自动生成流程图、架构图等技术图表

[图像生成助手]

[视频生成助手]

业务自动化类Meeting Minutes Generation:会议录音自动转换为结构化纪要 Web Content Extraction:网页内容智能提取和格式化

[会议实时转录和纪要生成]

用例构建器:无代码AI应用开发

GenU的核心创新是用例构建器(Use Case Builder),这是一个无代码的AI应用开发环境,让非技术人员也能创建定制化的AI应用。

[构建者模式]

核心特性:

  • 占位符语法:通过 {{text:标签}} 和 {{file:标签}} 语法自动生成用户界面
  • 自动UI生成:根据提示模板中的占位符自动创建输入表单
  • 无需代码修改:完全通过自然语言描述创建用例,无需修改GenU代码
  • 共享机制:创建的用例可与所有登录用户共享,支持.json格式导入导出

[定制化的AI应用:创建问卷问题和选项]

系统架构设计

GenU采用现代化的无服务器架构,确保高可用性和弹性扩展:

核心组件

  • AWS Lambda处理业务逻辑
  • Amazon API Gateway
  • Amazon DynamoDB存储用户数据和配置信息
  • Amazon S3存储文件和静态资源
  • Amazon Cognito User Pool管理用户身份
  • Amazon CloudFront + AWS WAF
  • Amazon Transcribe实现语音转文字
  • Amazon Polly提供文字转语音

[GenU系统架构]

Amazon Bedrock** **集成

GenU的核心优势在于与Amazon Bedrock的深度集成,提供业界领先的基础模型选择::

文本生成模型

  • Anthropic Claude系列
  • Amazon Nova系列
  • DeepSeek R1系列
  • Meta Llama系列

多媒体模型

  • 图像生成:Amazon Nova Canvas、Stability AI系列
  • 视频生成:Amazon Nova Reel、Luma Ray等
  • 语音处理:Amazon Nova Sonic语音合成

[Bedrock提供广泛的模型选择]

模型调用: 通过Lambda函数封装Bedrock API调用,支持跨区域模型访问: *参考:https://github.com/aws-samples/generative-ai-use-cases/blob/main/packages/cdk/lambda/utils/bedrockApi.ts*

灵活的配置管理系统

丰富的安全配置选项

访问控制

  • 邮箱域名限制:`allowedSignUpEmailDomains` 邮箱注册
  • IP地址限制:通过AWS WAF限制访问来源IP
  • 地理位置限制:基于地理位置访问控制
  • 自注册控制:`selfSignUpEnabled` 控制用户自注册
  • 身份认证集成

  • Amazon Cognito用户池管理
  • SAML 2.0企业SSO集成(支持Google Workspace、Microsoft Entra ID)
  • 多因素认证支持

[Web方式登陆]

集成RAG(检索增强生成)功能

GenU的RAG共,支持Amazon Kendra和Knowledge Base两种数据源。

[RAG相关组件]

智能Agent生态系统

GenU支持内置的Web搜索和代码解释Agent,也支持导入Bedrock Agent,还支持MCP。

[Bedrock Agents]

[在GenU中集成Bedrock Agents]

Token** **使用情况

查看使用情况和Model的Token消耗记录

[Statistics]

部署指南

快速部署

GenU提供多种部署方式,支持不同的技术背景和需求

最简单的是使用AWS CloudShell一键部署(推荐)**: **部署前置要求

  • 在Amazon Bedrock控制台启用所需模型
  • 确保AWS账户具备CDK部署权限
  • 部署时间约10-20分钟

[部署信息]

定制化部署

GenU通过cdk.json和parameter.ts提供了企业级的配置管理能力,支持多环境部署和高级功能定制::

方式二:packages/cdk/parameter.ts多环境配置

指定环境的升级部署和功能定制

针对特定环境做版本升级,可定制化启用或屏蔽功能

总结

AWS Generative AI Use Cases (GenU)提供一个完整的生成式AI应用解决方案。通过开箱即用的用例库、无代码开发环境和企业级安全架构,大大降低了企业采用生成式AI的技术门槛和成本。

GenU项目在GitHub上持续活跃更新,拥有1.1k stars和309 forks,得到了全球开发者社区的广泛认可。对于希望快速构建企业级生成式AI应用的组织,GenU提供了一个理想的起点。

[GenU持续更新]

相关资源

  • GitHub仓库:https://github.com/aws-samples/generative-ai-use-cases
  • 官方文档:https://aws-samples.github.io/generative-ai-use-cases/en/
  • *前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。


AWS代付、代充值免实名

联系我们阿里云国际免实名