0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一次对API响应时间的优化探索

我快闭嘴 来源:AI前线 作者:Ankit Joinwal 2022-09-20 11:50 次阅读

一次对 API 响应时间的优化探索。

在这普通的一天,我们用着普通的 API,突然发现响应速度过慢的警报意外亮起。

结果显示,我们的 API 需要约 70 秒的时间才能对常规流量下的客户端做出响应。开什么玩笑……

从问题入手

先向大家汇报一下我们的这个慢速 API 是做什么,又是怎么做的。

在这款应用程序中,我们把书籍及其作者的目录存储在 MySQL 数据库中。其中共包含约 6800 万本书,每本书对应一家出版社。

下面来看书籍和作者的表结构。

CREATE TABLE `book` (
  `id` int NOT NULL AUTO_INCREMENT,
  `book_uuid_bin` binary(16) NOT NULL,
  `publishing_house_uuid_bin` binary(16) NOT NULL,
  `display_name` varchar(750)  NOT NULL,
  `normalized_name` varchar(750) NOT NULL,
  `description` varchar(1000) DEFAULT NULL,
  `level` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_book_uuid_bin` (`book_uuid_bin`),
  KEY `book_description_idx` (`description`(768)),
  KEY `book_display_name_idx` (`display_name`),
  KEY `book_normalized_name_idx` (`normalized_name`),
  KEY `publishing_house_uuid_bin_idx` (`publishing_house_uuid_bin`),
  KEY `book_uuid_bin_idx` (`book_uuid_bin`)
)
CREATE TABLE `publishing_house` (
  `id` int NOT NULL AUTO_INCREMENT,
  `publishing_house_uuid_bin` binary(16) DEFAULT NULL,
  `display_name` varchar(750) NOT NULL,
  `normalized_name` varchar(750) NOT NULL,
  `alias_uuid_bin` binary(16) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_publishing_house_uuid_bin` (`author_uuid_bin`),
  KEY `publishing_house_normalized_name_idx` (`normalized_name`),
  KEY `publishing_house_display_name_idx` (`display_name`)
)

再说回 API,其用例是在 UI 上提供自动补全功能,方便用户更好地查找特定出版社出版的书籍,同时保证用户的查询字符串同书籍名称或描述的前缀相匹配。

API 中使用的 MySQL 查询如下所示:

select book_uuid_bin,
       display_name,
       normalized_name,
       description,      
       author_uuid_bin 
from book
where
     ((lower(display_name) like lower("%Software E%") or  lower(description) like lower("%Software E%")) and publishing_house_uuid_bin = UUID_TO_BIN("d2230981-e570-5ba4-9a3a-16028c51d54f"))order by display_name asc limit 100;

即使查询在单表上就能完成,不需要连接作者表,这条 SQL 查询也需要 7 秒左右才能执行完成。

我们在 where 子句所使用的列上建立了索引。但这一实现还是存在问题,包括:

1、display_name 和 description 等列属于 VARCHAR 类型。

2、会在 VARCHAR 类型列上使用带有 OR 子句的 LIKE 运算符。

3、会使用 ORDER BY。

4、 WHERE 子句中使用的所有列,都缺少复合索引。

5、表中共包含 5800 万条记录。

我们曾尝试在查询中使用的各列上创建一个复合索引,但最终发现无济于事。因为对于 RDBMS 数据库内的大表来说,在 VARCHAR 列上搜索文本的效率就不可能太高。

我们知道 Elasticsearch 提供全文本搜索功能,所以想在自己的用例中试试看。我们一直在用 AWS 的云服务,因此选择了相应的 AWS OpenSearch 服务。

Amazon OpenSearch 托管服务能帮助用户轻松在 AWS 云中部署、操作和扩展 OpenSearch 集群。Amazon OpenSearch 是 Amazon Elasticsearch 的继任方案。

开始行动

我们通过脚本将表数据从 MySQL 加载到了 AWS OpenSearch 集群当中。整个数据迁移过程大概用了几个小时。

我们为索引保留了 5 个分片和 1 个副本因子。

我们还为用例编写了一条等效的 OpenSearch 查询,具体如下所示:

API — POST /books-catalog/_search

{
  "query": {
    "bool": {
      "must": [
        {
          "match_phrase": {
            "publisherUuid": "1f754fc0-610c-5b29-b22b-fa8140afb7be"
          }
        },
        {
          "bool": {
            "should": [
              {
                "match_phrase": {
                  "displayName": "Software E"
                }
              },
              {
                "match_phrase": {
                  "description": "Software E"
                }
              }
            ]
          }
        }
      ]
    }
  },
  "size": 100,
  "sort": [
    {
      "displayName.keyword": {
        "unmapped_type": "keyword",
        "order": "asc"
      }
    }
  ]
}
结果

我们的 API 响应速度直接缩短至 70 毫秒以内。

API 响应速度提高了 1000 倍!

关于 OpenSearch 全文搜索的一些细节 :

在 ElasticSearch 中对文档进行索引(创建)时,AWS OpenSearch 会对字符串类型的字段使用文本分析器。

文本分析器会将字符串字段拆分为多个 token,为各 token 构建内部索引,然后根据查询中提供的 token 进行匹配。

权衡取舍

为了避免重写整个服务,同时尽快在 MySQL 切换至 AWS OpenSearch 后恢复正常生产,我们决定只在这个特定用例中使用 OpenSearch。

而且速度提升 1000 倍的代价,就是多了一套需要在 OpenSearch 当中维护的数据副本。但由于我们的数据大多是静态的,持续更新量非常有限,所以维护强度和成本都很低。

可以看到,选择正确的数据库引擎往往会给业务用例带来翻天覆地的提升。

希望我们的经历能给大家带来一点启发,祝编程愉快!

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • API
    API
    +关注

    关注

    2

    文章

    1382

    浏览量

    60989
  • MySQL
    +关注

    关注

    1

    文章

    775

    浏览量

    26002
  • 响应时间
    +关注

    关注

    0

    文章

    11

    浏览量

    6863

原文标题:将 API 从 MySQL 迁移到 AWS OpenSearch 后,我们将响应时间提高了 1000 倍

文章出处:【微信号:AI前线,微信公众号:AI前线】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    RL串联电路的响应时间怎么计算

    各位前辈:方波脉冲控制串联RL负载时,响应时间即上升下降时间怎么计算
    发表于 01-20 09:42

    产品响应时间

    大家好,我正在做个光开关的控制,老师要求我对产品的响应时间个仿真跟优化,基本工作电路是MCU控制升压芯片的电压,要求对从MCU发出升压命令到升压稳定的这
    发表于 06-16 22:20

    请问AD9144输出响应时间

    系统需求是个反馈测试系统,需要根据当前ADC采样后计算结果分析后,决定下一次DAc输出的波形。现在的问题是,系统对从ADC输入信号到DAC输入信号,给的响应时间只有100ns,且是关键指标不能放松
    发表于 08-03 06:55

    SAR ADC响应时间实现迅速响应、快速控制的方法

    如何优化系统响应时间 (tRESP) 上来。其中个比较有效的方法是在设计中的不同“非实时”块上,即ADC,主机控制器和DAC,安排系统响应时间。ADC的
    发表于 09-12 11:46

    应用响应时间的延迟问题怎么解决

    对于数据中心架构师而言,这似乎是个简单的问题。对于从电子商务平台背后的数据库、搜索引擎中的大数据工具、突然流行的数据分析到科学代码的各种应用而言,应用响应时间的主要限制是存储延迟。与此同时
    发表于 07-30 06:09

    什么是响应时间

    什么是响应时间      响应时间是指液晶显示器各像素点对输入信号反应的速度,即像素由暗转亮或由亮转暗所需要的时间(其原理是在液晶分子内
    发表于 05-24 21:53 4989次阅读

    液晶显示器的黑白响应时间

    液晶显示器的黑白响应时间 所谓黑白响应时间是液晶显示器各像素点对输入信号反应的速度,即像素由暗转亮或由亮转暗所需要的时间(其原理是
    发表于 12-26 16:48 1293次阅读

    什么是液晶电视的响应时间

    什么是液晶电视的响应时间   响应时间是液晶电视各像素点对输入信号反应的速度,即像素由暗转亮或由亮转暗所需要的时间(其原理是在液晶分子内
    发表于 03-27 13:29 3971次阅读

    光敏电阻响应时间研究

    用半定量方法研究了光敏电阻的响应时间与照射光的照度和波长的关系,并给出了光敏电阻的上升时间和下降时间的测量方法.该实验可作为本科生的探索性实验。有助于培养学生的综
    发表于 09-20 17:00 85次下载
    光敏电阻<b class='flag-5'>响应时间</b>研究

    测量光耦响应时间的简单电路

    测量光耦响应时间的简单电路
    发表于 06-04 11:53 1856次阅读
    测量光耦<b class='flag-5'>响应时间</b>的简单电路

    什么是单片机的中断响应时间

    中断响应时间:从外部中断请求有效(外部中断请求标志置1)到转向中断入口地址所需要的响应时间。每个机器周期的S5P2时刻,INTx引脚的电平被锁存到内部寄存器中,待下一个周期查询。
    发表于 12-19 15:57 8888次阅读
    什么是单片机的中断<b class='flag-5'>响应时间</b>

    面板响应时间有什么影响

    响应时间是一个计算机,显示器成像等多个领域的概念,在网络上,指从空载到负载发生一个步进值的变化时,传感器的响应时间
    的头像 发表于 01-14 14:56 3611次阅读

    基于异构多核的多类型DAG响应时间分析

    基于异构多核的多类型DAG响应时间分析
    发表于 06-15 14:08 22次下载

    PLC的I/O响应时间

    响应时间是指 plc 接收到一个输入信号以后,到输出控制信号所需的时间。当 CPU 接收到对应于输入刷新周期的输入信号时,用于响应时间取决于扫描周期。
    的头像 发表于 10-05 09:23 1960次阅读
    PLC的I/O<b class='flag-5'>响应时间</b>

    进程响应时间是指什么

    进程响应时间是指从发出请求到收到响应时间间隔,是衡量系统性能和用户体验的重要指标之一。在计算机系统中,进程是指一个正在运行的程序实例。当用户发出请求,系统会创建一个新的进程来处理该请求。进程
    的头像 发表于 11-17 11:31 428次阅读