Elasticsearch LogsDB 发展历程:如何在不降低吞吐量的情况下,将索引大小减少多达 75%

news2026/4/28 1:17:21
Elasticsearch 最初是作为搜索引擎构建的。这种传承在日志存储方面是有代价的每个事件都会扩散到多个磁盘结构中每个结构都针对检索而非压缩进行了优化。LogsDB 改变了这一切。在我们的每晚基准测试中企业模式Enterprise mode下同样的数据在没有 LogsDB 的情况下需要 161.9 GB而使用 LogsDB 仅产生 37.5 GB 的索引——仅通过一个设置就减少了 77%。写入开销作为底层库的 Lucene 会为每个索引文档保留多个结构倒排索引 (Inverted index)将词条映射到文档。这是实现快速文本搜索的关键。_source存储原始 JSON 块在获取文档时返回。Doc values以列式存储字段值用于排序和聚合。Points / BKD 树对数值和日期字段进行索引用于范围查询。倒排索引物有所值它让你能在毫秒内通过关键词搜索数十亿条日志而且没有比这更廉价的方式来实现这种能力。_source的存在是为了让你能准确拿回索引时的内容搜索结果和GET请求会直接返回这个块。问题在于尽管相同的字段值已经可以通过 doc values 和其他结构获得它仍然存储了完整的事件。以一个包含host.name、timestamp、http.response.status_code和duration_ms等字段的日志事件为例。整个事件作为 JSON 序列化存储在_source中。同时相同的字段值还会被写入 doc values 列、编入倒排索引并存储在用于范围查询的 BKD 树中。相同的数据多个结构每个都有自己的磁盘占用。对于需要跨所有维度快速检索的搜索引擎来说这种开销是合理的权衡。但对于日志你很少需要原始 JSON也几乎从不做相关性排序搜索因此其中大部分都是纯粹的浪费。一次写入四个磁盘结构_source原始 JSON 块、倒排索引、doc values 列以及用于数值范围查询的 BKD/Points 树。相同的字段值最终出现在多个地方。为什么列式存储对压缩至关重要Doc values 是 LogsDB 所有功能的关键。与将整个文档存储为块的_source不同doc values 将 Lucene 段segment内所有文档的每个字段存储为独立的列。想象一个拥有一百万个日志事件的段。_source的表现形式是一百万个 JSON 块每个事件一个每个块都包含杂乱交织的所有字段。而 doc values 的表现形式是一组列一列包含一百万个时间戳一列包含一百万个主机名一列包含一百万个状态码依此类推。行式存储的_source将每个文档的所有字段保存在一个块中——doc0 到 doc5 每个都带着混合在一起的host.name、timestamp、status、duration_ms等。列式存储的 doc values 重新组织了相同的数据使所有host.name值位于一列所有时间戳位于另一列所有状态码位于又一列。随后压缩编解码器codecs可以独立地在每个连续的列上运行。这种列式布局使得逐列压缩成为可能。当所有的http.response.status_code值都位于一个连续的列中时Lucene 可以应用利用序列模式的编解码器。增量编码 (Delta encoding)存储相邻值之间的差异而非完整值。最大公约数编码 (GCD encoding)寻找公共因子并进行除法压缩。游程编码 (Run-length encoding, RLE)则折叠重复项。Lucene 会为每个段挑选编解码器并在段合并时重新评估。来自同一主机的四个已排序timestamps的四个阶段压缩。原始 (RAW)四个 32 位整数共 128 位。增量 (DELTA)存储差异而非完整值——保留基准值增量 100、200、300 占用 59 位。最大公约数 (GCD)除以公共因子 100剩下 1、2、3占用 39 位。位包装 (BIT-PACK)将这三个小整数打包进连续的位存储释放 9 位。但这里有一个关键这些编解码器只有在相邻文档具有相关值时才有效。以timestamp列为例。如果日志是从几十个主机随机交错到达的那么列中的时间戳会跳跃不定。相邻值之间的增量可能是 3 秒然后是 -47 秒接着是 120 秒。增量编码对此无能为力。现在考虑一下如果在写入段之前先按host.name和timestamp进行排序。来自 host-A 的所有日志都会连续存放接着是来自 host-B 的所有日志依此类推。在每个主机的连续数据中时间戳是单调递增的且增量是可预测的。来自同一主机的四个时间戳可能看起来像 1706745600, 100s, 200s, 300s。增量编码将它们缩小为一个基准值加上三个小整数。GCD 编码发现 100, 200, 300 都能被 100 整除于是存储 1, 2, 3。位包装随后将这三个值放入极少数的位中。同样的模式也适用于host.name、service.name或http.response.status_code等字段在一个排序后的序列中长段的相同值在游程编码下几乎会折叠为零。五个主机——api-01, api-02, db-01, web-01, web-02——按到达顺序随机分散左。按host.name排序后将它们分为五个连续的 8 条目块中。游程编码将每个块折叠为单个值计数对——存储 5 对而非 40 个释放了剩余空间右。Elasticsearch 以前从未默认进行排序。文档按到达顺序存放并使用 DEFLATE 压缩。我们浪费了很多优化空间。演进历程2012–2026LogsDB 中的各项技术并非全都是为日志设计的。它们是在十二年间为了解决不同问题而构建的LogsDB 正是将这些技术堆叠在一起的结果。基础阶段 (2012–2017)。Lucene 4.0 在 2012 年引入了 doc values。到 2016 年的 Elasticsearch 5.0它们已成为所有 keyword 和数值字段的默认配置。Lucene 7.0 增加了稀疏 doc values这样仅在部分文档中出现的字段就不会在段中的每个文档上浪费空间。这解决了一个严重的强制合并膨胀问题在稀疏字段上最高可达 10 倍并建立了其他所有功能都依赖的存储模型。稠密编码Dense为每个文档保留一个 8 字节槽位无论是否存在值。稀疏编码Sparse仅存储有值的文档每个 12 字节值 文档 ID。对于填充率为 12% 的error_code稀疏编码小 81%24 B vs 128 B。对于填充率为 88% 的request_path稀疏编码反而更大。Lucene 会逐字段选择在填充率低于约 67% 时稀疏编码胜出。渐进式提升 (2020–2021)。两项较小的改动针对的是可观测性工作负载。基于字典的存储字段压缩对重复的字符串元数据进行了去重带来了约 10% 的提升。match_only_text字段类型从倒排索引中去掉了词频term frequencies和位置信息positions。词频是 BM25 用来根据相关性对文档评分的——即一个词条相对于整个语料库在文档中出现的频率。对于日志搜索这个信号毫无意义你不在乎 “timeout” 在一行日志中出现了两次还是七次你只想找到它。位置信息类似存储它是为了让 Elasticsearch 进行精确短语匹配但位置数据非常昂贵而且对日志的短语查询足够少见这种权衡是值得的。当你在match_only_text字段上运行短语查询时它仍然有效——只是会回退到一条较慢的路径通过重新评分候选文档而非直接使用存储的位置。text存储每个词条及其频率和出现的每个位置。match_only_text仅保留文档 ID——足以找到文档仅此而已。在此示例中timeout出现了两次位置 1 和 4这些数据会被丢弃。去掉频率和位置信息可以将文本字段的倒排索引减少约 40%。但在 2021 年整体索引的影响仅为约 10%对于 40% 的字段级缩减来说这听起来回报不高。原因是当时的存储分布_source以原始 JSON 块的形式完整存储doc values 未压缩且未排序也没有使用 ZSTD。message字段的倒排索引只是一个更大、压缩极差的整体中的一小部分。随着接下来的五年工作解决了其他结构的问题同样的 40% 字段级节省变成了更小总量中的重要组成部分。这两项改变本身都不是决定性的但它们确立了针对日志特定的存储优化是值得追求的。TSDB 转折点 (2023 年 4 月)。故事真正开始的地方。我们在 Elasticsearch 8.7 中为时序指标metrics发布了合成_source(synthetic_source)和索引排序。合成_source改变了读写约定。在写入时我们完全跳过存储原始 JSON 块。在读取时当查询需要返回原始文档我们通过从 doc values 和存储字段中读取每个字段的值并将它们重新组装成 JSON。其结果在功能上等同于原始_source仅在字段顺序等方面有细微差别但我们从未存储过那个块。索引排序在写入磁盘前按维度字段和时间戳对文档进行分组。合成_source和索引排序结合将指标存储减少了高达 70%。这个结果告诉我们一件重要的事情同样的架构也可以用于日志。在没有 LogsDB 的情况下Elasticsearch 将每个日志事件写入两次一次作为磁盘上的原始_source块一次写入 doc values 列。LogsDB 完全跳过该块。在读取时GET index/_doc/1请求会收集 doc values 字段值并即时组装文档。TSDB 编解码器 (2024 年)。在 8.13 和 8.14 中我们构建了一个自定义 doc values 编解码器针对排序后的连续值优化了游程编码以及 PFOR-delta 编码和针对多值维度的循环序号编码。数据非常惊人在一次基准测试中kubernetes.pod.name的 doc values 从 110 MB 降到了 7.25 MB。我们将覆盖范围扩大到了所有数值和关键字类型包括ip、scaled_float和unsigned_long。LogsDB 技术预览版 (2024 年 8 月)。在 8.15 中我们将所有功能整合到了index.mode: logsdb中主机优先排序、合成_source、ZSTD 压缩以及 TSDB 数值编解码器。一个决定比预想的更重要排序顺序。先按host.name排序再按timestamp排序可以减少高达约 40% 的存储。先按时间戳排序则只能减少 ≤10%。主机优先排序使共享字段值的文档聚集在一起这正是数值编解码器所需要的。LogsDB 要求使用自动生成的_id用户提供的 ID 会禁用合成_source和路由优化。ZSTD 与正式发布 (2024 年 11 月–12 月)。在 8.16 中我们将best_compression永久从 DEFLATE 切换到了 ZSTD3 级块大小最高 2,048 个文档或 240 kB在 JDK 21 上通过 Panama FFI 使用原生绑定。ZSTD 同时带来了约 12% 的存储空间减少和约 14% 的索引吞吐量提升这在性能调优中极少发生。LogsDB 在 8.17 中正式发布 (GA)。在 GA 时我们宣称存储减少最高可达 65%。路由与恢复 (2025 年 4 月)。在 8.18 中route_on_sort_fields开始根据排序字段值而非_id将文档路由到分片。如果没有这项优化Elasticsearch 会哈希_id来挑选分片因此来自同一主机的日志会分散在所有分片上。通过排序字段路由具有相似host.name值的日志会落在同一个分片上。这在分片级别而不只是段级别聚集了相似的文档在增加 1-4% 的摄取损耗下额外带来了约 20% 的存储缩减。包含六个主机、分布在三个分片上的数据流.ds-logs-nginx-default-00001。标准模式按_id哈希所有主机的颜色随机散布。路由模式route_on_sort_fields同一主机的日志落在同一分片但在分片内仍按到达顺序排列。路由排序模式主机优先排序每个分片包含单一主机的连续块——这种组合让数值编解码器和 RLE 发挥最大潜力。我们还将副本恢复切换为合成_source重构消除了重复的_recovery_source块。在 9.0 中logs-*-*索引默认启用 LogsDB。2024 年 12 月的每晚合成_source基准测试。当副本恢复从复制原始_recovery_source块切换为从 doc values 重构文档的那天写入的索引大小下降了 39%——从约 279 GB 降至约 171 GB。合并与恢复重构9.1 (2025 年 7 月)。我们完全消除了恢复源。副本恢复使用批量合成重构将写入 I/O 减少了约 50%并将中值索引吞吐量比 8.17 基准提升了约 19%。我们将多达四次独立的 doc values 合并过程替换为单次将后台合并 CPU 占用了减少了高达 40%。此外我们将_seq_no的 BKD 树替换为 Lucene doc value skippers使_seq_no存储减半。pattern_text 与失败存储9.2–9.3 (2025 年 10 月–2026 年 2 月)。在 9.2 中我们发布了pattern_text技术预览版这是一种新的字段类型可将日志消息分解为静态模板和动态变量部分。一行日志如Session opened for user alice from 10.0.1.42 via TLS会被拆分为模板Session opened for user {} from {} via TLS仅存储一次作为模板 ID和变量alice、10.0.1.42按文档存储。对于具有高模板重复率的日志这可以将 message 字段的存储减少高达 50%。配套的template_id子字段允许你按模板排序而 LogsDB 设置index.logsdb.default_sort_on_message_template会自动启用此功能。pattern_text在 9.3 中正式发布。TEXT 将每条日志消息作为每个文档的完整字符串存储——八个几乎相同的块副本。PATTERN_TEXT 对其进行分解共享模板存储一次ID 为 T0只有变量列user,ip按文档存储。pattern_text确实会带来索引 CPU 成本在写入时将每条消息分解为模板和变量比直接存储原始字符串需要更多工作。这种权衡是否合理取决于你的数据集和优先级。如果你的日志消息遵循高度重复的模式结构化应用日志、Kubernetes 事件、访问日志存储收益将非常巨大且 CPU 开销是有限的。如果你的消息是自由格式或重复率低压缩增益会缩小而 CPU 成本大致保持不变。对于保留数月或数年的数据累积的存储减少通常是值得的。对于存储不是瓶颈的高基数、快速变化的消息可能并不划算。9.3 还带来了二进制 doc values 的压缩使wildcard字段类型显著提高了存储效率。在内部wildcard 字段在二进制 doc values 列中存储三元组trigrams的倒排索引该列现在使用 Zstandard 压缩而非原始存储。在一次基准测试中URL 字段从 2.92 GB 降至 1.12 GB压缩率超过 60%。如果你大量使用wildcard字段这种增益是自动获得的无需更改映射。同样在 9.3 中针对timestamp和host.name的跳表skip lists成为了 LogsDB 的可选配置。跳表允许 Elasticsearch 在 doc values 列中向前跳过而无需读取每个条目从而加快大型段上的时间范围查询。其他索引模式默认禁用跳表在 LogsDB 中你可以有选择地为最常进行范围查询的字段启用它们。同样在 9.3 中失败存储 (Failure Store) 对logs-*-*数据流默认启用。失败的文档映射冲突、摄取管道错误现在会进入专用的::failures索引而非被直接拒绝这意味着 LogsDB 严格的合成_source要求在迁移过程中不太可能导致静默数据丢失。不仅仅是存储还有性能LogsDB 始于存储优化早期版本确实带来了吞吐量成本——排序、合成_source重构和 ZSTD 都会在写入时增加工作量。经过两年的版本迭代我们夺回了这些性能。现在的索引吞吐量已与用户启用 LogsDB 之前的水平持平。你在获得存储缩减的同时无需牺牲以往的摄取速率。自技术预览版以来吞吐量青色已从约 2.5k 攀升至约 3.5k docs/s。在相同的基准测试数据集上磁盘存储蓝色从约 65 GB 降至约 36 GB。在分层发布的推动下两条曲线都向着正确的方向移动。实时数据见 elasticsearch-benchmarks.elastic.co。这两个趋势互补。更少的存储意味着更少需要合并的段从而释放了 CPU 用于索引。合成_source重构的计算成本比存储和复制原始块更低。每一个缩小索引的版本也减少了后台 I/O这反过来又提升了吞吐量。实际结果是如果你两年前运行标准 Elasticsearch 进行日志摄取那么你当时拥有的吞吐量大致就是 LogsDB 现在能提供的——同时还伴随着缩小了 50-75% 的索引。如何启用从 9.0 开始logs-*-*数据流会自动默认使用 LogsDB。如果你的数据流匹配该模式你已经在使用了。想要动手尝试使用 LogsDB 将 Elasticsearch 日志存储成本降低 76%介绍了创建两个索引、重新索引并使用_statsAPI 衡量差异的过程包括针对 8.x 集群的版本特定启用说明。对于其他索引模式请在模板中进行设置PUT_index_template/logs-template{index_patterns:[logs-*],template:{settings:{index.mode:logsdb}}}合成_source会随index.mode: logsdb自动开启。对于路由优化 (8.18)再添加一个设置PUT_index_template/logs-template{index_patterns:[logs-*],template:{settings:{index.mode:logsdb,index.logsdb.route_on_sort_fields:true}}}这将按排序字段值而非_id路由分片在增加 1-4% 摄取损耗的情况下增加约 20% 的存储缩减。它要求在timestamp之外至少有两个排序字段并使用自动生成的_id。将现有索引切换到 LogsDB 需要重新索引reindex。回滚也是如此。目前没有就地转换功能因此请先在新的数据流上进行尝试。随着段的合并存储空间会进一步优化——新写入的数据压缩效果不错但合并后的段压缩效果更好。未来展望由于其搜索引擎的根源Elasticsearch 仍然带有一些结构性开销。_id和_seq_no就是两个例子两者都消耗了大量的磁盘空间在小文档上它们可能占到索引大小的一半以上但对于日志分析工作负载来说这两者都不是必不可少的。我们已经为 TSDB 迈出了第一步PR #144026 通过从 doc values 即时重构字段消除了 TSDB 索引中存储的_id字节这与合成_source使用的方法相同。我们正在为 LogsDB 探索同样的方向。9.4 及以后。该架构仍有改进空间我们正在努力。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…