MySQL——高性能

MySQL高性能优化思路

  • 读写分离
  • 分库分表

读写分离

为什么要读写分离?

写负载是不能够分担的,而且只能在主库上进行写操作。读操作主从上都可以。为了分担主库的读负载,就需要进行读写分离,写操作只能在主库上进行,而读操作尽量的在从库上完成。

而完成读写分离后,对于读操作,如何分配多个服务器的读操作,这就需要我们进行读的负载均衡了。

目前实现读写分离有两种方式:

  • 由程序实现读写分离;
  • 由中间件实现读写分离,例如 mysql-proxy(高并发下存在一定的问题)、maxScale(相对来说性能损耗小);

优缺点对比

- 优点 缺点
由程序实现读写分离 1、由开发人员控制什么样的查询在从库中执行,比较灵活;
2、由程序直接连接数据,性能损耗比较少;
1、增加了开发的工作量,使程序代码更加复杂;
2、人为控制,容易出现错误;
由中间件实现读写分离 1、由中间件根据查询语法分析,自动完成读写分离;
2、对程序透明,对于已有程序不用做任何调整;
1、由于增加了中间层,所以对查询性能有损耗(经测试,QPS可能降低50%-70%);
2、对于延迟敏感的业务,无法自动在主库执行,不灵活;

分库分表

随着业务的不断增长,数据库中的数据也会越来越多,数据库的压力会越来越大,我们会发现,在业务繁忙的时候,数据库的性能会直线下降,这时为了保证良好的性能,需要想办法分担数据库的压力。分担数据库的读负载可以使用主从复制的方式,增加只读从数据库,通过读写分离的方式把数据库的读负载分担到不同的从数据库中,这时在一段时间内已经可以解决问题了。随着业务的发展,会发现,单一的主数据库已经无法承担写负载了,那么这时就需要对单一的主数据库进行拆分了。

数据库分片

为了解决上面的问题,我们需要对一个库中的相关表进行水平拆分到不同实例的数据库中,即需要进行分片处理,我们通常所说的分库,大多数情况下指的就是这种方式。

数据库分片前的准备:

在进行数据库分片前,最重要的一项工作就是如何选择分区键。分区键决定了我们如何对数据库进行分片,以及分片后如何查询数据。分区键选择的是否合适直接决定了分区后数据库的性能,对于分区键的选择,我们应该做到以下几点:

  • 分区键要能尽量避免跨分片查询的发生;
  • 分区键要能尽量使各个分片中的数据平均。

如何存储无需分片的表?

  • 方案一:每个分片中存储一份相同(冗余)的数据。这种方式可以更好的提高查询效率。如果使用这种方式,对于维护每个分片中相同表的一致性就显得非常重要了,一般可以采用多写的方式维护数据;
  • 方案二:使用额外的节点统一存储。好处是不存在数据冗余问题。如果分片的表与统一存储的表需要关联查询时,就只能由程序分别查询后进行合并操作了,查询效率比方案一要差一些。

如何在节点上部署分片?

  • 方案一:每个分片使用单一数据库,并且数据库名也相同;
  • 方案二:将多个分片表存储在一个数据库中, 由于数据的表不能重名,所以需要在表名上加入分片号后缀;
  • 方案三:在一个节点中部署多个数据库,每个数据库包含一个分片。

如何分配分片中的数据?

  • 方案一:按分区键的 Hash 值取模来分配分片数据。优点是可以相对平均的,在各个分片中分配数据,缺点是很难人为的控制什么样的数据分配到哪个分片中;
  • 方案二:按分区键的范围来分配分片数据。常用于分区键是日期类型或数值类型的情况,优点是可以很清楚的知道某条数据分配到了哪个分片中,缺点是很容易产生数据分配不平均和数据访问量不平均的情况;
  • 方案三:利用分区键和分片的映射表来分配分片数据,这张映射表需要使用缓存的方式进行缓存,否则这张映射表就可能会成为系统的瓶颈。

如何生成全局唯一ID?

  • 方案一:使用 auto_increment_increment 和 auto_increment_offset 参数;
  • 方案二:使用全局节点来生成ID,比如雪花ID
  • 方案三:使用 Redis 等缓存服务器中创建全局 ID。

猜你喜欢

转载自blog.csdn.net/lwl2014100338/article/details/107877308