分表分库原则

        分表分库虽然能解决大表对数据库系统的压力,但它并不是万能的,也有一些不利之处,因此首要问题是,分不分库,分哪些库,什么规则分,分多少分片。

       原则一:能不分就不分,1000 万以内的表,不建议分片,通过合适的索引,读写分离等方式,可以很好的解决性能题。

       原则二:分片数量尽量少,分片尽量均匀分布在多个DataHost 上,因为一个查询 SQL 跨分片越多,则总体性能越差,虽然要好于所有数据在一个分片的结果,只在必要的时候进行扩容,增加分片数量。

       原则三:分片规则需要慎重选择,分片规则的选择,需要考虑数据的增长模式,数据的访问模式,分片关联性问题,以及分片扩容问题,最近的分片策略为范围分片,枚举分片,一致性 Hash分片,这几种分片都有利于扩容。

       原则四:尽量不要在一个事务中的SQL 跨越多个分片,分布式事务一直是个不好处理的问题。

       原则五:查询条件尽量优化,尽量避免Select * 的方式,大量数据结果集下,会消耗大量带宽和CPU 资源,查询尽量避免返回大量结果集,并且尽量为频繁使用的查询语句建立索引。

       这里特别强调一下分片规则的选择问题,如果某个表的数据有明显的时间特征,比如订单、交易记录等,则他们通常比较合适用时间范围分片,因为具有时效性的数据,我们往往关注其近期的数据,查询条件中往往带有时间字段进行过滤,比较好的方案是,当前活跃的数据,采用跨度比较短的时间段进行分片,而历史性的数据,则采用比较长的跨度存储。

      总体上来说,分片的选择是取决于最频繁的查询SQL 的条件,因为不带任何Where 语句的查询SQL,会便利所有的分片,性能相对最差,因此这种 SQL 越多,对系统的影响越大,所以我们要尽量避免这种SQL 的产生。

       如何准确统计和分析当前系统中最频繁的 SQL 呢?有几个简单做法:

- 采用特殊的 JDBC 驱动程序,拦截所有业务 SQL,并写程序进行分析

- 采用 Mycat的 SQL 拦截器机制,写一个插件,拦截所欲 SQL,并进行统计分析

- 打开 MySQL日志,分析统计所有 SQL

      找出每个表最频繁的SQL,分析其查询条件,以及相互的关系,并结合 ER图,就能比较准确的选择每个表的分片策略。

       对于大家经常提起的同库内分表的问题,这里做一些分析和说明,同库内分表,仅仅是单纯的解决了单一表数据过大的问题,由于没有把表的数据分布到不同的机器上,因此对于减轻MySQL 服务器的压力来说,并没有太大的作用,大家还是竞争同一个物理机上的 IO、CPU、网络。此外,库内分表的时候,要修改用户程序发出的SQL,可以想象一下A、B两个表各自分片 5个分表情况下的 Join SQL 会有多么的反人类。这种复杂的 SQL 对于DBA 调优来说,也是个很大的问题。因此,Mycat和一些主流的数据库中间件,都不支持库内分表,但由于MySQL 本身对此有解决方案,所以可以与Mycat 的分库结合,做到最佳效果,下面是 MySQL的分表方案:

  • MySQL 分区;

  • MERGE 表(MERGE 存储引擎)。

       通俗地讲 MySQL分区是将一大表,根据条件分割成若干个小表。mysql5.1 开始支持数据表分区了。 如:某用户表的记录超过了600 万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区。当然也可根据其他的条件分区。

  •  RANGE 分区:基于属于一个给定连续区间的列值,把多行分配给分区,MySQL分区支持的分区规则有以下几种:LIST分区:类似于按 RANGE 分区,区别在于LIST 分区是基于列值匹配一个离散值集合中的某个值来进行选择。

  •  HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含 MySQL 中有效的、产生非负整数值的任何表达式。

  • KEY分区:类似于按 HASH 分区,区别在于KEY分区只支持计算一列或多列,且 MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

       在Mysql 数据库中,Merge 表有点类似于视图,mysql 的 merge引擎类型允许你把许多结构相同的表合并为一个表。之后,你可以执行查询,从多个表返回的结果就像从一个表返回的结果一样。每一个合并的表必须有完全相同表的定义和结构,但只支持只是支持 MyISAM 引擎。

  • Mysql Merge表的优点:

  • 更容易维护大数据集;

  • 查询时可以访问更少的数据;

  • 利用结构接近的的数据来优化查询;

  • 分离静态的和动态的数据。

       在数据量、查询量较大的情况下,不要试图使用Merge 表来达到类似于Oracle的表分区的功能,会很影响性能。我的感觉是和union 几乎等价。

        Mycat建议的方案是 Mycat分库+MySQL 分区,此方案具有以下优势:

  •  充分结合分布式的并行能力和MySQL 分区表的优化;

  •  可以两个维度对表进行分片,MyCAT 一个维度分库,MySQL一个维度分区;

  • 可以灵活的控制表的数据规模。

 

你可能感兴趣的:(数据库)