Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >别再说你不会 ElasticSearch 调优了,都给你整理好了

别再说你不会 ElasticSearch 调优了,都给你整理好了

作者头像
芋道源码
发布于 2019-06-15 09:33:25
发布于 2019-06-15 09:33:25
1.2K0
举报
文章被收录于专栏:芋道源码1024芋道源码1024

点击上方“芋道源码”,选择“设为星标

做积极的人,而不是积极废人!

源码精品专栏

来源:http://tinyurl.com/y4gnzbje

  1. 第一部分:调优索引速度
  2. 第二部分-调优搜索速度
  3. 第三部分:通用的一些建议

ES发布时带有的默认值,可为es的开箱即用带来很好的体验。全文搜索、高亮、聚合、索引文档 等功能无需用户修改即可使用,当你更清楚的知道你想如何使用es后,你可以作很多的优化以提高你的用例的性能,下面的内容告诉你 你应该/不应该 修改哪些配置

第一部分:调优索引速度

(https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html)

  1. 使用批量请求批量请求将产生比单文档索引请求好得多的性能。

为了知道批量请求的最佳大小,您应该在具有单个分片的单个节点上运行基准测试。 首先尝试索引100个文件,然后是200,然后是400,等等。 当索引速度开始稳定时,您知道您达到了数据批量请求的最佳大小。 在配合的情况下,最好在太少而不是太多文件的方向上犯错。 请注意,如果群集请求太大,可能会使群集受到内存压力,因此建议避免超出每个请求几十兆字节,即使较大的请求看起来效果更好。

  1. 发送端使用多worker/多线程向es发送数据 发送批量请求的单个线程不太可能将Elasticsearch群集的索引容量最大化。 为了使用集群的所有资源,您应该从多个线程或进程发送数据。 除了更好地利用集群的资源,这应该有助于降低每个fsync的成本。

请确保注意TOO_MANY_REQUESTS(429)响应代码(Java客户端的EsRejectedExecutionException),这是Elasticsearch告诉您无法跟上当前索引速率的方式。 发生这种情况时,应该再次尝试暂停索引,理想情况下使用随机指数回退。

与批量调整大小请求类似,只有测试才能确定最佳的worker数量。 这可以通过逐渐增加工作者数量来测试,直到集群上的I / O或CPU饱和。

  1. 调大 refresh interval 默认的index.refresh_interval是1s,这迫使Elasticsearch每秒创建一个新的分段。 增加这个价值(比如说30s)将允许更大的部分flush并减少未来的合并压力。
  2. 加载大量数据时禁用refresh和replicas 如果您需要一次加载大量数据,则应该将index.refresh_interval设置为-1并将index.number_of_replicas设置为0来禁用刷新。这会暂时使您的索引处于危险之中,因为任何分片的丢失都将导致数据 丢失,但是同时索引将会更快,因为文档只被索引一次。 初始加载完成后,您可以将index.refresh_interval和index.number_of_replicas设置回其原始值。
  3. 设置参数,禁止OS将es进程swap出去 您应该确保操作系统不会swapping out the java进程,通过禁止swap (https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html)
  4. 为filesystem cache分配一半的物理内存 文件系统缓存将用于缓冲I / O操作。 您应该确保将运行Elasticsearch的计算机的内存至少减少到文件系统缓存的一半。
  5. 使用自动生成的id(auto-generated ids) 索引具有显式id的文档时,Elasticsearch需要检查具有相同id的文档是否已经存在于相同的分片中,这是昂贵的操作,并且随着索引增长而变得更加昂贵。 通过使用自动生成的ID,Elasticsearch可以跳过这个检查,这使索引更快。
  6. 买更好的硬件 搜索一般是I/O 密集的,此时,你需要 a.为filesystem cache分配更多的内存 b.使用SSD硬盘 c.使用local storage(不要使用NFS、SMB 等remote filesystem) d.亚马逊的 弹性块存储(Elastic Block Storage)也是极好的,当然,和local storage比起来,它还是要慢点 如果你的搜索是 CPU-密集的,买好的CPU吧
  7. 加大 indexing buffer size 如果你的节点只做大量的索引,确保index.memory.index_buffer_size足够大,每个分区最多可以提供512 MB的索引缓冲区,而且索引的性能通常不会提高。 Elasticsearch采用该设置(java堆的一个百分比或绝对字节大小),并将其用作所有活动分片的共享缓冲区。 非常活跃的碎片自然会使用这个缓冲区,而不是执行轻量级索引的碎片。

默认值是10%,通常很多:例如,如果你给JVM 10GB的内存,它会给索引缓冲区1GB,这足以承载两个索引很重的分片。

  1. 禁用_field_names字段 _field_names字段引入了一些索引时间开销,所以如果您不需要运行存在查询,您可能需要禁用它。 (_field_names:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-field-names-field.html)
  2. 剩下的,再去看看 “调优 磁盘使用”吧 (https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-disk-usage.html)中有许多磁盘使用策略也提高了索引速度。

第二部分-调优搜索速度

  1. filesystem cache越大越好 为了使得搜索速度更快, es严重依赖filesystem cache 一般来说,需要至少一半的 可用内存 作为filesystem cache,这样es可以在物理内存中 保有 索引的热点区域(hot regions of the index)
  2. 用更好的硬件 搜索一般是I/O bound的,此时,你需要 a.为filesystem cache分配更多的内存 b.使用SSD硬盘 c.使用local storage(不要使用NFS、SMB 等remote filesystem) d.亚马逊的 弹性块存储(Elastic Block Storage)也是极好的,当然,和local storage比起来,它还是要慢点 如果你的搜索是 CPU-bound,买好的CPU吧
  3. 文档模型(document modeling) 文档需要使用合适的类型,从而使得 search-time operations 消耗更少的资源。咋作呢? 答:避免 join操作。具体是指 a.nested 会使得查询慢 好几倍 b.parent-child关系 更是使得查询慢几百倍 如果 无需join 能解决问题,则查询速度会快很多
  4. 预索引 数据 根据“搜索数据最常用的方式”来最优化索引数据的方式 举个例子: 所有文档都有price字段,大部分query 在 fixed ranges 上运行 range aggregation。你可以把给定范围的数据 预先索引下。然后,使用 terms aggregation
  5. Mappings(能用 keyword 最好了) 数字类型的数据,并不意味着一定非得使用numeric类型的字段。 一般来说,存储标识符的 字段(书号ISBN、或来自数据库的 标识一条记录的 数字),使用keyword更好(integer,long 不好哦,亲) 6.避免运行脚本 一般来说,脚本应该避免。 如果他们是绝对需要的,你应该使用painless和expressions引擎。
  6. 搜索rounded 日期 日期字段上使用now,一般来说不会被缓存。但,rounded date则可以利用上query cache rounded到分钟等
  7. 强制merge只读的index 只读的index可以从“merge成 一个单独的 大segment”中收益
  8. 预热 全局序数(global ordinals) 全局序数 用于 在 keyword字段上 运行 terms aggregations es不知道 哪些fields 将 用于/不用于 term aggregation,因此 全局序数 在需要时才加载进内存 但,可以在mapping type上,定义 eager_global_ordinals==true,这样,refresh时就会加载 全局序数
  9. 预热 filesystem cache 机器重启时,filesystem cache就被清空。OS将index的热点区域(hot regions of the index)加载进filesystem cache是需要花费一段时间的。 设置 index.store.preload 可以告知OS 这些文件需要提早加载进入内存

11使用索引排序来加速连接 索引排序对于以较慢的索引为代价来加快连接速度非常有用。在索引分类文档中阅读更多关于它的信息。

12.使用preference来优化高速缓存利用率 有多个缓存可以帮助提高搜索性能,例如文件系统缓存,请求缓存或查询缓存。然而,所有这些缓存都维护在节点级别,这意味着如果连续运行两次相同的请求,则有一个或多个副本,并使用循环(默认路由算法),那么这两个请求将转到不同的分片副本,阻止节点级别的缓存帮助。

由于搜索应用程序的用户一个接一个地运行类似的请求是常见的,例如为了分析索引的较窄的子集,使用标识当前用户或会话的优选值可以帮助优化高速缓存的使用。

13.副本可能有助于吞吐量,但不会一直存在 除了提高弹性外,副本可以帮助提高吞吐量。例如,如果您有单个分片索引和三个节点,则需要将副本数设置为2,以便共有3个分片副本,以便使用所有节点。

现在假设你有一个2-shards索引和两个节点。在一种情况下,副本的数量是0,这意味着每个节点拥有一个分片。在第二种情况下,副本的数量是1,这意味着每个节点都有两个碎片。哪个设置在搜索性能方面表现最好?通常情况下,每个节点的碎片数少的设置将会更好。原因在于它将可用文件系统缓存的份额提高到了每个碎片,而文件系统缓存可能是Elasticsearch的1号性能因子。同时,要注意,没有副本的设置在发生单个节点故障的情况下会出现故障,因此在吞吐量和可用性之间进行权衡。

那么复制品的数量是多少?如果您有一个具有num_nodes节点的群集,那么num_primaries总共是主分片,如果您希望能够一次处理max_failures节点故障,那么正确的副本数是max(max_failures,ceil(num_nodes / num_primaries) - 1)。

14.打开自适应副本选择 当存在多个数据副本时,elasticsearch可以使用一组称为自适应副本选择的标准,根据包含分片的每个副本的节点的响应时间,服务时间和队列大小来选择数据的最佳副本。这可以提高查询吞吐量并减少搜索量大的应用程序的延迟。

第三部分:通用的一些建议

1、不要 返回大的结果集 es设计来作为搜索引擎,它非常擅长返回匹配query的top n文档。但,如“返回满足某个query的 所有文档”等数据库领域的工作,并不是es最擅长的领域。如果你确实需要返回所有文档,你可以使用Scroll API

2、避免 大的doc。即,单个doc 小了 会更好 given that(考虑到) http.max_context_length默认==100MB,es拒绝索引操作100MB的文档。当然你可以提高这个限制,但,Lucene本身也有限制的,其为2GB 即使不考虑上面的限制,大的doc 会给 network/memory/disk带来更大的压力; a.任何搜索请求,都需要获取 _id 字段,由于filesystem cache工作方式。即使它不请求 _source字段,获取大doc _id 字段消耗更大 b.索引大doc时消耗内存会是 doc本身大小 的好几倍 c.大doc的 proximity search, highlighting 也更加昂贵。它们的消耗直接取决于doc本身的大小

3、避免 稀疏 a.不相关数据 不要 放入同一个索引 b.一般化文档结构(Normalize document structures) c.避免类型 d.在 稀疏 字段上,禁用 norms & doc_values 属性

稀疏为什么不好? Lucene背后的数据结构 更擅长处理 紧凑的数据 text类型的字段,norms默认开启;numerics, date, ip, keyword,doc_values默认开启 Lucene内部使用 integer的doc_id来标识文档 和 内部API交互。 举个例子: 使用match查询时生成doc_id的迭代器,这些doc_id被用于获取它们的norm,以便计算score。当前的实现是每个doc中保留一个byte用于存储norm值。获取norm值其实就是读取doc_id位置处的一个字节 这非常高效,Lucene通过此值可以快速访问任何一个doc的norm值;但,给定一个doc,即使某个field没有值,仍需要为此doc的此field保留一个字节 doc_values也有同样的问题。2.0之前的fielddata被现在的doc_values所替代了。 稀疏性 最明显的影响是 对存储的需求(任何doc的每个field,都需要一个byte);但是呢,稀疏性 对 索引速度和查询速度 也是有影响的,因为:即使doc并没有某些字段值,但,索引时,依然需要写这些字段,查询时,需要skip这些字段的值 某个索引中拥有少量稀疏字段,这完全没有问题。但,这不应该成为常态 稀疏性影响最大的是 norms&doc_values ,但,倒排索引(用于索引 text以及keyword字段),二维点(用于索引geo_point字段)也会受到较小的影响

如何避免稀疏呢? 1、不相关数据 不要 放入同一个索引 给个tip:索引小(即:doc的个数较少),则,primary shard也要少 2、一般化文档结构(Normalize document structures) 3、避免类型(Avoid mapping type) 同一个index,最好就一个mapping type 在同一个index下面,使用不同的mapping type来存储数据,听起来不错,但,其实不好。given that(考虑到)每一个mapping type会把数据存入 同一个index,因此,多个不同mapping type,各个的field又互不相同,这同样带来了稀疏性 问题 4、在 稀疏 字段上,禁用 norms & doc_values 属性 a.norms用于计算score,无需score,则可以禁用它(所有filtering字段,都可以禁用norms) b.doc_vlaues用于sort&aggregations,无需这两个,则可以禁用它 但是,不要轻率的做出决定,因为 norms&doc_values无法修改。只能reindex

秘诀1:混合 精确查询和提取词干(mixing exact search with stemming) 对于搜索应用,提取词干(stemming)都是必须的。例如:查询 skiing时,ski和skis都是期望的结果 但,如果用户就是要查询skiing呢? 解决方法是:使用multi-field。同一份内容,以两种不同的方式来索引存储 query.simple_query_string.quote_field_suffix,竟然是 查询完全匹配的

秘诀2:获取一致性的打分 score不能重现 同一个请求,连续运行2次,但,两次返回的文档顺序不一致。这是相当坏的用户体验

如果存在 replica,则就可能发生这种事,这是因为: search时,replication group中的shard是按round-robin方式来选择的,因此两次运行同样的请求,请求如果打到 replication group中的不同shard,则两次得分就可能不一致

那问题来了,“你不是整天说 primary和replica是in-sync的,是完全一致的”嘛,为啥打到“in-sync的,完全一致的shard”却算出不同的得分?

原因就是标注为“已删除”的文档。如你所知,doc更新或删除时,旧doc并不删除,而是标注为“已删除”,只有等到 旧doc所在的segment被merge时,“已删除”的doc才会从磁盘删除掉

索引统计(index statistic)是打分时非常重要的一部分,但,由于 deleted doc 的存在,在同一个shard的不同copy(即:各个replica)上 计算出的 索引统计 并不一致

个人理解: a. 所谓 索引统计 应该就是df,即 doc_freq b. 索引统计 是基于shard来计算的

  1. 搜索时,“已删除”的doc 当然是 永远不会 出现在 结果集中的
  2. 索引统计时,for practical reasons,“已删除”doc 依然是统计在内的

假设,shard A0 刚刚完成了一次较大的segment merge,然后移除了很多“已删除”doc,shard A1 尚未执行 segment merge,因此 A1 依然存在那些“已删除”doc

于是:两次请求打到 A0 和 A1 时,两者的 索引统计 是显著不同的

如何规避 score不能重现 的问题?使用 preference 查询参数 发出搜索请求时候,用 标识字符串 来标识用户,将 标识字符串 作为查询请求的preference参数。这确保多次执行同一个请求时候,给定用户的请求总是达到同一个shard,因此得分会更为一致(当然,即使同一个shard,两次请求 跨了 segment merge,则依然会得分不一致) 这个方式还有另外一个优点,当两个doc得分一致时,则默认按着doc的 内部Lucene doc id 来排序(注意:这并不是es中的 _id 或 _uid)。但是呢,shard的不同copy间,同一个doc的 内部Lucene doc id 可能并不相同。因此,如果总是达到同一个shard,则,具有相同得分的两个doc,其顺序是一致的

score错了 score错了(Relevancy looks wrong) 如果你发现

  1. 具有相同内容的文档,其得分不同
  2. 完全匹配 的查询 并没有排在第一位 这可能都是由 sharding 引起的
  3. 默认情况下,搜索文档时,每个shard自己计算出自己的得分。
  4. 索引统计 又是打分时一个非常重要的因素。

如果每个shard的 索引统计相似,则 搜索工作的很好 文档是平分到每个primary shard的,因此 索引统计 会非常相似,打分也会按着预期工作。但,万事都有个但是:

  1. 索引时使用了 routing(文档不能平分到每个primary shard 啦)
  2. 查询多个索引
  3. 索引中文档的个数 非常少 这会导致:参与查询的各个shard,各自的 索引统计 并不相似(而,索引统计对 最终的得分 又影响巨大),于是 打分出错了(relevancy looks wrong)

那,如何绕过 score错了(Relevancy looks wrong)?

如果数据集较小,则,只使用一个primary shard(es默认是5个),这样两次查询 索引统计 不会变化,因而得分也就一致啦 另一种方式是,将search_type设置为:dfs_query_then_fetech(默认是query_then_fetch) dfs_query_then_fetch的作用是

  1. 向 所有相关shard 发出请求,要求 所有相关shard 返回针对当前查询的 索引统计
  2. 然后,coordinating node 将 merge这些 索引统计,从而得到 merged statistics
  3. coordinating node 要求 所有相关shard 执行 query phase,于是 发出请求,这时,也带上 merged statistics。这样,执行query的shard 将使用 全局的索引统计 大部分情况下,要求 所有相关shard 返回针对当前查询的 索引统计,这是非常cheap的。但,如果查询中 包含 非常大量的 字段/term查询,或者有 fuzzy查询,此时,获取 索引统计 可能并不cheap,因为 为了得到 索引统计 可能 term dictionary 中 所有的term都需要被查询一遍

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 芋道源码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
30 个 ElasticSearch 调优知识点,都给你整理好了!
ES发布时带有的默认值,可为es的开箱即用带来很好的体验。全文搜索、高亮、聚合、索引文档 等功能无需用户修改即可使用,当你更清楚的知道你想如何使用es后,你可以作很多的优化以提高你的用例的性能,下面的内容告诉你 你应该/不应该 修改哪些配置。
肉眼品世界
2021/09/03
7440
【ElasticSearch面试】10道不得不会的ElasticSearch面试题
以下是 ElasticSearch 面试题,相信大家都会有种及眼熟又陌生的感觉、看过可能在短暂的面试后又马上忘记了。**JavaPub**在这里整理这些容易忘记的重点知识及**解答**,建议收藏,经常温习查阅。
JavaPub
2022/03/26
1.3K0
【ElasticSearch面试】10道不得不会的ElasticSearch面试题
万字长文,理解Elasticsearch和面试总结
约 10+ 索引,5 分片,每日新增数据量约为 2G,4000w 条。记录保存 30 天。
开发者技术前线
2020/11/23
1.1K0
万字长文,理解Elasticsearch和面试总结
Elasticsearch索引和检索优化与压测监控总结
先来看看es的整体架构图,上面有多个重要模块,今天主要写在lucene上面的index模块与search模块的优化经历,力求简要写出改变了configuration之后,会给es cluster带来什么样的影响。
王知无-import_bigdata
2020/06/11
1.4K0
这份​Elasticsearch 工作笔记,值得收藏
从事Elasticsearch云产品的研发已经四年多了,在服务公有云客户的过程中也遇到了各种各样的使用方式以及问题,本文就把过去几年记录的一些问题和解决办法进行归类和总结,常读常新。
bellen
2022/03/14
1.8K0
这份​Elasticsearch 工作笔记,值得收藏
Elasticsearch集群规划最佳实践
一个节点在默认情况会下同时扮演:master eligible,data node 和 ingest node。
Se7en258
2021/05/18
1.6K0
Elasticsearch集群规划最佳实践
ElasticSearch性能优化官方建议
ES是设计成一个搜索引擎的,只擅长返回匹配查询较少文档,如果需要返回非常多的文档需要使用Scroll。
cutd
2020/03/04
1.2K0
Elasticsearch 8.X 检索实战调优锦囊 001
可以考虑用 filter “包裹一层”,如处理时间范围检索,Elasticsearch 能缓存部分结果。但,要说明的是更换时间窗口,换不同时间段检索,原有缓存不起作用。
铭毅天下
2022/09/26
1.3K0
Elasticsearch 8.X 检索实战调优锦囊 001
Elasticsearch深入:数据持久化过程
Elasticsearch 存储的基本单元是shard, ES中一个Index 可能分为多个shard, 事实上每个shard 都是一个Lucence 的Index,并且每个Lucence Index 由多个Segment组成, 每个Segment事实上是一些倒排索引的集合, 每次创建一个新的Document, 都会归属于一个新的Segment, 而不会去修改原来的Segment; 且每次的文档删除操作,会仅仅标记Segment中该文档为删除状态,而不会真正的立马物理删除, 所以说ES的index 可以理解为一个抽象的概念。
HLee
2020/12/28
4.5K0
Elasticsearch深入:数据持久化过程
干货 | Elasticsearch通用优化建议
Elasticsearch开发实战的后期会遇到性能问题,包括:创建索引性能、写入数据性能、检索性能等。网上有很多结合自己实际应用场景的相关优化建议,但“对症下药”才是关键。
铭毅天下
2018/10/09
1.3K0
Elasticsearch调优实践
在规模比较大的集群中,可以防止新建shard时扫描所有shard的元数据,提升shard分配速度。
HLee
2021/02/08
5950
Elasticsearch调优实践
2021-Java后端工程师面试指南-(Elasticsearch)
面试指南系列,很多情况下不会去深挖细节,是小六六以被面试者的角色去回顾知识的一种方式,所以我默认大部分的东西,作为面试官的你,肯定是懂的。
用户9927510
2022/07/29
3730
ElasticSearch常见面试题汇总
Elasticsearch 是基于 Lucene 的 Restful 的分布式实时全文搜索引擎,每个字段都被索引并可被搜索,可以快速存储、搜索、分析海量的数据。
TimeFriends
2022/06/24
5690
ElasticSearch常见面试题汇总
Elasticsearch(五)
ES 的默认配置已经提供了良好的开箱即用的体验,但是仍有一些优化手段去继续提升它的使用性能。
凌虚
2020/07/17
9210
Elasticsearch调优实践
本文基于ES 5.6.4,从性能和稳定性两方面,从linux参数调优、ES节点配置和ES使用方式三个角度入手,介绍ES调优的基本方案。当然,ES的调优绝不能一概而论,需要根据实际业务场景做适当的取舍和调整,文中的疏漏之处也随时欢迎批评指正。
技术姐
2018/07/04
14K3
Elasticsearch调优实践
严选 | Elasticsearch中文社区201901错题本
马云演讲中曾经提到:很多时候少听成功专家的话。所有的创业者多花点时间学习别人是怎么失败的,因为成功的原因有千千万万,失败的原因就一两个点。
铭毅天下
2019/03/07
9870
用 ElasticSearch 搭建自己的搜索和分析引擎
文章主要讲述了如何通过ElasticSearch来搭建一个搜索和分析引擎。首先介绍了ElasticSearch的基本概念,然后阐述了ElasticSearch的基本使用方法和API,并针对一个搜索场景,介绍了ElasticSearch的具体实现过程。最后,介绍了如何利用ElasticSearch搭建自己的搜索和分析引擎,并提供了代码示例。
WeTest质量开放平台团队
2017/04/17
6.5K0
用 ElasticSearch 搭建自己的搜索和分析引擎
触类旁通Elasticsearch:优化
ES提供的批量(bulk)API,可以用来一次索引多篇文档,从而大幅加快索引速度。如图1所示,可以使用http完成这个操作,并且将获得包含全部索引请求结果的答复。
用户1148526
2019/05/25
1.2K0
《Elasticsearch 源码解析与优化实战》第20章:磁盘使用量优化
优化磁盘使用量与建立索引时的映射参数和索引元数据字段密切相关,在介绍具体的优化措施之前,我们先介绍这两方面的基础知识。
HLee
2021/07/27
8950
《Elasticsearch 源码解析与优化实战》第20章:磁盘使用量优化
一次看完28个关于ES的性能调优技巧,很赞,值得收藏!
因为总是看到很多同学在说Elasticsearch性能不够好、集群不够稳定,询问关于Elasticsearch的调优,但是每次都是一个个点的单独讲,很多时候都是case by case的解答,本文简单梳理下日常的Elasticsearch使用调优,以下仅为自己日常经验之谈,如有疏漏,还请大家帮忙指正。
程序员白楠楠
2020/11/24
3.1K0
相关推荐
30 个 ElasticSearch 调优知识点,都给你整理好了!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档