单点数据库
数据库往往是系统中的性能瓶颈,所以通常在系统设计中会引入各种各样的缓存机制,以避免频繁访问数据库。另外,数据库由于其重要性,高可用要求也是避免不了的,因为一旦数据库挂了基本上整个系统也就不能使用了。
而以上这些常见问题都是单点数据库带来的限制,为了解决这些问题,达到高性能、高可用的目的,我们就需要在系统架构设计中采用数据库集群方案。
性能测试
既然单点数据库存在性能问题,那么有没有实际数据呢?下面我们就来对单点数据库进行一个性能测试,看看其并发极限大概是多少。我这里使用了一台2核2G的云服务,mysql版本为8.0.18。
mysql自带了一个性能测试工具:mysqlslap,我们可以使用该工具进行测试,具体的测试参数如下:
[root@localhost ~]# mysqlslap -hlocalhost -uroot -pyour_password -P3306 --concurrency=500 --iterations=1 --auto-generate-sql --auto-generate-sql-load-type=mixed --auto-generate-sql-add-autoincrement --engine=innodb --number-of-queries=500
主要参数说明: |
参数 | 说明 |
---|---|---|
--concurrency |
并发数量,即模拟的客户端数量 | |
--iterations |
执行多少次该测试 | |
--auto-generate-sql |
使用系统自己生成的SQL脚本来测 | |
--auto-generate-sql-load-type |
要测试的是读还是写还是两者混合的(取值:read, write, update, mixed) | |
--auto-generate-sql-add-autoincrement |
将自增的列添加到自动生成的表中 | |
--engine |
要测试的存储引擎 | |
--number-of-queries |
每个客户端的访问次数,该数值除以并发数量就是每个客户端的访问次数,在本例中:500 / 500 = 1 |
- 更多内容详见官方文档
这里我分别进行了不同量级的测试,在并发500、1000和5000个连接时,数据库还可以正常处理,没有太大问题:
# 500个并发连接
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 0.391 seconds
Minimum number of seconds to run all queries: 0.391 seconds
Maximum number of seconds to run all queries: 0.391 seconds
Number of clients running queries: 500
Average number of queries per client: 1
# 1000个并发连接
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 0.802 seconds
Minimum number of seconds to run all queries: 0.802 seconds
Maximum number of seconds to run all queries: 0.802 seconds
Number of clients running queries: 1000
Average number of queries per client: 1
# 5000个并发连接
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 3.884 seconds
Minimum number of seconds to run all queries: 3.884 seconds
Maximum number of seconds to run all queries: 3.884 seconds
Number of clients running queries: 5000
Average number of queries per client: 1
由该测试案例可知,普通的单节点数据库性能瓶颈大概在1w个并发连接左右。当然这里的测试结果与机器的硬件差异有关,只是提供一个参考。
PXC集群方案
上一小节介绍了单点数据库存在的问题,以及进行了一个简单的性能测试。为了应对这些问题,我们需要将单点数据库向集群转变。
目前存在许多的数据库集群方案,而这些方案中也没有哪个好那个坏,只有适合的才是好的。本小节则介绍一下主流的方案之一:PXC集群方案,其架构图大致如下:
- PXC集群最大的特点就是数据读写的强一致性,在图中的任意一个节点写入数据,其他的节点就一定能读到这个数据。不会出现A节点成功写入,而读B节点时读取不到数据。该特性使得PXC集群适合存储高价值重要数据,因为类似于订单、钱有关的数据基本都有强一致性的要求
上图只是PXC集群最基础的架构,所以还有优化的余地。我们都知道mysql的单表数据处理的性能极限在2千万左右,当数据达到这个量级时,mysql的处理性能就会很低下了。而上图中每个PXC节点都会进行数据的同步,所以当每个节点的数据量级都达到2千万时,整个集群的性能就会降低。
这时就需要增加多一个集群,并且这两个集群之间的数据是不进行同步的。为了让不同的集群存储不同的数据,就得引入Mycat这种数据库中间件将数据进行切分,让数据可以在不同的集群上进行读写,分散存储压力。在这个场景下,一个集群称为一个数据分片。如图:
PXC集群工作原理
我们知道数据库数据的一致性和持久性是通过事务来保证的,而PXC集群的强一致性也是采用了事务,只不过这个事务是分布式事务。
客户端在写入数据完成后,同样需要提交一个事务,在事务内节点之间会进行数据的同步复制。该事务会作用到集群内的所有节点上,保证所有节点要么全写入成功,要么全写入失败。这里用一个时序图表达一下大致流程:
搭建PXC集群需要注意的事项:
- PXC集群中的节点并不是越多越好,节点多并不能提高性能。相反,节点多意味着同步数据所需的耗时就越多,反而会降低性能。通常来讲,一个PXC集群最好是不超过15个节点。若需要更多的节点时,应当搭建一个新的集群,然后用中间件来做分片。
- PXC集群的性能不取决于配置最好的那个节点,而是取决于配置最差的那个节点,这和电脑硬件是类似的。所以我们应当尽量保证PXC集群内的节点配置都趋于一致,避免某个节点配置太差而拖慢了集群的整体性能。
PXC简介
说了那么多,我们还没介绍PXC是个啥玩意呢。PXC是Percona XtraDB Cluster的缩写,PXC是基于mysql自带的Galera集群技术,将不同的mysql实例连接起来,实现的多主集群。在PXC集群中每个mysql节点都是可读可写的,也就是主从概念中的主节点,不存在只读的节点。
PXC可以集群任何mysql的衍生版本,例如MariaDB和Percona Server。由于Percona Server的性能最接近于mysql企业版,性能相对于标准版的mysql有显著的提升,并且对mysql基本兼容。所以在搭建PXC集群时,通常建议基于Percona Server进行搭建。
Replication集群方案
PXC集群的数据强一致性是以牺牲性能为代价的,因为客户端需要等待所有的节点写入数据。而与之相反的一种集群方案就是本小节要介绍的Replication集群。该方案不牺牲性能,但不具有数据强一致性,正可谓鱼和熊掌不可兼得。
所谓读写非强一致的意思就是在A节点成功写入数据,并提交了事务。但在B节点上进行读取时,可能会读取不到写入的数据。
因为这里提交的事务只是该节点的本地事务,只能保证数据成功写入了该节点,而不保证数据成功写入整个集群内的节点。当该节点与其他节点进行数据同步时,可能会由于种种原因没有成功同步数据,从而导致在其他节点上读不到该数据。
所以该集群方案就不适合保存高价值的数据,但对于非高价值的数据,又对读写性能要求高的,就适合采用该集群方案。例如,用户行为日志、操作日志及商品描述等这类非重要的数据。
同样的,上图只是Replication集群最基础的架构,也需要在数据量达到一定规模时采用Mycat对数据进行分片处理。如图:
实际上,在大型的系统架构中,往往不是单独采用某一种特定的集群方案,而是多种方案进行结合。例如,PXC集群和Replication集群就可以结合使用,让PXC集群存储高价值数据,Replication集群存储低价值数据。然后采用Mycat等数据库中间件来完成集群之间的数据分片及管理,如图:
总结
- PXC集群采用同步复制,事务在所有的集群节点要么同时提交,要么不提交,能够保证集群中的数据强一致性。但性能相对较低,客户端需等待所有节点同步复制完成
- Replication集群采用异步复制,无法保证数据的强一致性。性能相对较高,客户端只需要等待目标节点的本地事务提交成功即可,而不需要等待所有节点成功复制完数据
- PXC和Replication集群都只实现了数据的同步,没有数据切分功能。当数据量大时,需要引入Mycat等数据库中间件来做数据的切分及管理
- PXC和Replication集群方案并不排他,且各有优劣,可以结合一起使用,以达到取长补短的效果。高价值数据存储至PXC集群,低价值数据存储至Replication集群