当前位置: 首页 > article >正文

如何利用 Go 语言开发高性能服务

        当我们搭建了一个完整的 Go 项目后,这个项目的性能如何呢?能否应对高并发流量(比如秒杀活动)呢?如果不能,我们该如何优化系统性能呢?性能优化的前提是确定服务瓶颈。

1. 分库分表

        数据库通常是 Web 服务的性能瓶颈,为什么呢?因为一般情况下,单个数据库实例的QPS (Queries-Per-Second,每秒查询次数)也就几千,这只能满足小型系统的需求,而某些中大型系统有可能需要承接数万甚至数十万的 QPS,单个数据库实例是绝对扛不住的。那么如何优化数据库性能呢?一方面,可以通过提升机器性能来优化数据库配置,同时通过优化表结构、查询语句等方式尽可能地提升单个数据库实例的 QPS; 另一方面,也可以通过分库分表方式提升数据库的 QPS。

1.1 分库分表基本原理

        分库的含义就是将一个数据库拆分成多个数据库,并部署到不同的机器。例如,我们可以将商城项目的用户表、商品表、订单表等分别拆分到3个数据库实例。这样一来,原本一个数据库实例的压力就分散到了 3 个数据库实例(用户库、商品库、订单库)。总体而言,数据库的性能得到了提升。

        通过这种方式优化之后就能万无一失了吗?举一个例子,假设商品模块的访问 QPS 在 1 万以上,而单个数据库实例的 QPS 在几千。也就是说,拆分数据库之后,商品库的性能依然无法满足条件。还有什么办法可以优化数据库性能呢?这时候我们通常会选择主从架构(读写分离)方案。首先,从数据库实例会实时同步主数据库实例的数据;其次,读请求可以由从数据库实例处理,写请求由数据库实例处理。通过这种方式,数据库性能可以得到成倍的提升。

        使用读写分离方案时,一定要注意:主数据库实例的数据同步到从数据库实例是有延迟的。也就是说,当执行了一条写请求(INSERT、UPDATE、DELETE)时,如果立即执行读请求(QUERY)查询对应的数据,结果可能不符合预期。因为这时候主数据库的数据修改可能还没有同步到从数据库。另外,使用读写分离方案时,项目中获取数据库实例的代码逻辑需要根据操作类型进行相应的调整,改造成本还是不小的。

        那还有什么其他方案吗?我们可以在业务代码和数据库实例之间加一层代理服务。代理服务将自己伪装成数据库实例,接收业务请求并转发给后端真正的数据库实例。这样就只需要在代理服务上实现读写分离逻辑即可。

        需要说明的是,我们不可能通过增加从数据库来无限制地提升数据库性能,毕竟主、从数据库实例之间的数据同步也是有开销的。另外,虽然可以部署多个从数据库实例,但是主数据库实例只有一个,也就是说通过这种方式无法提升写请求的 QPS。

        还有什么方案能优化数据库性能吗?分表。分表就是将一张数据表拆分为多张数据表,这些数据表可以在一个数据库实例中,也可以在多个数据库实例中。众所周知,当一张数据表的数据量过大时,即使命中了索引查询也会变慢(如果没有命中索引,查询将会非常慢),这是因为 MySQL 数据库(以 InnoDB引擎为例)的索引基于 B+ 树实现,查询耗时将会随之增加。所以,分表可以在一定程度上提升数据库性能,即使这些拆分后的数据表都在同一个数据库实例中。当然,如果我们将这些拆分后的数据表分布在多个数据库实例中,数据库性能还可以得到大幅度提升。

分表有两种实现方式:

1)垂直分表:这种方式适用于列非常多的数据表,这时候我们可以将一些不常用的、数据量较大的列拆分到其他数据表。

2)水平分表:这种方式适用于数据量非常大(行记录非常多)的数据表。这是以订单表为例,介绍如何实现水平分表。水平分表的核心在于,以什么维度拆分数据表,比如我们可以按照时间拆分,可以按照订单 ID 拆分,也可以按照用户 ID 拆分。

        那到底应该按照哪种方式水平分表呢?这取决于查询需求。设想一下,如果将订单表按照订单 ID 拆分为 64 张表,那么


http://www.kler.cn/news/285002.html

相关文章:

  • Fetch API 的基本使用
  • 探索JSON Schema的世界
  • 小程序使用iconfont字体图标
  • 【Unity-UGUI组件拓展】| ContentSizeFitter 组件拓展,支持设置最大宽高值
  • 网页html版——在线查字典的一个web服务器
  • Android 移除最近任务列表展示
  • CSND文章质量分批量查询
  • 类图的关联关系
  • Python基础 3 - 函数及数据容器
  • JAVA毕业设计167—基于Java+Springboot+vue3+小程序的物业管理系统小程序(源代码+数据库+万字论文+文献综述)
  • Llamaindex RAG实践
  • 并发服务器
  • 代码随想录算法训练营第六十天 | 图论part10
  • SkyWalking部署(监控系统)
  • jquery下载的例子如何应用到vue中
  • 【秋招笔试】8.30饿了么秋招(算法岗)-三语言题解
  • MongoDB 中国用户大会8月31日 (MongoDB 8.0 发布)
  • 医院建筑的电气设计——保障医疗质量与安全的坚固基石
  • 深度学习100问20:什么是RNN
  • GPT带我学-设计模式-责任链模式
  • 力扣面试150 插入区间 模拟
  • 【经典面试题】Kafka为什么这么快?
  • Qt: QGraphicsView二维图形绘图框架
  • sql 4,创建表类型
  • HTML <template> 标签的基本技巧
  • flutter 开发中常用的 Widget
  • Metasploit漏洞利用系列(十):MSF渗透测试 - 震网三代(远程快捷方式漏洞)实战
  • Elasticsearch中别名的作用
  • .NET WPF 抖动动画
  • python 天气与股票的关系--第一部分,爬取数据