MySQL Sharding 可能存在的问题
转载:https://blog.csdn.net/michael_kong_nju/article/details/47147403 MySQL Sharding详解
文章写得很好,有条理,简单清晰的介绍了切片的类型和各种实现方案。以下只是摘录和整理对存在问题的分析。
数据切分与整合可能存在的问题
这里,大家应该对数据切分与整合的实施有了一定的认识了,或许很多读者朋友都已经根据各种解决方案各自特性的优劣基本选定了适合于自己应用场景的方案,后面的工作主要就是实施准备了。
在实施数据切分方案之前,有些可能存在的问题我们还是需要做一些分析的。一般来说,我们可能遇到的问题主要会有以下几点:
1、引入分布式事务的问题
一旦数据进行切分被分别存放在多个MySQLServer中之后,不管我们的切分规则设计的多么的完美(实际上并不存在完美的切分规则),都可能造成之前的某些事务所涉及到的数据已经不在同一个MySQLServer中了。
在这样的场景下,如果我们的应用程序仍然按照老的解决方案,那么势必需要引入分布式事务来解决。
而在MySQL各个版本中,只有从MySQL5.0开始以后的各个版本才开始对分布式事务提供支持,而且目前仅有Innodb提供分布式事务支持。
不仅如此,即使我们刚好使用了支持分布式事务的MySQL版本,同时也是使用的Innodb存储引擎,分布式事务本身对于系统资源的消耗就是很大的,性能本身也并不是太高。而且引入分布式事务本身在异常处理方面就会带来较多比较难控制的因素。
怎么办?其实我们可以可以通过一个变通的方法来解决这种问题,首先需要考虑的一件事情就是:是否数据库是唯一一个能够解决事务的地方呢?
其实并不是这样的,我们完全可以结合数据库以及应用程序两者来共同解决。各个数据库解决自己身上的事务,然后通过应用程序来控制多个数据库上面的事务。
也就是说,只要我们愿意,完全可以将一个跨多个数据库的分布式事务分拆成多个仅处于单个数据库上面的小事务,并通过应用程序来总控各个小事务。当然,这样作的要求就是我们的俄应用程序必须要有足够的健壮性,当然也会给应用程序带来一些技术难度。
2、跨节点Join的问题
上面介绍了可能引入分布式事务的问题,现在我们再看看需要跨节点Join的问题。数据切分之后,可能会造成有些老的Join语句无法继续使用,因为Join使用的数据源可能被切分到多个MySQLServer中了。
怎么办?这个问题从MySQL数据库角度来看,如果非得在数据库端来直接解决的话,恐怕只能通过MySQL一种特殊的存储引擎Federated来解决了。
Federated存储引擎是MySQL解决类似于Oracle的DBLink之类问题的解决方案。
和OracleDBLink的主要区别在于Federated会保存一份远端表结构的定义信息在本地。
咋一看,Federated确实是解决跨节点Join非常好的解决方案。但是我们还应该清楚一点,那就似乎如果远端的表结构发生了变更,本地的表定义信息是不会跟着发生相应变化的。
如果在更新远端表结构的时候并没有更新本地的Federated表定义信息,就很可能造成Query运行出错,无法得到正确的结果。
对待这类问题,我还是推荐通过应用程序来进行处理,先在驱动表所在的MySQLServer中取出相应的驱动结果集,然后根据驱动结果集再到被驱动表所在的MySQLServer中取出相应的数据。
可能很多读者朋友会认为这样做对性能会产生一定的影响,是的,确实是会对性能有一定的负面影响,但是除了此法,基本上没有太多其他更好的解决办法了。
而且,由于数据库通过较好的扩展之后,每台MySQLServer的负载就可以得到较好的控制,单纯针对单条Query来说,其响应时间可能比不切分之前要提高一些,所以性能方面所带来的负面影响也并不是太大。更何况,类似于这种需要跨节点Join的需求也并不是太多,相对于总体性能而言,可能也只是很小一部分而已。
所以为了整体性能的考虑,偶尔牺牲那么一点点,其实是值得的,毕竟系统优化本身就是存在很多取舍和平衡的过程。
3、跨节点合并排序分页问题
一旦进行了数据的水平切分之后,可能就并不仅仅只有跨节点Join无法正常运行,有些排序分页的Query语句的数据源可能也会被切分到多个节点,这样造成的直接后果就是这些排序分页Query无法继续正常运行。其实这和跨节点Join是一个道理,数据源存在于多个节点上,要通过一个Query来解决,就和跨节点Join是一样的操作。同样Federated也可以部分解决,当然存在的风险也一样。
还是同样的问题,怎么办?我同样仍然继续建议通过应用程序来解决。(from me:论应用程序的重要性,哈哈。不过深以为然!程序本来就是相互配合的)
如何解决?解决的思路大体上和跨节点Join的解决类似,但是有一点和跨节点Join不太一样,Join很多时候都有一个驱动与被驱动的关系,所以Join本身涉及到的多个表之间的数据读取一般都会存在一个顺序关系。
但是排序分页就不太一样了,排序分页的数据源基本上可以说是一个表(或者一个结果集),本身并不存在一个顺序关系,所以在从多个数据源取数据的过程是完全可以并行的。
这样,排序分页数据的取数效率我们可以做的比跨库Join更高,所以带来的性能损失相对的要更小,在有些情况下可能比在原来未进行数据切分的数据库中效率更高了。
当然,不论是跨节点Join还是跨节点排序分页,都会使我们的应用服务器消耗更多的资源,尤其是内存资源,因为我们在读取访问以及合并结果集的这个过程需要比原来处理更多的数据。
分析到这里,可能很多读者朋友会发现,上面所有的这些问题,我给出的建议基本上都是通过应用程序来解决。大家可能心里开始犯嘀咕了,是不是因为我是DBA,所以就很多事情都扔给应用架构师和开发人员了?
其实完全不是这样,首先应用程序由于其特殊性,可以非常容易做到很好的扩展性,但是数据库就不一样,必须借助很多其他的方式才能做到扩展,而且在这个扩展过程中,很难避免带来有些原来在集中式数据库中可以解决但被切分开成一个数据库集群之后就成为一个难题的情况。
要想让系统整体得到最大限度的扩展,我们只能让应用程序做更多的事情,来解决数据库集群无法较好解决的问题。(from me:应用程序确实可以提供更好的灵活性。)
扩展阅读:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)