干货 | Elasticsearch 8.X 性能优化实战

news2024/11/28 2:33:37

Elasticsearch 是实现用户无缝搜索体验的关键工具。它通过提供快速、准确和相关的搜索结果,彻底改变了用户与应用程序的互动方式。然而,要确保 Elasticsearch 部署达到最佳性能,就必须关注关键指标,并对诸如索引、缓存、查询、搜索以及存储等各种组件进行优化。

在本博文中,我们将深入探讨如何调整 Elasticsearch 以实现最佳性能和发挥最大潜能的最佳实践与技巧,从优化集群健康、搜索性能和索引,到精通缓存策略和存储选项。无论你是经验丰富的 Elasticsearch 专家,还是初涉此领域的新手,遵循一些最佳实践以确保部署具备性能、可靠性和可扩展性都至关重要。

adc1c8cd8fdaaea6adc9349fad758ed8.jpeg

1、通用优化建议

1.1 使用合适的硬件

Elasticsearch是一个内存密集型应用程序,因此使用足够内存的硬件非常重要。此外,建议使用固态硬盘(SSD)作为存储设备,因为它们可以显著提高索引和搜索性能。

尽管 SSD 的 I/O 性能优于传统硬盘,但如果 Elasticsearch 集群中的节点数量较多,I/O 性能仍然可能成为瓶颈。为了保证性能,可以采取一些优化措施,如使用 RAID 配置、合理的磁盘划分和负载均衡等。

RAID级别优点缺点适用场景
RAID 0高I/O性能,实现并行读写无冗余,磁盘故障可能导致数据丢失性能敏感型应用,可接受数据恢复时间
RAID 1数据冗余,磁盘故障时数据不丢失写入性能不如RAID 0数据安全性和可靠性较高的应用
RAID 5数据冗余,一定程度的I/O性能优势写入性能不如RAID 0需要在性能和数据安全性之间取得平衡的应用
RAID 10结合RAID 0和RAID 1的优点,高I/O性能和数据冗余需要更多磁盘,成本较高既需要保证性能又需要保证数据安全性的应用

1.2 规划索引策略

Elasticsearch设计用于处理大量数据,但需要考虑如何索引这些数据。这包括需要多少分片和副本,数据将如何索引,以及如何处理更新和删除。

  1. 分片数量

选择合适数量的分片以实现水平扩展和负载均衡。

默认情况下,每个索引有 1 个主分片。根据数据量和节点数量调整分片数量。尽量避免使用过多分片,因为每个分片都需要额外的资源和开销。

  1. 副本数量

增加副本数量以提高搜索性能和系统容错能力,但要辩证看,后文会详细解读。

默认情况下,每个分片有 1 个副本。根据负载和可用性需求调整副本数量。

  1. 数据索引策略

使用基于时间的索引生命周期管理策略(ILM)以提高查询性能和降低资源消耗。例如,为每天、每周或每月的数据创建一个新索引。

选择合适的字段类型和分析器。优化映射以减少存储空间和提高查询性能。

使用 Index Templates 自动应用映射和设置。

  1. 更新和删除处理

使用 Update API 更新文档,避免删除和重新索引整个文档。

合理使用 Elasticsearch 的版本控制特性。

考虑使用 Index Lifecycle Management (ILM) 自动管理索引的生命周期。根据具体业务需求和场景,灵活调整上述建议以优化 Elasticsearch 集群性能。

1.3 优化查询

Elasticsearch是一个功能强大的搜索引擎,但要确保查询性能优化。这包括尽可能使用过滤器而不是查询,并使用分页限制返回结果的数量。

9cc617250de386f180c4bbeb5b6d560d.png

  1. 使用过滤器而不是查询:

  • 提高查询速度:过滤器不计算相关性得分。

  • 结果可被缓存:相同过滤条件直接获取结果。

使用分页限制返回结果数量:

  • 降低计算和传输负担:提高查询性能。

  • 注意深度分页可能导致性能问题:考虑使用 search_after 参数。

优化查询性能有助于降低响应时间、提高吞吐量并确保集群在高负载下保持稳定。

1.4 保持Elasticsearch版本更新

Elasticsearch是一个活跃的项目,定期发布新版本以修复错误并提供新功能。保持版本更新至关重要,以利用这些改进并避免已知问题。

26c22566f4d4acc4eb19b56340eff86f.png

1.5 监控集群

Elasticsearch 提供了各种监控工具,如Elasticsearch Head、Kibana monitoring(优先推荐)插件,可用于监控集群的健康和性能。需要密切关注磁盘使用情况、CPU和内存使用情况以及搜索请求的数量。

3c289722388b35c0cc31feb69cef1642.png

3c2f31e67138f1b2ce94f5b911ea6704.png

9a6626c64683b6f493322ff1d4294cd8.png

在通用最佳实践的基础上,我们将深入探讨索引、查询和搜索、扩展、性能和监控等具体领域。

2、写入(索引化)优化建议

2.1 使用批量请求

Elasticsearch的批量API允许在单个API调用中执行多个索引/删除操作。这大大提高了索引速度。如果请求中的一个失败,顶层错误标志将设置为true,并在相关请求下报告错误详细信息。

使用 Elasticsearch 的批量 API 的原因

  1. 提高性能

减少网络开销和连接建立时间,提高索引速度。

  1. 减少资源消耗

降低服务器和客户端资源消耗,提高系统效率和吞吐量。

  1. 错误处理

灵活且可控的错误处理方式,即使部分操作失败,其他操作仍可继续执行。

使用批量 API 可实现高效的数据索引和删除操作,同时提高系统的稳定性和可靠性。

2.2 使用多线程客户端索引数据

单个线程发送批量请求无法充分利用Elasticsearch集群的索引能力。

通过多线程或多进程发送数据,将有助于利用集群的所有资源,降低每个fsync的成本,提高性能。

2.3 增加刷新间隔(index.refresh_interval)

Elasticsearch中默认的刷新间隔为1秒,但如果搜索流量很小,可以增加此值以优化索引速度。

2.4 使用自动生成的ID

在索引具有显式ID的文档时,Elasticsearch需要检查是否已经存在具有相同ID的文档,这是一项代价高昂的操作。

使用自动生成的ID可以跳过此检查,使索引更快。

2.5 index.translog.sync_interval

此设置控制translog何时提交到磁盘,无论写操作如何。默认值为5秒,但不允许使用小于100毫秒的值。

官方文档地址:

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-translog.html

2.6 避免大型文档

大型文档会给网络、内存使用和磁盘带来压力,导致索引速度缓慢,影响邻近搜索和高亮显示。

高亮处理推荐 fvh 高亮方式。

推荐阅读:Elasticsearch大文件检索性能提升20倍实践(干货)

2.7 显式设置映射

Elasticsearch可以动态创建映射,但并不适用于所有场景。显式设置(strict)映射将有助于确保最佳性能。

99035778a5016a0cd9bd8b5ffc1475d8.png

显式设置映射的优势

  1. 准确的字段类型

确保查询和聚合操作正确性。

  1. 优化存储和性能

降低存储空间,提高查询性能。

  1. 避免不必要的映射更新

减少映射更新操作和性能开销。

2.8 避免使用嵌套Nested类型

虽然嵌套类型在某些场景下很有用,但它们也带来了一定的性能影响:

  1. 查询速度较慢

与查询非嵌套文档中的普通字段相比,查询嵌套字段速度较慢。

这是因为嵌套字段的查询需要执行额外的处理步骤,例如过滤器和关联。这可能导致较低的查询性能,特别是在处理大量数据时。

  1. 额外的减速

在检索匹配嵌套字段的文档时,Elasticsearch 需要对嵌套层文档进行关联。这意味着它需要将嵌套文档与其外层文档匹配,以确定哪些文档实际上包含匹配的嵌套字段。这个过程可能导致额外的性能开销,尤其是在查询结果集很大时。

为了避免嵌套类型带来的性能影响,可以考虑使用以下方法:

  • 扁平化数据结构(俗成大宽表):尽可能将嵌套字段转换为扁平化的数据结构,例如使用多个普通字段表示原本的嵌套字段。

  • 使用关键词类型(keyword类型):对于具有固定集合值的字段,可以使用关键词类型进行索引,以提高查询速度。

  • 使用 join 类型(父子关联类型):在某些场景下,可以使用 join 类型替代嵌套类型。

但请注意,join 类型也可能导致性能问题,尤其是在需要频繁修改文档关系时。

3、查询和搜索优化建议

3.1 尽可能使用 filter 而不是 query

  • query 子句用于回答“这个文档与这个子句的匹配程度如何?

  • filter(过滤器)子句用于回答“这个文档是否与这个子句匹配?” Elasticsearch只需要回答“是”或“否”。它不需要为过滤器子句计算相关性得分,而且过滤器结果可以被缓存。

3.2 增加刷新间隔

增加刷新间隔有助于减少段数量,降低搜索的IO成本。

而且,一旦刷新发生并且数据发生变化,缓存就会失效。增加刷新间隔可以使Elasticsearch更有效地利用缓存。

3.3 辩证的看待增加副本数量对检索性能的影响

直接给出企业级测试结论——副本数对检索性能的影响非正相关。也就是说:不是副本越多,检索性能越高。

增加副本数量的优势

  1. 负载均衡

分散查询请求负载,实现负载均衡。

  1. 高可用性

提高集群的可用性和容错能力。

  1. 并行处理

加快查询速度,提高吞吐量。

注意:增加副本数量会消耗额外的存储空间和计算资源。需根据需求和资源限制权衡副本数量。

3.4 仅检索必要字段

如果文档很大,且仅需要几个字段,请使用stored_fields仅检索所需字段,而不是所有字段。

3.5 避免通配符查询

通配符查询可能会很慢且耗资源。最好尽量避免使用它们。

替代方案:Ngram分词、设置 wildcard 数据类型。

Elasticsearch 警惕使用 wildcard 检索!然后呢?

3.6 使用节点查询缓存

过滤器上下文中使用的查询结果将缓存在节点查询缓存中,以便快速查找。

过滤器上下文查询结果缓存的优势

  1. 缓存命中率

过滤器查询具有较高的缓存命中率,常在多个查询中重复使用。

  1. 节省计算资源

缓存结果减少重复计算,节省资源。

  1. 提高查询速度

缓存加速查询,特别是复杂或数据量大的过滤器查询。

  1. 并发查询效果更好

节点查询缓存在高并发场景下发挥作用,提高性能。

注意:需平衡缓存使用与内存消耗。对于频繁变更或低缓存命中率的查询,缓存效果可能有限。

Elasticsearch 缓存深入详解

3.7 使用分片查询缓存

可以通过将“index.requests.cache.enable”设置为true来启用分片查询缓存。

设置参考如下:

PUT /my-index-000001
{
  "settings": {
    "index.requests.cache.enable": false
  }
}

官方文档地址:

https://www.elastic.co/guide/en/elasticsearch/reference/current/shard-request-cache.html

3.8 使用索引模板

索引模板可以帮助自动将设置和映射应用于新索引。

852442adeea6e7fa46f2cc2c078b0281.png

使用索引模板的优势

  1. 一致性

确保新索引具有相同的设置和映射,实现集群一致性。

  1. 简化操作

自动应用预定义的设置和映射,减少手动配置。

  1. 易于扩展

快速创建具有相同配置的新索引,便于集群扩展。

  1. 版本控制和更新

实现模板版本控制,确保新索引使用最新配置。

4、性能优化建议

4.1 活动分片应与CPU成比例

活动分片=主分片+副本分片数之和。

活动分片与 CPU 成比例的原因

  1. 并行处理

更多活动分片提高并行处理能力,加速查询和索引请求。与 CPU 核心数成比例确保充分利用 CPU 资源。

  1. 避免资源竞争

将活动分片与 CPU 核心数成比例,避免多分片竞争同一 CPU 核心,提高性能。

  1. 负载均衡

成比例的活动分片数有助于在多节点间分散请求,避免单节点资源瓶颈。

  1. 性能优化

与 CPU 核心数成比例的分片数根据可用计算资源为分片分配处理能力,优化查询和索引操作。

注意:实际部署需考虑其他因素,如内存、磁盘和网络资源等。

如前所述,为了提高写入密集型用例的性能,应将刷新间隔增加到较大的值(例如,30秒),并增加主分片以将写请求分发到不同节点。对于读取密集型用例,增加副本分片以在副本之间平衡查询/搜索请求会有所帮助。

4.2 如果查询具有日期范围 filter 过滤器,请按日期组织数据。

对于日志或监控场景,按每日、每周或每月组织索引并按指定日期范围获取索引列表可以提高性能。

bad9635cd6a521753d964036258ddf60.png

Elasticsearch只需要查询较小的数据集,而不是整个数据集,而且在数据过期时缩小/删除旧索引会很容易。

负面案例:之前有客户超大规模(100TB)以上的数据没有日期格式字段或者出现字段格式不规范的问题。

4.3 如果查询具有过滤字段且其值可枚举,则将数据分割成多个索引。

如果我们的查询中包含可枚举的过滤字段(例如,地区),则可以通过将数据分割成多个索引来提高查询性能。

例如,如果数据包含来自美国、欧洲和其他地区的记录,并且经常使用“region”过滤查询,那么可以将数据分割成三个索引,每个索引包含一组地区的数据。

这样,当执行带有过滤子句“region”的查询时,Elasticsearch 只需要在包含该地区数据的索引中搜索,从而提高查询性能。

5、扩展建议

5.1 索引状态管理

定义自定义管理策略以自动执行常规任务,并将其应用于索引和索引模式。例如,可以定义一项策略,使索引在30天后进入只读状态,然后在90天后将其删除。

ILM(索引生命周期管理)是 Elasticsearch 的一项功能,可自动化索引的管理和维护,具有以下好处:

  • 简化索引管理:自动化索引的生命周期管理,包括索引的创建、更新、删除和存档,减轻管理员的负担。

  • 提高性能:自动优化索引设置,包括调整分片大小、缩小索引和删除过期数据等,有助于提高查询性能和减少存储空间的使用。

  • 降低成本:自动归档和删除过期数据,降低存储成本,减少管理员的工作量和时间成本。

  • 更好的可扩展性:根据需要自动调整索引设置和存储策略,使索引更好地适应不断增长和变化的数据。

使用 ILM 可以让索引管理变得更简单、更可靠。

  1. 干货 | Elasticsearch 索引生命周期管理 ILM 实战指南

  2. Elasticsearch ILM 索引生命周期管理常见坑及避坑指南

5.2 快照生命周期管理

SLM(快照生命周期管理)是 Elasticsearch 的一项功能,可自动化快照的管理和维护,具有以下好处:

  • 简化快照管理:自动化快照的生命周期管理,包括创建、管理、删除和清理快照,减轻管理员的负担。

  • 提高效率:自动化快照的创建、管理、删除和清理,提高管理效率。

  • 减少存储成本:自动删除无用的快照,降低存储成本。

  • 更好的可扩展性:根据需要自动调整快照设置和存储策略,使快照更好地适应不断增长和变化的数据。

使用 SLM 可以让快照管理变得更简单、更可靠,提高管理效率和降低存储成本。

Elasticsearch 快照生命周期管理 (SLM) 实战指南

5.3 用好监控

为了监视Elasticsearch集群的性能并检测任何潜在问题,应该定期跟踪以下指标:

1e3218e2b02e82c66287c577d2f0318b.png

  • 集群健康状况节点和分片:监控集群中节点的数量以及分片及其分布。

  • 搜索性能:请求延迟和速率 - 跟踪搜索请求的延迟以及每秒搜索请求的数量。

  • 索引性能:刷新时间和合并时间 - 监控刷新索引所需的时间以及合并段所需的时间。

  • 节点利用率:线程池 - 监控每个节点上线程池的使用情况,例如索引池。

6、小结

遵循这些最佳实践,可以确保Elasticsearch部署性能高、可靠且可扩展。

请记住,Elasticsearch是一个功能强大的搜索和分析引擎,可以快速并近乎实时地处理大量数据,但是要充分利用它,需要计划、优化和监控部署。

以上建议仅供参考,实操环节以 Elasticsearch 官方文档和自己集群的性能测试结论为准。没有普适的优化建议,只有适合自己的优化才是最好的优化。

推荐阅读

  1. 全网首发!从 0 到 1 Elasticsearch 8.X 通关视频

  2. 重磅 | 死磕 Elasticsearch 8.X 方法论认知清单

  3. 如何系统的学习 Elasticsearch ?

  4. 2023,做点事

  5. JMeter 如何实现 Elasticsearch 8.X 性能测试?

  6. Elasticsearch 检索性能优化实战指南

  7. 让Elasticsearch飞起来!——性能优化实践干货

  8. Elasticsearch性能优化实战指南

  9. Elasticsearch 聚合性能优化六大猛招

  10. esrally 如何进行简单的自定义性能测试?

89a2e81ba6c2ab724ab028d679d66814.jpeg

更短时间更快习得更多干货!

和全球 近2000+ Elastic 爱好者一起精进!

75ff13042afdcdcb552db2a2a579c758.gif

比同事抢先一步学习进阶干货!

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

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

相关文章

【计算机图形学】课堂习题汇总

在直线的光栅化算法中,如果不考虑最大位移方向则可能得到怎样的直线? A:斜率为1的线 B:总是垂直的 C:离散的点,无法构成直线 D:总是水平的 在直线的改进的Bresenham算法中,每当误…

Qt音视频开发42-网络推流(视频推流/本地摄像头推流/桌面推流/网络摄像头转发推流等)

一、前言 上次实现的文件推流,尽管优点很多,但是只能对现在存在的生成好的音视频文件推流,而现在更多的场景是需要将实时的视频流重新推流分发,用户在很多设备比如手机/平板/网页/电脑/服务器上观看,这样就可以很方便…

IP-GUARD如何通过流量控制策略限制客户端下载文件?

如何通过流量控制策略限制客户端下载文件? 可通过流量控制策略限制接收流量上限速度,实现控制客户端下载文件效果。流量控制支持网络地址和端口范围限制。 网络流量统计能否基于用户进行统计? 目前最新的客户端版本已经支持控制应用程序的网络流量,在应用层实现了控制…

专利进阶(二):专利撰写常用技术及算法汇总(持续更新中)

文章目录 一、前言二、常用技术及算法2.1 区跨链技术2.2 聚类算法2.3 边缘算法2.4 蚁群算法2.4.1 路径构建2.4.2 信息素更新 2.5 哈希算法2.5.1 常见算法 2.6 数字摘要2.72.82.92.10 三、拓展阅读 一、前言 专利撰写过程中使用已有技术或算法解决新问题非常常见,本…

基于SpringBoot的冬奥会科普平台

摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理平台应运而生,各行各业相继进入信息管理时代&…

【五一创作】Scratch资料

Scratch软件是免费的、免费的、免费的。任何需要花钱才能下载Scratch软件的全是骗子。 1、什么是Scratch Scratch是麻省理工学院的“终身幼儿园团队”开发的一种图形化编程工具。是面向青少年的一款模块化,积木化、可视化的编程语言。 什么是模块化、积木化&…

leetcode每日一题【7】

第一题:67. 二进制求和 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。示例 1:输入:a "11", b "1" 输出:"100" 示例 2:输入:a "1010", b …

MyBatis:生命周期、作用域、结果集映射 ResultMap、日志、分页、使用注解开发、Lombok

文章目录 MyBatis:Day 02一、生命周期和作用域二、结果集映射:ResultMap三、日志工厂1. 标准日志:STDOUT_LOGGING2. LOG4J 四、分页五、使用注解开发六、Lombok注意: MyBatis:Day 02 一、生命周期和作用域 理解不同作…

Syncfusion Essential Studio Enterprise 2023.1 Crack

Syncfusion 的所有用户界面、报告、商业智能组件和库都在一个综合套件中。 Syncfusion Essential Studio 企业版包括 1,700 多个组件和框架,适用于 WinForms、WPF、ASP.NET(Web Forms、MVC、Core)、UWP、WinUI、.NET MAUI、Xamarin、Flutter、…

【Linux从入门到精通】Linux中的权限管理(实例+详解)

本篇文章对Linux下的普通用户和超级用户进行了对比详解。同时有添加和删除普通用户的讲解。也详细的解释了普通文件的权限、拥有者、所属组设置方法,和对目录的权限设置方法。根据需求引出粘滞位,对粘滞位进行详细的解释。解释每个要点是都带有实例&…

分享一个可交互的卡片

五一放假了&#xff0c;寻思着来一个应景的玩意&#xff0c;所以它诞生了。 先上效果图&#xff1a; 再上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><…

给失业的互联网人一个思路:别再苦苦找工作了,要去找门槛低、现金流好、天花板低、资本看不上的创业项目,一年也能几百万!...

失业大潮中的互联网人该何去何从&#xff1f;这大概是许多人在难捱的深夜反复思考的问题。 一位失业很久的网友就在痛苦思索中悟出了适合自己的道路&#xff0c;下面分享给大家&#xff0c;篇幅太长&#xff0c;小编给大家划一下重点。 先说结论&#xff1a;失业的互联网人别再…

MySql数据库的初步安装与数据表结构数据管理

1.数据库的相关了解 1.1 数据库的概念 数据库&#xff08;database&#xff09;是用来组织、存储和管理数据的仓库 数据库管理系统&#xff08;DBMS&#xff09;&#xff1a;是实现对数据有效组织&#xff0c;管理和存取的系统软件。 数据的建立和维护功能&#xff0c;数据定…

【C语言】struct结构体

文章目录 一. 结构体简述二. 结构体的声明和定义1、简单地声明一个结构体和定义结构体变量2、声明结构体的同时也定义结构体变量3、匿名结构体4、配合typedef&#xff0c;声明结构体的同时为结构体取别名5、在声明匿名结构体时&#xff0c;使用typedef给这个匿名结构体取别名 三…

用 AudioGPT 输入自然语言,可以让 ChatGPT 唱歌了?

夕小瑶科技说 原创作者 | 智商掉了一地 借助 ChatGPT 强大的理解与生成能力&#xff0c;结合基础语音模型&#xff0c;集成模型 AudioGPT 诞生了&#xff01; 最近基于 ChatGPT 的二创如雨后春笋一样冒出&#xff0c;上周我们一起看了黑客松优秀作品大赏&#xff0c;这周又有新…

HCIP-7.2VLAN间通信单臂、多臂、三层交换方式学习

VLAN间通信单臂、多臂、三层交换方式学习 1、单臂路由2、多臂路由3、三层交换机的SVI接口实现VLAN间通讯3.1、VLANIF虚拟接口3.2、VLAN间路由3.2.1、单台三层路由VLAN间通信&#xff0c;在一台三层交换机内部VLAN之间直连。3.2.2、两台三层交换机的之间的VLAN通信。3.2.3、将物…

Ae:画笔面板

Ae菜单&#xff1a;窗口/画笔 Brushes 快捷键&#xff1a;Ctrl 9 画笔 Brushes面板提供了画笔预设及画笔设置&#xff08;包括画笔动态&#xff09;等的参数设置。 画笔预设 Brush Presets 画笔预设窗格中提供了自带的画笔预设&#xff0c;主要有尖角 Hard Round、柔角 Soft R…

【云原生】Epinio--Kubernetes 的应用程序开发引擎

Kubernetes 已成为容器编排的事实标准&#xff0c;改变了我们的开发流程。十年前&#xff0c;我们只需要将代码打包成 war/jar 包&#xff0c;然后启动应用即可。然而&#xff0c;现在面向 Kubernetes 的开发&#xff0c;交付的产物有可能是 Helm Chart、Workload Yaml、Docker…

SOFA Weekly|SOFAArk 社区会议预告、Layotto 社区会议回顾、社区本周贡献

SOFA WEEKLY | 每周精选 筛选每周精华问答&#xff0c;同步开源进展 欢迎留言互动&#xff5e; SOFAStack&#xff08;Scalable Open Financial Architecture Stack&#xff09;是蚂蚁集团自主研发的金融级云原生架构&#xff0c;包含了构建金融级云原生架构所需的各个组件&am…

【SPSS】相关分析和偏相关分析详细操作过程(附案例实战)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…