数据存储架构

在互联网系统架构中,当系统遇到高并发压力带来性能瓶颈时,应用层可以通过水平伸缩采用分布式集群部署来提高系统的处理能力。

而承受着最大处理压力,难以被水平伸缩的是数据存储部分。数据存储是整个系统的底座、基石。数据存储架构的变化往往会导致整个系统架构的改造。所以数据存储架构设计就显得尤其重要。

数据存储压力主要受两方面约束:

一、数据存储需要使用磁盘,磁盘的处理速度远低于其它几种计算机资源(如 CPU,内存,网卡等)。随着SSD固态硬盘的技术发展,磁盘的速度相对以往已经快非常多了。

二、数据是公司得要的资产,需要保证数据的高可用和一致性,非功能性约束更多一些。

在高并发的情况下,最容易出现性能问题的就是数据存储。目前,用来改善数据存储能力的主要方法包括:数据库主从复制,数据库分片和 NoSQL数据库

主从复制

以 MySQL 为例,看数据库主从复制的实现技术及应用场景。

主从复制原理

MySQL的主从复制,就是将MySQL主数据库中的数据复制到从数据库中。

其复制原理是,当应用程序客户端发送一条更新命令到主服务器数据库时,数据库会把这条更新命令同步记录到 Binlog 中,然后由另外一个线程从 Binlog 中读取这条志日,并通过远程通信的方式将它复制到从服务器上去。

从数据库获得这条更新日志后,将期加入自己的 Relay Log 中,然后由另外一个SQL执行线程,从 Relay Log 中读取这条新的日志,并把它在本地的数据库中重新执行一遍。

这样当客户端应用程序执行一个 update 命令的时候,这个命令会同时在主数据库和从数据库上执行,从而实现了主数据库向从数据库的复制,让从数据库和主数据库保持一样的数据。

读写分离实现

通过数据库主从复制的方式,可以实现数据库读写分离。写操作访问主数据库,读操作访问从数据库,使数据库具有更强大的访问负载能力,支撑更多的用户访问。

在实践中,通常采用一主多从的数据复制方案,多个数据库承担更多的读操作压力,它们分别有不同的用途,比如,有的从数据库用来做实时数据分析,有的用来做批任务报表计算,有的单纯做数据备份。

主从高可用性

采用一主多从的方案时,如果某个从数据库宕机,还可以将读操作迁移到其他从数据库上,保证读操作的高可用。

主主复制

主从复制的方案,当主数据库宕机,系统就没法使用了,无法满足主数据库的高可用。因此在现实中,也会采用 MySQL 主主复制方案

也就是说,两台服务器互相备份,任何一台服务器都会将自己的 Binlog 复制到另一台机器的 Relay Log 中,以保持两台服务器的数据一致性。

注意,主主复制仅能用来提升数据写操作的可用性,并不能提高写操作的性能。任何时候,系统中都只能有一个数据库作为主数据库,也就是说,所有的应用程序都必须连接到同一个主数据库进行写操作。只有当该数据库宕机失效的时候,才会将写操作切换到另一台主数据库上。这样才能保证数据库数据的一致性,不会出现数据冲突。

主从复制,主主复制都只能提高数据库的可用性,无法提升数据库的存储能力。

主从复制,主主复制需要数据库故障自动切换转移方案的支持,例如 MMM,MHA,MGR,PXC等架构。

分库分表

数据库分库分表可以解决大数据存储问题。将一张表的数据分成若干片,每一片都包含了数据表中一部分的行记录,且每一片都存储在不同的服务器上,这样一张表就存储在多台服务器上了。

硬编码实现

最简单的分库分表可以采用硬编码的方式,在代码中使用一定的算法计算一条数据要存放在哪个服务器的哪个表上。例如,对用户订单数据根据用户ID进行奇偶计算,ID为偶数的记录数据存储服务器A,ID为奇数的记录数据存到服务器B。

硬编码方式实现简单,但缺点也比较明显。

首先,如果要增加服务器,就必须修改分片逻辑代码,这样代码就会因为非业务需求产生不必要的变更。

其次,分析逻辑偶合在处理业务逻辑的代码中,修改分片逻辑或修改业务逻辑,可能导致影响范围扩大,进而使另一部分代码产生Bug。

中间件实现

可以通过使用分布式关系数据库中间件来实现分库分表,在中间件中完成数据的分片逻辑,数据存储对应用程序透明。

比如,使用 MyCat 实现数据库的分库分表。MyCat 实现了MySQL数据库网络协议,可以理解为一个虚拟数据库,内部提供了数据分片的逻辑,应用程像使用 MySQL 数据库一样连接 MyCat,提交SQL命令。MyCat 在收到命令后,查到配置的分片逻辑规则,解析出分片的字段,再根据该字段连接对应的数据库,并提交这条SQL到该数据库。

数据库伸缩

常见的数据库分片算法有余数Hash算法,即根据字段和服务器的数目进行取模计算,然后根据余数连接对应的服务器。但会带来集群伸缩性问题,也就是如果需要增加服务器扩容,需要重新计算数据所在的服务器,如果因增加服务器扩容导致在分布式数据库中有数据无法找到,则可能导致系统严重故障。

因此分布式数据库集群扩容,增加服务器的时候,会要求所有的数据必须正常访问,不能有数据丢失(数据分片没有命中到,扩容导致数据重新分片迁移存储而丢失),即原来服务器的部分数据完整地迁移到新服务器。

实践中,分布式关系数据库通常采用逻辑数据库进行分片,而不是物理服务器进行分片。

例如,MySQL 可以在一个数据库实现上创建多个 Schema,每个 Schema 对应自己的文件目录。数据分片的时候可以以 Schema 为单位进行,每个数据库实例可启动多个 Schema。进行服务器扩容时,只需将部分 Schema 迁移到新服务器上就可以了。因为分片不变,所以路由算法不需修改,但是集群的服务器却增加了。

而且因为 MySQL 配置了主从复制的能力,所以在迁移时,只需将这些 Schema 的从库配置到新服务器上,数据就开始复制了。等数据同步完成,再将服务器的 Schema 设置为主服务器,就完成了集群的扩容。

NoSQL

NoSQL 使用 Key,Value 的方式进行数据访问,不是使用 SQL 进行操作,所以被称为 NoSQL数据库。常用的 NoSQL 数据有 Apache HBase,Apache Cassandra 等。Redis 是一个分布式缓存技术产品,也归类为 NoSQL 数据库。

NoSQL 数据库面临的挑战之一是数据一致性问题。如果数据分布存储在多台服务器组成的集群上,当有服务器节点失效,或服务器之间网络故障,不同的用户读取到的数据可能不一致。

基于分布式系统的 CPA 原理,网络失效是不可控的,或一定会发生的,只能保证 CP 或 AP,即分区容错是必须要保证的,对于互联网应用来说,可用性也是需要保证的,分布式系统通常需要在一致性上做一定程度的妥协。

Apache Cassandra 解决数据一致性问题的方案是,在用户写入数据时,将一个数据写入集群中的三个服务器节点,等待至少两个节点响应写入成功。用户读取数据的时候,会从三个节点尝试读取,至少等到两个节点返回数据后,才根据返回数据的时间戳选取最新的版本的数据。这样即使服务器中的数据不一致,最终用户还是能得到一个一致的数据,这种方案也被称为最终一致性解决方案。

相关参考

  1. MyCat
  2. Mysql数据库架构:第十四节 Mysql高可用MHA架构解决方案
  3. mysql mmm和mha对比
  4. MGR原理及集群搭建
  5. MySQL高可用架构-MMM、MHA、MGR、PXC
作者

光星

发布于

2023-02-26

更新于

2023-03-06

许可协议

评论