• mysql:解决高并发访问瓶颈问题


    一、缓存式的应用程序架构:

    在应用层和db层之间加一层cache层,主要目的:减少数据库读取负担,提高数据读取速度。cache存取的媒介是内存,可以考虑采用分布式的cache层,这样更容易破除内存容量的限制,同时增加了灵活性。游戏多采用redis、Memcached这类。

    二、实现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、表=中间变量 % 每个库的表数量

    数据库经过业务拆分及分库分表,虽然查询性能和并发处理能力提高了。但是原本跨表的事务上升为分布式事务;由于记录被切分到不同的库和不同的表中,难以进行多表关联查询,并且不能不指定路由字段对数据进行查询。且分库分表后需要进一步对系统进行扩容(路由策略变更)将变得非常不方便,需要重新进行数据迁移。

    五、数据操作

    数据库加索引

    选择利于高效查询的数据类型

    1.多用数字运算,少用字符串运算

    2.当较小类型够用时,就不用较大类型

    3.把数据列声明成NOT NULL

    4.考虑使用ENUM

    5.整理表碎片

    6.使用合成索引

    Innodb与Myisam引擎的区别与应用场景


    1. 区别:

    (1)事务处理:

    MyISAM是非事务安全型的,而InnoDB是事务安全型的(支持事务处理等高级处理);

    (2)锁机制不同:

    MyISAM是表级锁,而InnoDB是行级锁;

    (3)select ,update ,insert ,delete 操作:

    MyISAM:如果执行大量的SELECT,MyISAM是更好的选择
    InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表

    (4)查询表的行数不同:

    MyISAM:select count(*) from table,MyISAM只要简单的读出保存好的行数,注意的是,当count(*)语句包含   where条件时,两种表的操作是一样的
    InnoDB : InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行
    (5)外键支持:
    mysiam表不支持外键,而InnoDB支持

    2. 为什么MyISAM会比Innodb 的查询速度快。

    INNODB在做SELECT的时候,要维护的东西比MYISAM引擎多很多;
    1)数据块,INNODB要缓存,MYISAM只缓存索引块,  这中间还有换进换出的减少; 
    2)innodb寻址要映射到块,再到行,MYISAM 记录的直接是文件的OFFSET,定位比INNODB要快
    3)INNODB还需要维护MVCC一致;虽然你的场景没有,但他还是需要去检查和维护
    MVCC ( Multi-Version Concurrency Control )多版本并发控制 
    3. 应用场景

    MyISAM适合:(1)做很多count 的计算;(2)插入不频繁,查询非常频繁;(3)没有事务。

    InnoDB适合:(1)可靠性要求比较高,或者要求事务;(2)表更新和查询都相当的频繁,并且行锁定的机会比较大的情况。

    参考:

    https://blog.csdn.net/u010832551/article/details/77836681

    https://www.cnblogs.com/changna1314/p/6878900.html

  • 相关阅读:
    redis持久化方案之RDB
    redis实现分布式锁
    redis数据类型(图解)
    js上拉加载
    apicloud直接上传图片
    layer.confirm
    json数组去重
    js解决手机键盘影响定位的问题
    click禁用事件
    ipcloud上传裁切图片,保存为base64再压缩传给后台
  • 原文地址:https://www.cnblogs.com/losophy/p/9232292.html
Copyright © 2020-2023  润新知