怎么做高可用存储空间,如何设计和实现高可用的MySQL
一、电脑的磁盘阵列是怎么做的
磁盘阵列(DiscArray)是由许多台磁盘机或光盘机按一定的规则,如分条(Striping)、分块(Declustering)、交叉存取(Interleaving)等组成一个快速,超大容量的外存储器子系统。它在阵列控制器的控制和管理下,实现快速,并行或交叉存取,并有较强的容错能力。从用户观点看,磁盘阵列虽然是由几个、几十个甚至上百个盘组成,但仍可认为是一个单一磁盘,其容量可以高达几百~上千千兆字节,因此这一技术广泛为多媒体系统所欢迎。
盘阵列的全称是:
RedundanArrayofInexpensiveDisk,简称RAID技术。它是1988年由美国加州大学Berkeley分校的DavidPatterson教授等人提出来的磁盘冗余技术。从那时起,磁盘阵列技术发展得很快,并逐步走向成熟。现在已基本得到公认的有下面八种系列。
1.RAID0(0级盘阵列)
RAID0又称数据分块,即把数据分布在多个盘上,没有容错措施。其容量和数据传输率是单机容量的N倍,N为构成盘阵列的磁盘机的总数,I/O传输速率高,但平均无故障时间MTTF(MeanTimeToFailure)只有单台磁盘机的N分之一,因此零级盘阵列的可靠性差。
2.RAID1(1级盘阵列)
RAID1又称镜像(Mirror)盘,采用镜像容错来提高可靠性。即每一个工作盘都有一个镜像盘,每次写数据时必须同时写入镜像盘,读数据时只从工作盘读出。一旦工作盘发生故障立即转入镜像盘,从镜像盘中读出数据,然后由系统再恢复工作盘正确数据。因此这种方式数据可以重构,但工作盘和镜像盘必须保持一一对应关系。这种盘阵列可靠性很高,但其有效容量减小到总容量一半以下。因此RAID1常用于对出错率要求极严的应用场合,如财政、金融等领域。
3.RAID2(2级盘阵列)
RAID2又称位交叉,它采用汉明码作盘错检验,无需在每个扇区之后进行CRC(CyclicReDundancycheck)检验。汉明码是一种(n,k)线性分组码,n为码字的长度,k为数据的位数,r为用于检验的位数,故有:n=2r-1r=n-k
因此按位交叉存取有利于作汉明码检验。这种盘适于大数据的读写。但冗余信息开销还是太大,阻止了这类盘的广泛应用。
4.RAID3(3级盘阵列)
RAID3为单盘容错并行传输阵列盘。它的特点是将检验盘减小为一个(RAID2校验盘为多个,DAID1检验盘为1比1),数据以位或字节的方式存于各盘(分散记录在组内相同扇区号的各个磁盘机上)。它的优点是整个阵列的带宽可以充分利用,使批量数据传输时间减小;其缺点是每次读写要牵动整个组,每次只能完成一次I/O。
5.RAID4(4级盘阵列)
RAID4是一种可独立地对组内各盘进行读写的阵列。其校验盘也只有一个。
RAID4和RAID3的区别是:RAID3是按位或按字节交叉存取,而RAID4是按块(扇区)存取,可以单独地对某个盘进行*作,它无需象RAID3那样,那怕每一次小I/O*作也要涉及全组,只需涉及组中两台磁盘机(一台数据盘,一台检验盘)即可。从而提高了小量数据的I/O速率。
6.RAID5(5级盘阵列)
RAID5是一种旋转奇偶校验独立存取的阵列。它和RAID1、2、3、4各盘阵列的不同点,是它没有固定的校验盘,而是按某种规则把其冗余的奇偶校验信息均匀地分布在阵列所属的所有磁盘上。于是在同一台磁盘机上既有数据信息也有校验信息。这一改变解决了争用校验盘的问题,因此DAID5内允许在同一组内并发进行多个写*作。所以RAID5即适于大数据量的*作,也适于各种事务处理。它是一种快速,大容量和容错分布合理的磁盘阵列。
7.RAID6(6级盘阵列)
RAID6是一种双维奇偶校验独立存取的磁盘阵列。它的冗余的检、纠错信息均匀分布在所有磁盘上,而数据仍以大小可变的块以交叉方式存于各盘。这类盘阵列可容许双盘出错。
8.RAID7(7级盘阵列)
RAID7是在RAID6的基础上,采用了cache技术,它使得传输率和响应速度都有较大的提高。Cache是一种高速缓冲存储器,即数据在写入磁盘阵列以前,先写入cache中。一般采用cache分块大小和磁盘阵列中数据分块大小相同,即一块cache分块对应一块磁盘分块。在写入时将数据分别写入两个独立的cache,这样即使其中有一个cache出故障,数据也不会丢失。写*作将直接在cache级响应,然后再转到磁盘阵列。数据从cache写到磁盘阵列时,同一磁道的数据将在一次*作中完成,避免了不少块数据多次写的问题,提高了速度。在读出时,主机也是直接从cache中读出,而不是从阵列盘上读取,减少与磁盘读*作次数,这样比较充分地利用了磁盘带宽。
这样cache和磁盘阵列技术的结合,弥补了磁盘阵列的不足(如分块写请求响应差等缺陷),从而使整个系统以高效、快速、大容量、高可靠以及灵活、方便的存储系统提供给用户,从而满足了当前的技术发展的需要,尤其是多媒体系统的需要。
解析磁盘阵列的关键技术
存储技术在计算机技术中受到广泛关注,服务器存储技术更是业界关心的热点。一谈到服务器存储技术,人们几乎立刻与SCSI(Small Computer Systems Interface)技术联系在一起。尽管廉价的IDE硬盘在性能、容量等关键技术指标上已经大大地提高,可以满足甚至超过原有的服务器存储设备的需求。但由于Internet的普及与高速发展,网络服务器的规模也变得越来越大。同时,Internet不仅对网络服务器本身,也对服务器存储技术提出了苛刻要求。无止境的市场需求促使服务器存储技术飞速发展。而磁盘阵列是服务器存储技术中比较成熟的一种,也是在市场上比较多见的大容量外设之一。
在高端,传统的存储模式无论在规模上,还是安全上,或是性能上,都无法满足特殊应用日益膨胀的存储需求。诸如存储局域网(SAN)等新的技术或应用方案不断涌现,新的存储体系结构和解决方案层出不穷,服务器存储技术由直接连接存储(DAS)向存储网络技术(NAS)方面扩展。在中低端,随着硬件技术的不断发展,在强大市场需求的推动下,本地化的、基于直接连接的磁盘阵列存储技术,在速度、性能、存储能力等方面不断地迈上新台阶。并且,为了满足用户对存储数据的安全、存取速度和超大的存储容量的需求,磁盘阵列存储技术也从讲求技术创新、重视系统优化,以技术方案为主导的技术推动期逐渐进入了强调工业标准、着眼市场规模,以成熟产品为主导的产品普及期。
回顾磁盘阵列的发展历程,一直和SCSI技术的发展紧密关联,一些厂商推出的专有技术,如IBM的SSA(Serial Storage Architecture)技术等,由于兼容性和升级能力不尽如人意,在市场上的影响都远不及SCSI技术广泛。由于SCSI技术兼容性好,市场需求旺盛,使得SCSI技术发展很快。从原始5MB/s传输速度的SCSI-1,一直发展到现在LVD接口的160MB/s传输速度的Ultra 160 SCSI,320MB/s传输速度的Ultra 320 SCSI接口也将在2001年出现(见表1)。从当前市场看,Ultra 3 SCSI技术和RAID(Redundant Array of Inexpensive Disks)技术还应是磁盘阵列存储的主流技术。
SCSI技术
SCSI本身是为小型机(区别于微机而言)定制的存储接口,SCSI协议的Version 1版本也仅规定了5MB/s传输速度的SCSI-1的总线类型、接口定义、电缆规格等技术标准。随着技术的发展,SCSI协议的Version 2版本作了较大修订,遵循SCSI-2协议的16位数据带宽,高主频的SCSI存储设备陆续出现并成为市场的主流产品,也使得SCSI技术牢牢地占据了服务器的存储市场。SCSI-3协议则增加了能满足特殊设备协议所需要的命令集,使得SCSI协议既适应传统的并行传输设备,又能适应新出现的一些串行设备的通讯需要,如光纤通道协议(FCP)、串行存储协议(SSP)、串行总线协议等。渐渐地,“小型机”的概念开始弱化,“高性能计算机”和“服务器”的概念在人们的心目中得到强化,SCSI一度成为用户从硬件上来区分“服务器”和PC机的一种标准。
通常情况下,用户对SCSI总线的关心放在硬件上,不同的SCSI的工作模式意味着有不同的大传输速度。如40MB/s的Ultra SCSI、160MB/s的Ultra 3 SCSI等等。但大传输速度并不代表设备正常工作时所能达到的平均访问速度,也不意味着不同SCSI工作模式之间的访问速度存在着必然的“倍数”关系。SCSI控制器的实际访问速度与SCSI硬盘型号、技术参数,以及传输电缆长度、抗干扰能力等因素关系密切。提高SCSI总线效率必须关注SCSI设备端的配置和传输线缆的规范和质量。可以看出,Ultra 3模式下获得的实际访问速度还不到Ultra Wide模式下实际访问速度的2倍。
一般说来,选用高速的SCSI硬盘、适当增加SCSI通道上连接硬盘数、优化应用对磁盘数据的访问方式等,可以大幅度提高SCSI总线的实际传输速度。尤其需要说明的是,在同样条件下,不同的磁盘访问方式下获得的SCSI总线实际传输速度可以相差几十倍,对应用的优化是获得高速存储访问时必须关注的重点,而这却常常被一些用户所忽视。按4KB数据块随机访问6块SCSI硬盘时,SCSI总线的实际访问速度为2.74MB/s,SCSI总线的工作效率仅为总线带宽的1.7%;在完全不变的条件下,按256KB的数据块对硬盘进行顺序读写,SCSI总线的实际访问速度为141.2MB/s,SCSI总线的工作效率高达总线带宽的88%。
随着传输速度的提高,信号传输过程中的信号衰减和干扰问题显得越来越突出,终结器在一定程度上可以起到降低信号波反射,改善信号质量的作用。同时,LVD(Low-Voltage Differential)技术的应用也越来越多。LVD工作模式是和SE(Single-Ended)模式相对应的,它可以很好地抵抗传输干扰,延长信号的传输距离。同时,Ultra 2 SCSI和Ultra 3 SCSI模式也通过采用专用的双绞型SCSI电缆来提高信号传输的质量。
在磁盘阵列的概念中,大容量硬盘并不是指单个硬盘容量大,而是指将单个硬盘通过RAID技术,按RAID级别组合成更大容量的硬盘。所以在磁盘阵列技术中,RAID技术是比较关键的,同时,根据所选用的RAID级别的不同,得到的“大硬盘”的功能也有不同。
RAID是一项非常成熟的技术,但由于其价格比较昂贵,配置也不方便,缺少相对专业的技术人员,所以应用并不十分普及。据统计,全世界75%的服务器系统目前没有配置RAID。由于服务器存储需求对数据安全性、扩展性等方面的要求越来越高,RAID市场的开发潜力巨大。RAID技术是一种工业标准,各厂商对RAID级别的定义也不尽相同。目前对RAID级别的定义可以获得业界广泛认同的只有4种,RAID 0、RAID 1、RAID 0+1和RAID 5。
RAID 0是无数据冗余的存储空间条带化,具有低成本、极高读写性能、高存储空间利用率的RAID级别,适用于Video/ Audio信号存储、临时文件的转储等对速度要求极其严格的特殊应用。但由于没有数据冗余,其安全性大大降低,构成阵列的任何一块硬盘损坏都将带来数据灾难性的损失。所以,在RAID 0中配置4块以上的硬盘,对于一般应用来说是不明智的。
RAID 1是两块硬盘数据完全镜像,安全性好,技术简单,管理方便,读写性能均好。但其无法扩展(单块硬盘容量),数据空间浪费大,严格意义上说,不应称之为“阵列”。
RAID 0+1综合了RAID 0和RAID 1的特点,独立磁盘配置成RAID 0,两套完整的RAID 0互相镜像。它的读写性能出色,安全性高,但构建阵列的成本投入大,数据空间利用率低,不能称之为经济高效的方案。
RAID 5是目前应用广泛的RAID技术。各块独立硬盘进行条带化分割,相同的条带区进行奇偶校验(异或运算),校验数据平均分布在每块硬盘上。以n块硬盘构建的RAID 5阵列可以有n-1块硬盘的容量,存储空间利用率非常高(见图6)。任何一块硬盘上数据丢失,均可以通过校验数据推算出来。它和RAID 3大的区别在于校验数据是否平均分布到各块硬盘上。RAID 5具有数据安全、读写速度快,空间利用率高等优点,应用非常广泛,但不足之处是1块硬盘出现故障以后,整个系统的性能大大降低。
对于RAID 1、RAID 0+1、RAID 5阵列,配合热插拔(也称热可替换)技术,可以实现数据的**恢复,即当RAID阵列中的任何一块硬盘损坏时,不需要用户关机或停止应用服务,就可以更换故障硬盘,修复系统,恢复数据,对实现HA(High Availa**lity)高可用系统具有重要意义。
各厂商还在不断推出各种RAID级别和标准。例如更高安全性的,从RAID控制器开始镜像的RAID;更快读写速度的,为构成RAID的每块硬盘配置CPU和Cache的RAID等等,但都不普及。用IDE硬盘构建RAID的技术是新出现的一个技术方向,对市场影响也较大,其突出优点就是构建RAID阵列非常廉价。目前IDE RAID可以支持RAID 0、RAID 1和RAID 0+1三个级别,多支持4块IDE硬盘。由于受IDE设备扩展性的限制,同时,也由于IDE设备也缺乏热可替换的技术支持的原因,IDE RAID的应用还不多。
总之,发展是永恒的主题,在服务器存储技术领域也不例外。一方面,一些巨头厂商尝试推出新的概念或标准,来**服务器及存储技术的发展方向,较有代表性的如Intel力推的IA-64架构及存储概念;另一方面,致力于存储的专业厂商以现有技术和工业标准为基础,推动SCSI、RAID、Fibre Channel等基于现有存储技术和方案快速更新和发展。在市场经济条件下,检验技术发展的唯一标准是市场的认同。市场呼唤好的技术,而新的技术必须起到推动市场向前发展作用时才能被广泛接受和承认。随着高性能计算机市场的发展,高性能比、高可靠性、高安全性的存储新技术也会不断涌现。
现在市场上的磁盘阵列产品有很多,用户在选择磁盘阵列产品的过程中,也要根据自己的需求来进行选择,现在列举几个磁盘阵列产品,同时也为需要磁盘阵列产品的用户提供一些选择。表2列出了几种磁盘阵列的主要技术指标。
--------------------------------------------------------------------------------
小知识:磁盘阵列的可靠性和可用性
可靠性,指的是硬盘在给定条件下发生故障的概率。可用性,指的是硬盘在某种用途中可能用的时间。磁盘阵列可以改善硬盘系统的可靠性。从表3中可以看到RAID硬盘子系统与单个硬盘子系统的可靠性比较。
此外,在系统的可用性方面,单一硬盘系统的可用性比没有数据冗余的磁盘阵列要好,而冗余磁盘阵列的可用性比单个硬盘要好得多。这是因为冗余磁盘阵列允许单个硬盘出错,而继续正常工作;一个硬盘故障后的系统恢复时间也大大缩短(与从磁带恢复数据相比);冗余磁盘阵列发生故障时,硬盘上的数据是故障当时的数据,替换后的硬盘也将包含故障时的数据。但是,要得到完全的容错性能,计算机硬盘子系统的其它部件也必须有冗余。
二、如何配置Nginx做高可用
Nginx配置
Nginx的配置主要是修改/usr/local/nginx/conf/nginx,conf文件
#配置用户和用户组
user www www;
#工作进程数,建议设置为CPU的总核数
worker_processes 2;
#全局错误日志定义类型,日志等级从低到高依次为: debug| info| notice| warn| error| crit
error_log logs/error.log info;
#记录主进程ID的文件
pid/usr/local/nginx/nginx.pid;
#一个进程能打开的文件描述符大值,理论上该值因该是多能打开的文件数除以进程数。但是由于nginx负载并不是完全均衡的,
#所以这个值好等于多能打开的文件数。执行 sysctl-a| grep fs.file可以看到linux文件描述符。
worker_rlimit_nofile 65535;
#工作模式与连接数上限
events{
#工作模式,linux2.6版本以上用epoll
use epoll;
#单个进程允许的大连接数
worker_connections 65535;
}
#设定http服务器,利用它的反向代理功能提供负载均衡支持
http{
#文件扩展名与文件类型映射表
include mime.types;
#默认文件类型
default_type application/octet-stream;
#日志格式
log_format main'$remote_addr-$remote_user [$time_local]"$request"'
'$status$body_bytes_sent"$http_referer"'
'"$http_user_agent""$http_x_forwarded_for"';
#access log记录了哪些用户,哪些页面以及用户浏览器、ip和其他的访问信息
access_log logs/access.log main;
#服务器名字的hash表大小
server_names_hash_bucket_size 128;
#客户端请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,
#如果header过大,它会使用large_client_header_buffers来读取。
#如果设置过小HTTP头/Cookie过大会报400错误 nginx 400 bad request
#如果超过buffer,就会报HTTP 414错误(URI Too Long)
#nginx接受长的HTTP头部大小必须比其中一个buffer大,否则就会报400的HTTP错误(Bad Request)。
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
#客户端请求体的大小
client_body_buffer_size 8m;
#隐藏ngnix版本号
server_tokens off;
#忽略不合法的请求头
ignore_invalid_headers on;
#指定启用除第一条error_page指令以外其他的error_page。
recursive_error_pages on;
#让 nginx在处理自己内部重定向时不默认使用 server_name设置中的第一个域名
server_name_in_redirect off;
#开启文件传输,一般应用都应设置为on;若是有**的应用,则可以设置成off来平衡网络I/O和磁盘的I/O来降低系统负载
sendfile on;
#告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送。
tcp_nopush on;
#告诉nginx不要缓存数据,而是一段一段的发送--当需要及时发送数据时,就应该给应用设置这个属性,
#这样发送一小块数据信息时就不能立即得到返回值。
tcp_nodelay on;
#长连接超时时间,单位是秒
keepalive_timeout 65;
#gzip模块设置,使用 gzip压缩可以降低网站带宽消耗,同时提升访问速度。
gzip on;#开启gzip
gzip_min_length 1k;#小压缩大小
gzip_buffers 4 16k;#压缩缓冲区
gzip_http_version 1.0;#压缩版本
gzip_comp_level 2;#压缩等级
gzip_types text/plain application/x-javascript text/css application/xml;#压缩类型
#upstream作负载均衡,在此配置需要轮询的服务器地址和端口号,max_fails为允许请求失败的次数,默认为1.
#weight为轮询权重,根据不同的权重分配可以用来平衡服务器的访问率。
upstream hostname{
server 192.168.2.149:8080 max_fails=0 weight=1;
server 192.168.1.9:8080 max_fails=0 weight=1;
}
#主机配置
server{
#监听端口
listen 80;
#域名
server_name hostname;
#字符集
charset utf-8;
#单独的access_log文件
access_log logs/192.168.2.149.access.log main;
#反向代理配置,将所有请求为的请求全部转发到upstream中定义的目标服务器中。
location/{
#此处配置的域名必须与upstream的域名一致,才能转发。
proxy_pass ;
proxy_set_header X-Real-IP$remote_addr;
}
#启用nginx status监听页面
location/nginxstatus{
stub_status on;
access_log on;
}
#错误页面
error_page 500 502 503 504/50x.html;
location=/50x.html{
root html;
}
}
}
至此,nginx基本的负载均衡配置完成,实验中部署2台tomcat,然后访问时返回不同的结果,在浏览器中输入地址,确实能看到不同的返回结果。nginx配置文件的内容还有待于继续学习。
三、如何设计和实现高可用的MySQL
王甲坤,腾讯高级工程师、腾讯云关系型数据库MySQL负责人,拥有多年客户端、数据库研发经验。在IOS客户端、MySQL、PostgreSQL、SQL Server等产品有丰富的研发和产品策划经验。
下面开始我们今天的主要内容,今天主要是通过什么、为什么、怎么做,这条思路跟大家呈现MySQL的高可用。
首先介绍一下什么是高可用?在我看来就是业务在高质量的情况下,对用户提供服务的可运行的总时长。其实我们从事MySQL相关的工作,大家对9这个数字比较敏感,大家选择云厂商云产品的时候,首先会看它的数据库有几个9。目前腾讯云MySQL可以做到99.95,全年在25分钟的样子。
据我了解,高可用高是能做到3个9,1个6,做到4个9很困难,做到5个9就是极限了。
为什么我们要做高可用?因为我们不可控的因素太多了,比如说,挖挖机,我记得基本上每隔一年都会出现这种类似的**,让我记忆犹新的是2015年杭州萧山的某个主干网被刮断,导致阿里的部分服务不可用。另外,还有类似的一些停电,或者一些天灾等等。值得一提是,运维人员的一些*作失误案例,rm整个目录或者drop表,民间有说法叫从删库到跑路。不可控制的因素很多,你的数据、用户是你的,如果不可控的话,你的业务上不去。
一般来说,有两个指标会被当作衡量的标准,第一是RPO,第二是RTO。RPO从故障开始到业务恢复所丢失的数据量,RTO就是从故障开始到业务恢复所耗费的时长,两者都是越短越好。
我们怎么做呢?一般来说业界有三种方式,左边是基于单机存储方式,这种方式在游戏场景比较多,大家上层是用单独的计算机节点,下层用三副本保证数据的可靠性。在计算节点发生故障以后可以快速迁移到另一个计算节点,当然我们腾讯云的MySQL已经推出了这种模式,相对来说非常廉价,是基础版,大家在**都可以购买到这种模式。第二种是基于共享存储方式,也叫share disk模式,这种比较典型的是oracle的RAC架构。底层基于共享存储的方式,上层采用多个计算节点,某个计算节点故障可立即从ip列表中提出,不影响用户访问。第三种就是基于数据**模式,也就share nothing模式,通过数据传输、**协议达到两台主机数据一致性,也是本次讲解的重点。另外,除了存储节点的高可用,其整个链路也需要高可用,比如,咱们的IDC机房,交换机,以及主机服务器等。
下面我们介绍下基础设施的高可用。大家经常听到几个术语,第一是同城双活,第二是两地三中心,两地三中心对于金融相关的场景是个强需求,其实说白了就是说我们在同城两个节点相差十公里之外有两个数据中心,在100公里异地以外有另个灾备中心,保证了机房的高可用。另外包括网络、主机,其实架构上是这样的,至少说你的交换机网络都有备份,一个倒了以后,另一个需要替换上去。
下面进入我们的重点,基于数据**的高可用,首先介绍一下备份,备份确实是非常重要的,而且备份是一个实在没办法后的一个保障,所以说建议大家不管是在云上用的业务,还是自己的IDC尽量做好备份。
MySQL备份基本上是这两种:逻辑备份、物理备份。逻辑备份通常使用官方的MySQLDump与第三方工具MyDumper,MyDumper优势在于多线程备份,速率快。物理备份使用Percona的xtrabackup,可以不落盘,通过基于流式并发与压缩,生产出成功率较高、速率较快并且暂用存储空间较低的备份。后一种就是快照,我们腾讯云的基础版的备份就是通过快照生成的。
那基于数据**方式,一般是主从两个节点,数据怎么保证一致性呢?其实是通过**协议进行数据传输,通过Switch切换保证故障以后服务能够尽快恢复。右边的图基本和腾讯云MySQL差不多的架构,我们采用了一主一从的方式,从节点只负责故障的转移,当主节点挂了以后,通过自动故障探测与自动切换,从而做到业务尽快恢复。另外针对读写分离,腾讯云MySQL现可以支持一主挂5个只读节点。
下面介绍一下**,在介绍**之前有必要介绍一个重要的概念:**nlog,**nlog是二进制文件,主要记录用户对数据库更新的sql信息,**nlog是什么样子呢?它是在磁盘上是这个样子,使用show **nlog events后它是这样的,里面会记录一些元信息,比如位点、**等等,我们通过MySQL官方解析工具mysql**nlog解析后是这样的,里面sql语句是使用base64编码的,解码后是这样的,可以看到这里是条插入语句。那什么时候写**nlog呢?大家来看这个图,我们知道事务提交有两个阶段:prepare与commit,请问是哪个阶段写**nlog呢?**nlog其实是在prepare后commit前写入的,同时写事务过程中,会产生redolog与undolog,那这两者有什么区别呢?我们知道MySQL是多引擎的关系型数据库,**nlog是MySQL Server层的日志,而redolog是MySQL引擎InnoDB层的日志;另外一个不同是两者写入时机不同,redolog是prepare阶段每执行sql语句就写redo了,而**nlog是在prepare完commit前写的。那MySQL在主从架构下怎么保证数据一致性呢?众所众知,MySQL为了保证性能,数据是先写内存后落盘的。当你数据库运行的时候,发生了宕机,机器再次恢复的时候可能是部分数据落盘了,部分未落盘。这时,mysql是找到**nlog新同步的位点或GTID,来确定redolog或者undolog中哪些实例需要回滚,哪些事务需要重做。另外,在写日志的时候,比如redolog或**nlog,MySQL为保证高性能,也是先写内存后落盘的,所以日志的落盘策略也会影响数据的一致性。为保证数据的一致性,建议大家将涉及日志的参数配置为“双1”,也就是如图上所示。
下面我们来看看**整个流程,其实很简单,Master通过dump线程将**nlog落盘,在Slave上会有两个线程,分别是IO线程和SQL线程。IO线程接受来自Master的**nlog并落地形成Relaylog,SQL线程并行读取relaylog中的sql信息,执行回放动作。一般来说,**分三种:异步**、半同步、强同步。这三者的区别在于何时将sql执行的结果反馈给客户端。异步**,Master不管Slave,Master执行sql完毕后立即返回给客户端,这种方式性能好,但是存在数据不一致的可能;强同步呢,Master完全关心Slave,等待Slave将relaylog回放后才返回给客户端,这种方式能够保证数据强一致,但是其性能有一定损耗;半同步则是Master部分关心Slave,认为只要**nlog传输到Slave侧,落为relaylog后,即可以返回给客户端了。半同步是一种兼顾的实现,一方面保证数据一致性,另一方面兼顾了数据库的性能。
在**过程中,我们经常遇到延迟问题,大家看图中所示,**经历三个阶段:Dump线程落盘**nlog、IO线程落盘relaylog、以及SQL线程回放,请问三个步骤里面哪个步骤是一个瓶颈?是SQL线程,是因为SQL线程在回放日志过程中是串行执行sql的,而Master对外是并行提供服务的。所以这里瓶颈是SQL线程。大家可用通过开启并行**来解决延迟问题,MySQL5.6基于库级别并行**;MySQL 5.7基于逻辑时钟并行**,也就是表级别的并行;而MySQL8.0则是行级别的并行**,粒度更细,**效率更高。
刚才是说在协议级别进行**,其实还有一种方式是块级别的数据**,其不关心上层是什么,只需要保证在磁盘层面数据**即可。当然这种方式的话,应用的比较少。说完**后,咱们来说一下切换,其实MySQL官方之前并没有提供故障自动发现与转移的能力,基本上靠第三方工具来实现。
第一种是Keepalived,Master和Slave相互探测对方,时刻询问对方存活状态。当出现网络抖动或者网络出现问题的时候,可能会出现脑裂问题,变成了两主,数据就写错*了。第二种就是MMM的方式, M1M2互为主备,再加上一个Slave节点做冗余。从图上看,虽然是双主,但该模式下同一时间点下只能有一个节点可以写,当发现这个主写节点出现故障,会将vip切换到另一个主上比。整体看,这种方式比较老,问题比较多。第三种是MHA,其应用广泛,这种方式是由**组与管理节点组成,每个**组里是由至少三个数据节点组成,数据节点上部署监控agent,定时上报到管理节点,当主节点出现问题时,由管理节点裁决是否切换到从节点。腾讯云是自己实现了一套故障检测,结构如右边的图,由高可用保证的Monitor节点来进行故障检测与切换。另外,目前我们还在做MySQL高可用的重构,届时能够做到故障检测恢复30秒钟以内,大大提高了高可用。
下面我们来说下集群的高可用架构,比较有名的就是PXC、MGC、MGR,PXC和MGC是结构比较类似,MGR是官方提供的,具有故障转移的高可用架构。大体的层级是这样的,MGR以插件的形式存在的,MGR主要是把**协议进行改造,因为MGR支持多活,所以这里另一个重点是冲突检测,若多个节点同时写同一主键时,依照哪个为准呢?MGR是采用基于Paxos协议实现的冲突检测。下面,我们大致看下结构,MGR是支持多个节点写,即多活,支持某个节点挂了后自动剔除,恢复后自动加入集群。这张图是介绍一下MGR数据流逻辑,图上有三个节点构成小MGR集群。假设DB1有一次写提交,在Prepare阶段,MGR插件会生成一个叫WriteSet的**,并将其广播给其他节点。这个WriteSet**包含此次提交的**nlog和更新的唯一键,此唯一键由db名、表名和主键组成。这里可以看出MGR有个限制,表中必须要有主键,要不无法进行冲突检测。我们再说回来当节点收到这一信息时,会进行比对,每个节点都有一个缓存,保存当前同步情况,即唯一键对应的GTID SET。通过比对后将结果返回给DB1,只要多于半数的节点返回说OK,可以提交,那DB1接下来就会执行**nlog的落盘*作,然后返回OK到客户端。其他节点则执行写Relaylog的动作,接下来进行回放的动作。若多数节点返回冲突,DB1则执行回滚*作,其他节点会drop掉**过来的**nlog。
其实PXC和MGC思路是差不多,应该说是MGR借鉴的,因为PXC和MGC是比较早就出来的,这里大同小异,主节点将WriteSet写**广播出去,广播完后进行验证与裁决。
后我们说一下NewSQL高可用架构,首先对AWS表示致敬,孵化出非常优秀的NewSQL产品-Aurora。那Aurora是怎么产生出来的呢?这与AWS数据库架构有关。我们来看看这个图,AWS数据库是架构在虚拟机与云盘上的,我们都知道MySQL的log比较多,所以很多IO是通过耗时较高的网络来完成的,因此AWS这种架构网络IO是它的瓶颈,性能也跑不上去。在此基础上,我们来认识下Aurora。
Aurora是计算与存储分离的架构,典型的share disk的结构。底层存储采用6副本,部署在三个不同的AZ上,可以保证一个AZ挂了,或者至多两个AZ的一个副本丢失的情况下数据不丢失,业务可以正常对外服务。Aurora的理念是“日志即数据库”,其把MySQL存储层进行了彻底的改造,摒弃了很多LOG,只留下了Redolog,具备将redolog转换到Innodb page的能力。通过这种方式,Aurora宣称其减少至少85%比例的IO。另外其把备份和回档下沉到存储节点,使得备份恢复更快并得到保障。Aurora整体感觉相对比较接地气,成本相对比较低。
另一个就是阿里云的Polar,理念和AWS不同,阿里云觉得未来网络不是问题,未来网络可以接近总线的质量,所以是架构在RDMA网络的机房里,日志方面大动作较少,保证后续MySQL社区新特性可快速迭代近来。Polardb也是share disk的架构,其存储节点是通ParallelRaft协议保证数据的完备性。可见这也是个伟大的架构,但是相对来说成本比较高一些。
我们腾讯云自己的NewSQL在研发中,只是目前还没有正式上线,我们的名字叫CynosDB,相比来说我们的理念是兼顾两者,未来在高网络新硬件的基础实施下,会发挥更大的性能,更稳健的服务和更高的可用性。请大家拭目以待。
本次我的分享就到此为止。
Q& A
Q:我想问一下在腾讯游戏的高并发行业里面,我们主要采用哪种架构?
A:腾讯内部有很多自研项目,但基本上我们是基于数据**的方式。内部有phxsql等分布式集群架构。
Q:如何在高并**况下,保证总库的定延时呢?
A:可以开启并行**,业务做分库分表,分散到多个实例上。
Q:比如说像游戏类的,在游戏高峰期的话会有很多人同时**,这种情况下怎么在后台看数据呢?
A:可以对比较热的数据进行分层,前一层可以通过KV方式缓存,比如Redis,来提高热数据的读取,后一层使用MySQL,定期将数据同步落盘。
Q:这种情况下怎么保证数据库是一致的呢?
A:写数据可以不经过KV缓存,直接写MySQL数据库,读取时,缓存内没有数据,需要从DB中捞取出来。另外,KV缓存也有落地能力,非关键数据也可以不使用MySQL落地。
相关阅读
【每日课程推荐】机器学习实战!快速入门**广告业务及CTR相应知识
此文已由作者授权腾讯云+社区发布,更多原文请点击
搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024送你一份技术课程大礼包!
海量技术实践经验,尽在云加社区!
如何设计和实现高可用的MySQL
标签:负责人基础问题特性目录三种方式共享完全ali