暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片
在数据库系统中遇见_存储技术飞跃_会怎样?.pdf
86
10页
0次
2023-09-01
5墨值下载
在数据库系统中遇见"存储技术飞跃"会怎样?
上个月初,在Percona的博客中看到一篇关于计算存储的性能测试文章(详见文末的链接),其中提到的一
些特性,引起了我的一些兴趣,于是,又扩展研究了一下计算存储相关的技术,突然发现计算存储这块对数
据库系统来说,或许能多多少少解决一些瓶颈与痛点、甚至还能够在不影响性能的前提下大幅度降低TCO
是什么样的特性有如此魔力呢?
这里先卖个关子,文中提到的内容我们稍后再说,我们先来看看数据库系统的生命周期管理中,可能碰到哪
些瓶颈与痛点。然后,再介绍计算存储是如何系统性地化解这些瓶颈与痛点的。
PS:以下内容仅代表个人观点。另外,由于本人对MySQL比较熟悉,下面以MySQL InnoDB引擎为例简单
列举几个典型的痛点进行阐述
1、据库型的点有
数据库性能的两个关键指标:(latency)与事务的并行数量(tps),两者相辅相成,且成反比,事务的
latency越低,则允许tps就越高,反之,事务的latency越高,则允许的tps就越低。越高的tps就代表着越好
的性能,反之就代表越低的性能。数据库对IO的响应延迟非常敏感,其直接影响着事务的响应延迟,而事务
的响应延迟则在很大程度上决定着数据库的tps高低。因此,在一个硬件规格配置合理的服务器中运行
MySQL数据库,且MySQL的索引使用比较规范的场景中,我们常常能够看到最先达到瓶颈的就是IO子系统
围绕着这2个关键指标,我这里罗列了4个可能出现瓶颈与痛点的典型场景,如下
1.1. 单台数据库服务器存储能力不足
存储容量不足
传统解决方案
* 时间紧迫时,可通过频繁删除文件来腾挪空间来临时解决
* 预算充足时,可更换更大容量的存储设备,做数据全量迁移
* 预算、时间充足时,可添加更多服务器做数据拆分
存储负载过高(吞吐量过高)
传统解决方案:
* 时间紧迫时,可以通过杀死存储吞吐量消耗最大的进程来临时解决
* 预算充足时,更换更高吞吐带宽的存储设备,做数据全量迁移
* 预算、时间充足时,可添加更多服务器做数据拆分
缺点:
临时解决方案需要频繁关注存储的负载情况,而且常常顾此失彼
更换配件需要增加额外的成本,做数据拆分更是增加了业务的复杂度和维护成本、而且还引入了一些新的问
题(详见"1.4. 并发查询数过高导致数据库实例负载过高"中提到的缺点)
1.2. 数据库服务器内存不足
传统解决方案:
临时清理不需要的表数据或者调小MySQL在各种缓存分配上的参数值,以便腾出更多的内存来使MySQL
Server能够做更多的事情
增加物理内存,并调大MySQL的各种缓冲分配参数值
缺点:
临时解决方案需要持续关注内存使用量,且需要频繁地操作,而且,这是挖东墙补西墙的做法
增加物理内存,除了增加成本之外,还会对业务造成一定影响(服务器需要关机)
1.3. 单个事务过大导致查询性能低下
传统解决方案:将大事务拆分成小事务
无法拆分的大事务,在硬件规格不变的前提下,可以对读写事务分别做一些优化。例如:写可以在执行前,
会话级别将binlog格式修改为statement,以减少主从实例之间传输的binlog日志量;读事务可以拆分到只
读从库中,以减少主库的访问压力
缺点:
将大事务拆分成小事务,并不会让原本大事务需要完成的工作任务少做一些,而是拆分成小事务之后,降低
对其他并行事务的影响(例如:大事务可能长时间的持有锁、二进制日志文件句柄资源等,从而导致长时间
的阻塞其他并行事务,导致并行事务执行失败)
1.4. 并发查询数过高导致数据库实例负载过高
传统解决方案:
杀死高负载查询会话、后续优化慢查询
读写分离,并增加只读从库,扩展只读能力
数据拆分,将数据分散到多个数据库实例中,扩展读/写能力。
* 对大表做数据拆分,先做垂直拆分(按业务拆分,将不同业务的字段拆分到不同的表、或不同的数据
库、甚至不同的实例中),然后做水平拆分(对于无法继续拆分字段的表,如果数据量仍然大到影响性能,则
可能还需要以不超过1000W行数据量的标准继续对大表执行拆分,即就是我们常说的数据分片)
缺点:无论是垂直拆分还是水平拆分,都需要应用配合相应的改造,而且,数据拆分之后,会引入新的痛
点,类似如下(虽然这些痛点可以通过技术改造来解决,但成本过高,而且需要较长时间来磨合才能够使其
达到稳定,另外,可能需要和业务深度契合改造,不同的客户可能需要做不一样的改造):跨分片访问,导
致不得不启用分布式事务来保证跨分片访问的数据一致性,而分布式事务本身除了实现起来有一定工程量之
外,应用本身也需要配合改造
如果分片跨了不同的实例,则无法做到数据的全局一致性备份,要实现跨实例多数据分片的全局数据一致性
备份,需要中间件、数据库都做一些改造
不受事务控制的DDL语句,无法通过分布式事务来保证数据的全局一致性,因此,还需要额外的机制来保证
数据的全局一致性
如果分片数据出现倾斜、或者访问负载出现倾斜,则还可能需要频繁地做分片数据的迁移(将大数据量的分
片、高负载实例中的分片,迁移到较为空闲的实例中)
2、算存解决瓶颈
针对计算存储,我这里列出3个我认为比较重要的特性,先对其原理做简单的介绍(关于相关原理的详细介
绍,可参考文末的链接),然后再说说这些特性是如何解决上述数据库的瓶颈与痛点的
第一个重要的特性:存储支持硬件级别的原子写
数据库为何需要原子写?
* InnoDB 数据文件默认的Page Size为16k,文件系统默认的块大小为4k,也就是说,InnoDB数据文件
的最小IO操作单位是16k,文件系统最小IO操作单位是4k,当InnoDB数据文件写入一个16k的页到文件系统
时,文件系统需要将其分解成4个4k大小的块,再写入到存储设备中。由于大部分的文件系统并不支持原子写,
如果文件系统在写入存储设备期间,发生了意外(例如掉电),则可能导致InnoDB的Page Size发生部分写
(损坏),进而导致MySQL Server无法正常启动
* 为了避免这个问题,InnoDB引入了doublewrite特性,doublewrite用来做什么的呢?当有数据需要写
入数据文件时(即刷脏),先写入doublewrite(MySQL 8.0.20版本之前,doublewrite位于共享表空间
ibdata1中,8.0.20版本开始,使用独立的文件存储,且支持多个文件,但文件的最大数量是buffer pool
instance的2倍,即每个buffer pool instance有2个doublewrite文件),每次1MB连续写入,数据页写入
doublewrite成功之后,再将数据页写入到数据文件中,这样一来,如果发生意外导致数据页发生损坏,则在数
据库执行Crash Recovery期间,会尝试从doublewrite中找到发生损坏的页进行覆盖修复,修复之后即可正常
启动MySQL Server(注:Redo虽然能够支持数据恢复,但它记录的是数据页的增量修改内容,并不是记录的
完整的数据页,但doublewrite中的数据页是完整的,所以,可以使用doublewrite中的完整数据页恢复损坏的
数据页,然后就能够正常应用Redo)
* doublewrite分成2个部分,内存中有2M的doublewrite buffer,磁盘文件中也有2个1M的连续
doublewrite空间,引入doublewrite之后的数据写入简单示意图如下,从图中我们可以看到,脏数据要成功写
入到数据文件中,需要写2次磁盘(一次写入到doublewrite中,一次写入到数据文件中)
计算存储支持原子写,对数据库的收益是什么呢?
* 既然存储支持硬件级别的原子写,那么,也就是说,数据库层面的doublewrite特性就可以关掉了,关掉
之后,脏数据写入到数据文件只需要一次写磁盘即可,从而节省了一半的刷脏流量。即,在能保证数据页不发
生部分写的情况下,直接就能缓解存储吞吐能力不足的燃眉之急!
第二个重要的特性:数据透明压缩/解压
数据库为何需要压缩/解压?
of 10
5墨值下载
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文档的来源(墨天轮),文档链接,文档作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论