1万字长文高速你千万级并发架构下如何提高数据库存储性能

  • 第一部分是TCP三次握手建立连接的数据包第一个数据包是客户端向服务区段发送一个SYN包第二个数据包是服务端返回给客户端的ACK包以及一个SYN包第三个数据包是客户端返回给服务端的ACK包

  • 第二个部分是Mysql服务端校验客户端密码的过程

从开始建立连接的时间130812到最终完成连接288721, 总共耗时157909,接近158ms时间,这个时间看起来很小,而且在请求量较小的情况下,对系统的影响不是很大。但是请求量上来之后,这个请求耗时的影响就非常大了。

而对于这个问题的解决办法大家都已经知道,就是利用池化技术,预先建立好数据库连接,当应用需要使用连接时,直接从预先建立好的连接中来获取进行调用,如图2-2所示。

1万字长文高速你千万级并发架构下如何提高数据库存储性能

图2-2

数据库连接池的工作原理和线程池类似,数据库连接池有两个最重要的配置: 最小连接数和最大连接数, 它们控制着从连接池中获取连接的流程:

  • 如果当前连接数小于最小连接数,则创建新的连接处理数据库请求;

  • 如果连接池中有空闲连接则复用空闲连接;

  • 如果空闲池中没有连接并且当前连接数小于最大连接数,则创建新的连接处理请求;

  • 如果当前连接数已经大于等于最大连接数,则按照配置中设定的时间(maxWait)等待旧的连接可用;

  • 如果等待超过了这个设定时间则向用户抛出错误。

总的来说,连接池核心思想是空间换时间,期望使用预先创建好的对象来减少频繁创建对象的性能开销,同时还可以对对象进行统一的管理,降低了对象的使用的成本。

数据库本身的性能优化

==========

数据库本身的性能优化也很重要,常见的优化手段

  • 创建并正确使用索引,尽量只通过索引访问数据

  • 优化SQL执行计划,SQL执行计划是关系型数据库最核心的技术之一,它表示SQL执行时的数据访问算法,优化执行计划也就能够提升sql查询的性能

  • 每次数据交互时,尽可能返回更少的数据,因为更大的数据意味着会增大网络通信延迟。常见的方式是通过分页来查询数据、只返回当前场景需要的字段

  • 减少和数据库的交互次数,比如批量提交、批量查询

数据库读写操作的性能问题

============

如果老板说公司准备在下个月搞一场运营活动,用户数量会快速增加,导致对数据库的读压力增加,假设在4 核 8G 的机器上运 MySQL 5.7 时,大概可以支撑 500 的 TPS 和 10000 的 QPS,而实际的QPS可能是10W,那怎么解决呢?

首先分析一下这个问题,在绝大部分面向用户的系统中,都是读多写少的模型,比如电商,大部分的时候是在搜索和浏览,比如抖音,大部分是在加载短视频,所以我们需要考虑的问题是,数据库如何扛住查询请求。一般的解决方法是读写分离,

所谓读写分离,就是把同一个数据库分离成两份,一份专门用来做事务操作,另一份专门用来做读操作,如图2-3所示。

1万字长文高速你千万级并发架构下如何提高数据库存储性能

图2-3

做了主从复制之后,我们就可以在写入时只写主库,在读数据时只读从库,这样即使写请求会锁表或者锁记录,也不会影响到读请求的执行。同时呢,在读流量比较大的情况下,我们可以部署多个从库共同承担读流量,这就是所说的 一主多从 部署方式,在你的垂直电商项目中就可以通过这种方式来抵御较高的并发读流量。另外,从库也可以当成一个备库来使用,以避免主库故障导致数据丢失。

那么你可能会说,是不是我无限制地增加从库的数量就可以抵抗大量的并发呢? 实际上并不是的。因为随着从库数量增加,从库连接上来的 IO 线程比较多,主库也需要创建同样多的 log dump 线程来处理复制的请求,对于主库资源消耗比较高,同时受限于主库的网络带宽,所以在实际使用中,一般一个主库最多挂 3~5 个从库

当然,主从复制也有一些缺陷, 除了带来了部署上的复杂度,还有就是会带来一定的主从同步的延迟,这种延迟有时候会对业务产生一定的影响

数据量增加带来的性能问题

============

随着业务的增长,数据库中的数据量也会随着增加,由于最早开发时主要是为了赶进度,数据都是单表存储,因此单表数据量增加之后,导致数据库的查询和写入都造成非常大的性能开销,具体体现在。

  • 单表数据量过大,千万级别到上亿级别,这时即使你使用了索引,索引占用的空间也随着数据量的增长而增大,数据库就无法缓存全量的索引信息,那么就需要从磁盘上读取索引数据,就会影响到查询的性能。

  • 数据量的增加也占据了磁盘的空间,数据库在备份和恢复的时间变长

  • 不同模块的数据,比如用户数据和用户关系数据,全都存储在一个主库中,一旦主库发生故障,所有的模块儿都会受到影响

  • 在 4 核 8G 的云服务器上对 MySQL5.7 做 Benchmark,大概可以支撑 500TPS 和 10000QPS,你可以看到数据库对于写入性能要弱于数据查询的能力,那么随着系统写入请求量的增长,对于写请求的耗时也会增加(更新数据操作需要同步更新索引,数据量较大的情况下更新索引耗时较长)

在这类场景中,解决方案就是对数据进行分片,也就是分库分表的机制,如图2-4所示。数据拆分的核心降低单表和单库的数据IO压力,从而提升对数据库相关操作的性能。

1万字长文高速你千万级并发架构下如何提高数据库存储性能

图2-4

不同存储设备带来的性能提升

=============

前面我们了解了对于传统关系型数据库的一些优化思路,整体来说,通过优化之后能够提升程序访问数据库的计算性能。但是还是有一些情况,即便是优化之后,使用传统关系型数据库无法解决的,比如。

  • 当数据量达到TB级别时,传统关系型数据库基本做了分库分表,单表数据量也是非常大的。

  • 对于一些不适合用关系型数据库存储的数据,传统数据库无法做到,所以数据库本身的特性限制了多样性数据的管理。

所以nosql出现了,大家对nosql这个概念已经不陌生了,它是指不同于传统关系型数据库的其他数据库系统的一个统称,它不使用SQL作为查询语言,并且相对于传统关系型数据库来说,

它提供了更高的性能以及横向扩展能力,非常适合互联网项目中高并发且数据量较大的场景中,如图25所示,表示目前比较主流的不同类型的nosql数据库。

1万字长文高速你千万级并发架构下如何提高数据库存储性能

图2-5 不同的NoSql数据库

这个网站上记录了所有的Nosql框架

NoSQL Database

Key-Value数据库

============

key-value数据库,典型的代表就是Redis、Memcached,也是目前业内非常主流的Nosq数据库。

之所以在IO性能方面比传统关系型数据库高,有两个点

  • 数据基于内存,读写效率高

  • KV型数据,时间复杂度为O(1),查询速度快

KV型NoSql最大的优点就是高性能,利用Redis自带的BenchMark做基准测试,TPS可达达到接近10W的级别,性能非常强劲。同样的Redis也有所有KV型NoSql都有的比较明显的缺点:

  • 查询方式单一,只有KV的方式,不支持条件查询,多条件查询唯一的做法就是数据冗余,但这会极大的浪费存储空间

  • 内存是有限的,无法支持海量数据存储

  • 同样的,由于KV型NoSql的存储是基于内存的,会有丢失数据的风险

基于Key-Value数据库的特性,这类数据库比较适用于缓存的场景。

  • 读多写少

  • 读取能力强

  • 可以接受数据丢失

这类存储相比于传统的数据库的优势是极高的读写性能,一般对性能有比较高的要求的场景会使用,主要使用场景。

  • 用来做分布式缓存,提升程序处理效率。

  • 用来做会话数据存储

  • 其他功能性特性,比如消息通信、分布式锁、布隆过滤器

  • 微博的feed流,早期就是用了redis实现。(持续更新并呈现给用户内容的信息流。每个人的朋友圈,微博关注页等等都是一个 Feed 流)

列式数据库

=====

我们最早学习数据库,都是基于以二维表形式存储,每一行代表一条完整的数据。大部分传统的关系型数据库中,都是以行来存储数据。不过最近几年,列式存储也逐步被广泛运用在大数据框架中。

行存储和列存储,是数据库底层数据组织的形式的区别,如图2-6所示,数据库表中所有列一次排成一行,以行位单位存储,再配合B+树或者SS-Table作为索引,就能快速通过主键找到相应的行数据。

1万字长文高速你千万级并发架构下如何提高数据库存储性能

图2-6

在实际应用中,大部分的操作都是以实体(Entity)为单位,也就是大部分CRUD操作都是针对一整行记录,如果需要保存一行数据,只需要在原来的数据后追加一行数据即可,所以数据的写入非常快。

但是对于查询来说,一个典型的查询操作需要遍历整个表,分组、排序、聚合等,对于行存储来说,这样的操作的优势就不存在了,更惨的是,分析型SQL可能不需要用到所有的列,仅仅只需要对某些列进行运算即可,但是那一行中和本次操作无关的列也必须要参与到数据扫描中。

比如,如图2-7所示,现在我想统计所有文章的总的点赞数量,作为行存储的系统,数据库会怎么操作呢?

  • 首先需要把所有行的数据加载到内存

  • 然后对like_num列做sum操作

1万字长文高速你千万级并发架构下如何提高数据库存储性能

图2-7

行式存储对于OLAP场景而言,优势就不存在了,所以就引入了列式存储。

OLTP(on-line transaction processing)翻译为联机事务处理, OLAP(On-Line Analytical Processing)翻译为联机分析处理,从字面上来看OLTP是做事务处理,OLAP是做分析处理。从对数据库操作来看,OLTP主要是对数据的增删改,OLAP是对数据的查询

如图2-8所示,列式存储是将每一列数据组织在一起,它方便对于列的操作,比如前面说的统计like_num之和,按列存储之后只需要一次磁盘操作就可以完成三个数据的汇总,所以非常适合OLAP的场景。

  • 当查询语句只涉及部分列时,只需要扫描相关列

  • 每一列数据都是相同类型,彼此间的关联性更大,对列数据压缩的效率较高。

但是对于OLTP来说不是很友好,因为一行数据的写入需要修改多个列。

1万字长文高速你千万级并发架构下如何提高数据库存储性能

图2-8

列式存储在大数据分析中使用非常多,比如推荐画像(蚂蚁金服的风控)、是空数据(滴滴打车的归集数据)、消息/订单(电信领域、银行领域)不少订单查询底层的存储。 Feeds流(朋友圈类似的应用)等等。

1万字长文高速你千万级并发架构下如何提高数据库存储性能

图2-9

文档型数据库

======

传统的数据库,所有信息会被分割成离散的数据字段,保存在关系型数据库中,甚至对于一些复杂的场景,还会分散在不同的表结构中。

举个例子,在一个技术论坛中,假设对于用户、文章、文章评论表的关系图如图2-10所示。

1万字长文高速你千万级并发架构下如何提高数据库存储性能

图2-10

那用户点一篇文章,里面要显示该文章的创建者、文章详情、文章的评论,那么服务端要做什么呢?

  • 查找文章详情

  • 根据文章中的uid查找用户信息

  • 查询该文章的所有评论列表

  • 查询每个评论的创建者名字

这个过程要么就是多次数据库查询,要么就是使用一个复杂关联查询来检索,不管怎么做,都不是很方便。而文档数据库就可以解决这样的问题。

文档数据库是以文档单位,具体的文档形式有很多种,比如(XML、YAML、JSON、BSON)等,文档中存储具体的字段和值,应用可以使用这些字段进行查询和数据筛选。

一般情况下,文档中包含了实体中的全部数据,比如图2-10的结构,我们可以直接把一篇文章的基本要素信息构建成一个完整的文档保存到文档数据库中,应用程序只需要发起一次请求就可以获取所有数据。b

Article:{

Creator:{

uid: ‘’,

username: ‘’

},

Topic: {

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

最后如何让自己一步步成为技术专家

说句实话,如果一个打工人不想提升自己,那便没有工作的意义,毕竟大家也没有到养老的年龄。

当你的技术在一步步贴近阿里p7水平的时候,毫无疑问你的薪资肯定会涨,同时你能学到更多更深的技术,交结到更厉害的大牛。

推荐一份Java架构之路必备的学习笔记,内容相当全面!!!

成年人的世界没有容易二字,前段时间刷抖音看到一个程序员连着加班两星期到半夜2点的视频。在这个行业若想要拿高薪除了提高硬实力别无他法。

你知道吗?现在有的应届生实习薪资都已经赶超开发5年的程序员了,实习薪资26K,30K,你没有紧迫感吗?做了这么多年还不如一个应届生,真的非常尴尬!

进了这个行业就不要把没时间学习当借口,这个行业就是要不断学习,不然就只能被裁员。所以,抓紧时间投资自己,多学点技术,眼前困难,往后轻松!

【关注】+【转发】+【点赞】支持我!创作不易!

工人不想提升自己,那便没有工作的意义,毕竟大家也没有到养老的年龄。

当你的技术在一步步贴近阿里p7水平的时候,毫无疑问你的薪资肯定会涨,同时你能学到更多更深的技术,交结到更厉害的大牛。

推荐一份Java架构之路必备的学习笔记,内容相当全面!!!

[外链图片转存中…(img-Zf42YvTb-1710391583449)]

成年人的世界没有容易二字,前段时间刷抖音看到一个程序员连着加班两星期到半夜2点的视频。在这个行业若想要拿高薪除了提高硬实力别无他法。

你知道吗?现在有的应届生实习薪资都已经赶超开发5年的程序员了,实习薪资26K,30K,你没有紧迫感吗?做了这么多年还不如一个应届生,真的非常尴尬!

进了这个行业就不要把没时间学习当借口,这个行业就是要不断学习,不然就只能被裁员。所以,抓紧时间投资自己,多学点技术,眼前困难,往后轻松!

【关注】+【转发】+【点赞】支持我!创作不易!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>