文章目录
- 一、存储服务的演化
- 1.单体结构
- 2.单表单库的数据量膨胀 -> 分库分表
- 3.单个MySQL的读写压力过大 -> MySQL索引优化
- 4.进一步缓解MySQL读写压力 -> 读写分离
- 5.冷热数据分离 -> 使用Redis缓存
- 二、MySQL分库分表
- 1.策略
- 2.需要注意的问题
一、存储服务的演化
1.单体结构
最初,服务只有一个MySQL存储。当用户通过浏览器发送请求时,请求会被发送到Java服务器上,这个后端的Java服务是使用Spring、MyBatis等框架编写的。后端服务会与MySQL进行交互,进行数据查询或写入操作。
2.单表单库的数据量膨胀 -> 分库分表
单表单库的数据量会不断增大,这个时候就可以考虑分库分表。分库分表的具体做法见下一章。
3.单个MySQL的读写压力过大 -> MySQL索引优化
如果我们碰到的是读多写少的场景,可以先尝试添加合适的索引。我在这篇博客中详细介绍了MySQL索引优化的内容。
4.进一步缓解MySQL读写压力 -> 读写分离
如果在为MySQL添加适当的索引后,单机仍然无法处理读取流量,可以考虑使用从库进行读写分离,以便多个从库共同分担读取流量。如果读写负载相对均衡,还可以考虑主从读写分离方案,这样主库只处理写入流量,从库只处理读取流量,从而减轻单个MySQL上的压力。
5.冷热数据分离 -> 使用Redis缓存
除了在全量数据上进行分治,还可以根据数据访问情况进行分治,将数据区分为冷热数据,并将经常访问的"热"数据放入更快的存储介质中,例如缓存。这样可以提高热数据的访问速度,减轻数据库的负载压力。
红色字体为读流程,蓝色字体为写流程。
二、MySQL分库分表
MySQL分库分表是一种在大规模数据存储和高并发访问场景下的数据库架构设计方法。它将一个大型的数据库拆分成多个小型的数据库(分库),并将每个数据库中的表进一步拆分成多个小表(分表),从而实现数据的水平拆分和分布式存储。
分库分表的主要目的是解决单一数据库在数据量和访问压力增大时的性能瓶颈和扩展性问题。通过将数据分散到多个数据库和表中,可以提高数据库的并发处理能力和查询性能。
1.策略
在MySQL分库分表中,通常采用以下策略:
-
垂直分库:将不同的业务数据存储在不同的数据库中。例如,将用户信息存储在一个数据库中,将订单信息存储在另一个数据库中。这样可以根据业务需求对不同的数据库进行独立的扩展和优化。
-
水平分表:将单个表按照某个规则(如范围、哈希、取模等)拆分成多个小表。例如,将订单表按照订单ID的范围进行拆分,将不同范围的订单存储在不同的表中。这样可以减少单个表的数据量,提高查询性能。
2.需要注意的问题
在进行MySQL分库分表时,有一些需要注意的问题:
-
数据一致性: 分库分表可能导致数据的分散和拆分,需要确保数据在不同数据库和表之间的一致性。在进行跨库事务或跨表查询时,需要考虑数据的一致性处理。在分表场景下,需要确保生成的主键在不同表之间唯一且不重复。可以使用 分布式主键生成算法或者数据库自增主键 来保证主键的唯一性。
-
跨库查询和事务: 在分库分表架构中,跨库查询和跨库事务是常见的需求。需要考虑如何处理跨库查询的性能和复杂性,除了要进行索引优化、查询路由优化等常规优化之外,还要选择合适的分布式事务管理方案。
- XA事务:XA是一种经典的分布式事务协议,它通过两阶段提交(Two-Phase Commit,2PC)协议来实现分布式事务的一致性。XA事务要求所有参与者(包括数据库、消息队列等)都支持XA协议。
- TCC事务:TCC(Try-Confirm-Cancel)是一种补偿型事务模式,它通过在业务逻辑中显式地定义Try、Confirm和Cancel三个阶段来实现分布式事务的一致性。TCC事务适用于对数据一致性要求较高的场景。
- 消息队列事务:一些消息队列中间件(如Apache Kafka、RabbitMQ)提供了事务性消息的支持。通过将事务性操作和消息发送放在同一个事务中,可以实现分布式事务的一致性。
- Saga模式:Saga是一种长事务处理模式,通过将一个大事务拆分为多个小事务,并使用补偿机制来保证事务的一致性。Saga模式适用于业务逻辑复杂、需要长时间执行的场景。
- 基于可靠消息的最终一致性:在一些分布式系统中,通过使用可靠消息队列和事件驱动的方式来实现最终一致性。每个参与者将操作转化为消息发送,并通过订阅和处理消息来实现最终一致性。
选择适合的分布式事务管理方案时,需要考虑业务需求、系统复杂性、性能要求和开发成本等因素。每种方案都有其优缺点,需要根据具体情况进行评估和选择。如果需要更详细的信息,可以使用搜索引擎进行进一步的调研。
- 数据维护: 在分库分表后,可能需要进行数据迁移、回滚、扩容操作。需要考虑如何平滑地将数据从一个数据库或表迁移到另一个数据库或表,并确保数据的完整性和一致性。