Mysql专栏 - Linux底层交互和Raid存储架构

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: Mysql专栏 - Linux底层交互和Raid存储架构

Mysql专栏 - Linux底层交互和Raid存储架构

前言

在专栏之前的几篇文章中,我们总结了缓冲池,缓存页,redo log,undo log,以及数据页和数据行在底层是如何进行存储的,后续介绍了表空间,段,区等概念。这一节比较特殊,讲述的是和Linux有关的交互原理,因为多数的mysql都是部署在linux的服务器上面,本节会简单介绍一下linux是如何处理mysql的请求的,以及linux系统会带来哪些问题

概述

  • 介绍mysql的随机读写和顺序读写,那一部分是随机读写,那一部分是顺序读写
  • linux的系统分层逻辑结构,以及和mysql系统的交互步骤。
  • Raid的存储结构简单了解,以及他对于mysql服务的影响。
  • 补充关于too many connections问题的产生原因和解决办法。

mysql的随机读写和顺序读写

mysql在执行增删改查的时候,会从表空间的磁盘文件里面读取数据页,首先我们需要明白一点,虽然在表空间的磁盘文件的数据页上进行磁盘的时是随机读写,但是包括Redo logbin log 等这些日志文件其实在磁盘上是顺序读写的。

磁盘的随机读

随机读取一个数据页到缓存就是磁盘的随机读操作,因为数据页的位置并不是固定的可能在磁盘的任意一位置,所以整个读写性能十分差的,根据之前的介绍,当数据页读取之后放到buffer pool里面。

为了IO的性能,这里需要了解两个重要的性能指标:IOPS响应延迟。IOPS 指的是存储系统每秒可以执行多少次磁盘读写操作,底层磁盘支持每秒执行1000个随机读写和200个差距是很大的。响应延迟说的则是一次IO请求之后多少时间进行响应,也是十分大的影响的,一秒200个读写是10MS完成和一次200读写却在1S完成响应差距也是非常大的。

redo日志是顺序写

虽然对于磁盘是随机读写到缓冲池,但是在缓存页更新了之后,这个数据是需要按照顺序写到redo log日志的,顺序写意味着读取的时候也可以顺序读。(关于redo log的细节将会在后续的文章介绍)磁盘顺序写的性能其实是很重要的,某种程度上来高速的顺序磁盘访问差不多可以赶上内存的读写性能,尤其是在数据库里用了os cache机制的情况下,也就是说就是redo log顺序写入磁盘之前,先是进入os cache,就是操作系统管理的内存缓存里。

关于os cache可以翻一翻之前的文章,他还有一个作用是如果innodb引擎中设置:innodb_flush_log_at_trx_commit 为 2,会在写入redo日志的时候把数据显写到os cache当中,并且在1S之后(可能)再把数据刷新回redo log的磁盘文件,但是这样在mysql宕机的时候会出现数据丢失的隐患....

另外这里在学习的时候查找了一下关于os cache以及application cache的速度消耗对比,在答案中讨论了缓存的有效性判定条件,以及什么时候才需要使用cache。感兴趣可以查看一下具体的文章内容:

stackoverflow.com/questions/1…

最后我们根据上面的文字总结下面的图:

image.png

根据上面的说明,我们大致可以总结出下面两点:

  • 写redo log的速度越快说明查询的sql性能就越高。
  • 磁盘每秒可以写入越多的数据,也说明越高的性能。

Linux系统分层

下面我们进入正题,简单来说Linux的存储系统分为VFS层、文件系统层、Page Cache缓存层、通用Block层、IO调度层、Block设备驱 动层、Block设备层,如下图:

mysql和linux交互步骤:

下面是mysql和llinux交互的大致流程:

  1. VFS层:当mysql发起一次数据页的随机读写,一次redo log顺序读写的时候,实际上会把io请求交给linux的vfs层面。
  2. 文件系统:vfs会把io请求需按照对应的文件管理系统进行操作和读写。比如ext1、ext2、ext3
  3. Page cache:文件系统会在page cache基于内存的缓存找所需的数据,基于内存缓存来执行读写,如果还没有此时会交给block层
  4. Block层:在一层把你对文件的io请求转换为block io
  5. io调度层:默认用的是CFS 公平调度算法,io调度完成之后,会决定那个io请求先执行那个后执行。

CFS调度器:采用完全公平调度算法,引入虚拟运行时间概念;

Deadline调度器:使用红黑树,把进程按照绝对截止期限进行排序,选择最小进程进行调度运行

实际情况下执行多个数据库请求的时候多个sql同时在io,所以建议生产环境把io调度算法换成 deadline调度,核心思想就是任何一个io不能随心所欲一直等待,在指定范围内他必须执行。

  1. Block设备驱动层:此时可以执行io的请求的就会交给block设备驱动层,最后把驱动交给设备层
  2. Block设备层:硬件设备完成了IO读写操作之后要不然是写要不然是读,最后就把响应经过上面的层级反向依次返回。

最终 MySQL可以得到本次IO读写操作的结果,最终的结构图如下所示:

image.png

ERROR 1040(HY000): Too many connections问题

下面补充一个比较常见的linux相关问题。

在专栏的第一篇介绍中我们知道数据库是存在连接池的概念,但是连接池的容量总归是有限的,出现这个报错说明连接池已经满了。

默认情况下每一台机器默认的连接池大小是200,每台java系统最多建立200个连接,如果是2台机器,最多400个连接。

关于这个设置的关键的参数是max_connections:比如最大连接数目是800.

实际上,在运行过程中通常会发现:show variables like 'max_connections'在线上的设置只有214,这是什么情况?为什么mysql会自动重置呢?其实是因为linux打开句柄的数量是1024导致只能连接214个

如何解决上面的问题

在linux当中:执行命令Ulimit -HSn 65535可以修改句柄的配置,为了验证是否成功,可以通过下面的命令查看句柄的配置:

Cat /ect/security/limits.conf

Cat /etc/rc.load

为了保险起见,也可以在my.cnf 的内部确保了 mac_connections 参数配置。

为什么最大连接数是214呢?

linux默认会限制你每个进程对机器资源的使用的,包括可以打开的文件句柄的限制,可以打开的子进程数的限制,网络缓存的限制,最大可以锁定的内存大小。

为了让mysql发挥最大的功效,句柄的设置值通常都是65535

所以我们平时可以用`ulimit`命令来设置每个进程被限制使用的资源量,用ulimit -a就可以看到进程被限制使用的各种资 源的量比如 core file size 代表的进程崩溃时候的转储文件的大小限制,max locked memory就是最大锁定内存大小,open files就是最大可以打开的文件句柄数量,max user processes就是最多可以拥有的子进程数量。

设置之后,我们要确保变更落地到/etc/security/limits.conf文件里,永久性的设置进程的资源限制所以执行ulimit -HSn 65535命令后,要用如下命令检查一下是否落地到配置文件里去了。

cat /etc/security/limits.conf 以及 cat /etc/rc.local

Raid存储架构的初步了解

了解完系统分层下面我们来聊聊Raid的存储架构。

进程操作系统和服务器的关系

mysql说白了也是一门编程语言,所以也是依赖操作系统执行的,他需要使用cpu内存和硬盘这些硬件进行存储。

磁盘冗余阵列简单理解:

磁盘冗余阵列,最简单的理解就是说使用一块硬盘管理多块硬盘的技术,在存储的层面上使用多个磁盘进行管理。那么磁盘RAID的硬盘有什么用?

RAID硬盘介绍:

  1. 数据冗余机制 - 备份:当多块磁盘中有一块硬盘挂了的时候,RAID硬盘可以对于其中一块的硬盘数据冗余到其他的磁盘。
  2. 多磁盘管理技术:RAID 0 RAID 1 …....
  3. RAID 卡缓存:类似于服务器的主内存的模式,和内存类似的SDRAM,大致认为基于内存进行存储。

对于RAID硬盘,内部通常会有一块叫做SDRAM的空间,用于保存操作系统的内存缓存,但是这一块类似内存的东西一旦断电怎么办,这样数据如果没有刷新到硬盘不就丢失?所以RAID基于锂电池供电运行把缓存的数据写入到磁盘阵列的磁盘。

然而锂电池也是要休息的,也存在性能衰退,所以需要在30 - 90天之内自动进行充放电一次,这样才可以延长锂电池的寿命和校准电池容量。

由于充放电的问题,通常充电放电的时候需要把数据写入磁盘而不是写入到缓存中防治数据丢失,但是也是因为这个问题定期充电放电导致的会性能大幅度的波动,在实际的体验上是定期的数据库线上波动。

至于如何解决上面的问题,我们放到下文介绍,我们先来补充一下raid的关系。

Raid 0 和 raid 1是什么关系?

在raid硬盘当中,有一块硬盘出现问题,此时就会在1和0之间形成一个数据冗余,一块磁盘坏了另一块上面也会有数据在上面。raid磁盘意味着每两块磁盘形成一个互为镜像的架构,一共有三组,所以会形成3组镜像的数据冗余。

image.png

raid锂电池的充放电问题处理办法:

  1. 锂电池换成电容,支持透明的冲带你放电,但是电容易老化,(不常用
  2. 手动充放电,在业务的低峰时期,关闭raid自动的充电放电,脚本触发**(通常解决办法)**
  3. 充电放电的时候不关闭write back,不降低缓存的级别为write through。(配合第二个策略使用)

总结

本节内容也是偏向理论为主,简单介绍了mysql的磁盘随机写和磁盘顺序写,并且简单介绍了linux的系统分层的逻辑结构,最后我们了解了Raid的存储架构,以及RAID的锂电池的细节。

写在最后

本篇内容同样比较基础,如果有意见或者建议欢迎指导。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
19天前
|
Linux 编译器 开发者
Linux设备树解析:桥接硬件与操作系统的关键架构
在探索Linux的庞大和复杂世界时🌌,我们经常会遇到许多关键概念和工具🛠️,它们使得Linux成为了一个强大和灵活的操作系统💪。其中,"设备树"(Device Tree)是一个不可或缺的部分🌲,尤其是在嵌入式系统🖥️和多平台硬件支持方面🔌。让我们深入了解Linux设备树是什么,它的起源,以及为什么Linux需要它🌳。
Linux设备树解析:桥接硬件与操作系统的关键架构
|
1月前
|
网络协议 Linux
Linux DNS服务详解——DNS主从架构配置
Linux DNS服务详解——DNS主从架构配置
408 4
|
1天前
|
存储 安全 Linux
Linux中的软RAID
Linux中的软RAID
12 2
|
7天前
|
SQL 关系型数据库 MySQL
Python与MySQL数据库交互:面试实战
【4月更文挑战第16天】本文介绍了Python与MySQL交互的面试重点,包括使用`mysql-connector-python`或`pymysql`连接数据库、执行SQL查询、异常处理、防止SQL注入、事务管理和ORM框架。易错点包括忘记关闭连接、忽视异常处理、硬编码SQL、忽略事务及过度依赖低效查询。通过理解这些问题和提供策略,可提升面试表现。
28 6
|
28天前
|
canal 消息中间件 关系型数据库
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
78 0
|
1月前
|
存储 Kubernetes 固态存储
IEEE HPCA 2024|LightPool:高性能、轻量级的存储池化架构
IEEE HPCA 2024|LightPool:高性能、轻量级的存储池化架构
|
1月前
|
设计模式 前端开发 数据处理
MVC架构中,控制器和模型之间是如何交互的
MVC架构中,控制器和模型之间是如何交互的
10 0
|
1月前
|
存储 监控 容灾
TiDB存储层深入:分布式存储架构与数据一致性保障
【2月更文挑战第26天】本文将深入探讨TiDB的存储层,详细解析其分布式存储架构、数据复制机制以及数据一致性保障措施。通过了解存储层的核心组件和工作原理,我们可以更好地理解TiDB如何确保数据的可靠性、高可用性和可扩展性。本文将从存储层的架构、数据分布、容错机制等方面展开介绍,帮助读者全面掌握TiDB存储层的关键技术和优势。
|
1月前
|
架构师 算法 关系型数据库
数据库架构师之道:MySQL安装与系统整合指南
数据库架构师之道:MySQL安装与系统整合指南
45 0
|
2月前
|
存储 监控 关系型数据库
ELK架构监控MySQL慢日志
ELK架构监控MySQL慢日志