数据切分与整合可能存在的问题
在实施数据切分方案之前, 有些可能存在的问题我们还是须要做一些分析的.
一般来说, 我们可能遇到的问题主要会有以下几点:
引入分布式事务的问题.
跨节点 Join 的问题;
跨节点合并排序分页问题.
引入分布式事务的问题
一旦数据进行切分被分别存放在多个 MySQLServer 中之后, 无论我们的切分规则设计的多么的完美 (实际上并不存在完美的切分规则), 都可能造成之前的某些事务所涉及到的数据已经不在同一个 MySQLServer 中了.
在这样的场景下, 假设我们的应用程序仍然依照老的解决方式, 那么势必须要引入分布式事务来解决. 分布式事务本身对于系统资源的消耗就是非常大的, 性能本身也并非太高, 并且引入分布式事务本身在异常处理方面就会带来较多比较难控制的因素.
首先须要考虑的一件事情就是: 是否数据库是唯一一个能够解决事务的地方呢? 事实上并非这样的, 我们全然能够结合数据库以及应用程序两者来共同解决. 各个数据库解决自己身上的事务, 然后通过应用程序来控制多个数据库上面的事务. 将一个跨多个数据库的分布式事务分拆成多个仅处于单个数据库上面的小事务, 并通过应用程序来总控各个小事务.
当然, 这样作的要求就是我们的俄应用程序必须要有足够的健壮性. 当然也会给应用程序带来一些技术难度.
跨节点 Join 的问题
上面介绍了可能引入分布式事务的问题, 如今我们再看看须要跨节点 Join 的问题.
数据切分之后可能会造成有些老的 Join 语句无法继续使用. 由于 Join 使用的数据源可能被切分到多个 MySQLServer 中了.
怎么办? 这个问题从 MySQL 数据库角度来看, 假设非得在数据库端来直接解决的话, 恐怕仅仅能通过 MySQL 一种特殊的存储引擎 Federated 来攻克了. Federated 存储引擎是 MySQL 解决相似于 Oracle 的 DBLink 之类问题的解决方式.
和 OracleDBLink 的主要差别在于 Federated 会保存一份远端表结构的定义信息在本地. 咋一看, Federated 确实是解决跨节点 Join 非常好的解决方式. 可是我们还应该清晰一点, 那就似乎假设远端的表结构发生了变更, 本地的表定义信息是不会跟着发生对应变化的. 假设在更新远端表结构的时候并没有更新本地的 Federated 表定义信息. 就非常可能造成 Query 执行出错, 无法得到正确的结果.
对待这类问题, 我还是推荐通过应用程序来进行处理, 先在驱动表所在的 MySQLServer 中取出对应的驱动结果集. 然后依据驱动结果集再到被驱动表所在的 MySQLServer 中取出对应的数据. 可能非常多读者朋友会觉得这样做对性能会产生一定的影响, 是的, 确实是会对性能有一定的负面影响, 可是除了此法, 基本上没有太多其它更好的解决的方法了.
并且, 由于数据库通过较好的扩展之后, 每台 MySQLServer 的负载就能够得到较好的控制. 单纯针对单条 Query 来说, 其响应时间可能比不切分之前要提高一些, 所以性能方面所带来的负面影响也并非太大. 更何况. 相似于这样的须要跨节点 Join 的需求也并非太多. 相对于总体性能而言, 可能也仅仅是非常小一部分而已. 所以为了总体性能的考虑, 偶尔牺牲那么一点点. 事实上是值得的. 毕竟系统优化本身就是存在非常多取舍和平衡的过程.
跨节点合并排序分页问题
一旦进行了数据的水平切分之后, 可能就并不仅仅仅仅有跨节点 Join 无法正常执行, 有些排序分页的 Query 语句的数据源可能也会被切分到多个节点. 这样造成的直接后果就是这些排序分页 Query 无法继续正常执行. 事实上这和跨节点 Join 是一个道理. 数据源存在于多个节点上, 要通过一个 Query 来解决, 就和跨节点 Join 是一样的操作. 相同 Federated 也能够部分解决. 当然存在的风险也一样.
解决的思路大体上和跨节点 Join 的解决相似, 可是有一点和跨节点 Join 不太一样. Join 非常多时候都有一个驱动与被驱动的关系. 所以 Join 本身涉及到的多个表之间的数据读取一般都会存在一个顺序关系. 可是排序分页就不太一样了, 排序分页的数据源基本上能够说是一个表 (或者一个结果集). 本身并不存在一个顺序关系, 所以在从多个数据源取数据的过程是全然能够并行的.
这样排序分页数据的取数效率我们能够做的比跨库 Join 更高. 所以带来的性能损失相对的要更小, 在有些情况下可能比在原来未进行数据切分的数据库中效率更高了.
小结
当然, 不论是跨节点 Join 还是跨节点排序分页. 都会使我们的应用 server 消耗很多其它的资源, 尤其是内存资源, 由于我们在读取访问以及合并结果集的这个过程须要比原来处理很多其它的数据.
事实上全然不是这样, 首先应用程序由于其特殊性. 能够非常容易做到非常好的扩展性, 可是数据库就不一样. 必须借助非常多其它的方式才干做到扩展. 并且在这个扩展过程中, 非常难避免带来有些原来在集中式数据库中能够解决但被切分开成一个数据库集群之后就成为一个难题的情况.
要想让系统总体得到最大限度的扩展, 我们仅仅能让应用程序做很多其它的事情来解决数据库集群无法较好解决的问题.
来源: http://www.jianshu.com/p/1122539df82f