解决数据库高并发访问瓶颈问题
Posted mengchunchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决数据库高并发访问瓶颈问题相关的知识,希望对你有一定的参考价值。
一、缓存式的Web应用程序架构:
在Web层和db层之间加一层cache层,主要目的:减少数据库读取负担,提高数据读取速度。cache存取的媒介是内存,可以考虑采用分布式的cache层,这样更容易破除内存容量的限制,同时增加了灵活性。
二、实现MySQL数据库异步查询实现:
通常情况下在php中mysql查询是串行的,如果能实现MySQL查询的异步化,就能实现多条SQL语句同时执行,这样就能大大地缩短MySQL查询的耗时,提高数据库查询的效率。目前MySQL的异步查询只在MySQLi扩展提供,查询方法分别是:
1、使用MYSQLI_ASYNC模式执行mysqli::query
2、获取异步查询结果:mysqli::reap_async_query
使用mysql异步查询,需要使用mysqlnd作为PHP的MySQL数据库驱动。
使用MySQL异步查询,因为需要给所有查询都创建一个新的连接,而MySQL服务端会为每个连接创建一个单独的线程进行处理,如果创建的线程过多,则会造成线程切换引起系统负载过高。Swoole中的异步MySQL其原理是通过MYSQLI_ASYNC模式查询,然后获取mysql连接的socket,加入到epoll事件循环中,当数据库返回结果时会回调指定函数,这个过程是完全异步非阻塞的。
三、MySQL主从读写分离:
当数据库的写压力增加,cache层(如Memcached)只能缓解数据库的读取压力。读写集中在一个数据库上让数据库不堪重负。使用主从复制技术(master-slave模式)来达到读写分离,以提高读写性能和读库的可扩展性。读写分离就是只在主服务器上写,只在从服务器上读,基本原理是让主数据库处理事务性查询,而从数据库处理select查询,数据库复制被用于把事务性查询(增删改)导致的改变更新同步到集群中的从数据库。
MySQL读写分离提升系统性能:
1、主从只负责各自的读和写,极大程度缓解X锁和S锁争用。
2、slave可以配置MyISAM引擎,提升查询性能以及节约系统开销。
3、master直接写是并发的,slave通过主库发送来的binlog恢复数据是异步的。
4、slave可以单独设置一些参数来提升其读的性能。
5、增加冗余,提高可用性。
实现主从分离可以使用MySQL中间件如:Atlas
四、分表分库:
在cache层的高速缓存,MySQL的主从复制,读写分离的基础上,这时MySQL主库的写压力开始出现瓶颈,而数据量的持续猛增,由于MyISAM使用表锁,在高并发下会出现严重的锁问题,大量的高并发MySQL应用开始使用InnoDB引擎代替MyISAM。采用Master-Slave复制模式的MySQL架构,只能对数据库的读进行扩展,而对数据的写操作还是集中在Master上。这时需要对数据库的吞吐能力进一步地扩展,以满足高并发访问与海量数据存储的需求。
对于访问极为频繁且数据量巨大的单表来说,首先要做的是减少单表的记录条数,以便减少数据查询所需的时间,提高数据库的吞吐,这就是所谓的分表【水平拆分】。在分表之前,首先需要选择适当的分表策略,使得数据能够较为均衡地分布到多张表中,并且不影响正常的查询。
分表能够解决单表数据量过大带来的查询效率下降的问题,但是却无法给数据库的并发处理能力带来质的提升。面对高并发的读写访问,当数据库master服务器无法承载写操作压力时,不管如何扩展Slave服务器都是没有意义的,对数据库进行拆分,从而提高数据库写入能力,即分库【垂直拆分】。
分库分表的理由策略如下:
1、中间变量=user_id % ( 库数量 * 每个库的表数量 )
2、库=取整(中间变量 / 每个库的表数量)
3、表=中间变量 % 每个库的表数量
数据库经过业务拆分及分库分表,虽然查询性能和并发处理能力提高了。但是原本跨表的事务上升为分布式事务;由于记录被切分到不同的库和不同的表中,难以进行多表关联查询,并且不能不指定路由字段对数据进行查询。且分库分表后需要进一步对系统进行扩容(路由策略变更)将变得非常不方便,需要重新进行数据迁移。
参考:
https://blog.csdn.net/u010832551/article/details/77836681
以上是关于解决数据库高并发访问瓶颈问题的主要内容,如果未能解决你的问题,请参考以下文章