首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > Mysql >

扩充MySQL

2013-09-28 
扩展MySQL一、概述构建高可扩展系统的重要原则:在系统内尽量避免串行化和交互。如果将应用所有的数据简单地

扩展MySQL

一、概述

构建高可扩展系统的重要原则:在系统内尽量避免串行化和交互。

如果将应用所有的数据简单地放到单个MySQL服务器实例上,则无法很好的扩展,迟早会碰到性能瓶颈。传统的方法是购买更多强悍的机器,也就是常说的“垂直扩展”或“向上扩展”。另一个方法是将任务分配到多台计算机上,这通常被称为“水平扩展”或“向外扩展”,最后,大部分应用还会有一些很少或者从不需要的数据,这些数据可以被清理或归档。这个方法称为“向内扩展”。

?

二、规划可扩展性

考虑以下问题,帮助规划可扩展性:

    应用的功能完成了多少?预期的最大负载时多少?如果依赖系统的每个部分来分担负载,在某个部分失效时会发生什么?

    为扩展赢得时间:

    在扩展之前可以先优化性能。

    比如更换高性能存储引擎、创建高性能索引、优化查询性能、优化服务器配置、优化操作系统和硬件等。

    ?

    三、扩展

    1、向上扩展

    建议使用MySQL5.5或更新的版本,或者Percona Server5.1及后续版本。当前合理的“收益递减点”的机器配置大约是256GB RAM,32核CPU以及一个PCIE flash驱动器。

    用更高配置的机器,MySQL的性能也提升不了多少了。

    ?

    2、向外扩展

    向外扩展策略划分为三个部分:复制、拆分、以及数据分片。

    ?

    2.1、复制

    最简单也最常见的向外扩展的方法是通过复制将数据分发到多个服务器上,然后将备库用于读查询。这种技术对于以读为主的应用很有效。

    ?

    2.2、按功能拆分

    将独立的服务器或节点分配给不同的应用,这样每个节点只包含它的特定应用所需要的数据。

    如门户网站常常把把不同的栏目放在一起,可以浏览网站新闻、论坛,寻求支持和访问知识库等,这些不同功能区域的数据可以放到专用的MySQL服务器中。

    这种分布数据的方法并不高效,不能通过功能划分来无限地进行扩展。

    ?

    2.3、数据分片

    目前用于大型MySQL应用的方案中,数据分片是最通用且最成功的方法。

    很难将应用从单一数据存储转化为分片架构。如果在应用设计初期就已经预计到分片,那实现起来就容易的多。

    分片数据存储看起来是优雅的解决方案,但很难实现。如非必要,尽量不分片。如果想扩展写容量,就必须切分数据。

    ?

    2.3.1、选择分区键

    我们目标是对那些最重要并且频繁查询的数据减少分片。这其中最重要的是如何为数据选择一个活多个分区键。分区键决定了每一个分配到哪一个分片中。确定分区键一个比较好的办法是用实体-关系图,或一个等效的能显示所有实体及其关系的工具来展示数据模型。尽量把关联的实体靠的更近。

    选择分区键的时候,尽可能选择那些能够皮面分片查询的,但同时也要让分片足够小。如果可能应该期望分片尽可能同样小,这样在为不同数量的分片进行分组时能够很容易平衡。
    应用拥有多个分区键,特别是存在两个货更多“维度”的时候,某些数据在系统内至少需要存储两份,但这并不意味着需要去设计两个完全冗余的数据存储,可以存储两份记录主键和分区键,其他内容通过再查询获取。

    ?

    2.3.2、跨分片查询

    大多数分片应用多少都有一些查询需要对多个分片的数据进行聚合或关联操作。一条跨分片查询实际上需要拆分成多条并行执行的查询,每个没偏上执行一条。一个设计良好的数据库抽象层能够减轻这个问题,但类似的查询仍然会比分片内查询要慢并且梗加昂贵,所以通常会更加依赖缓存。

    跨分片查询也可以借助汇总表来执行。

    未分片的数据通常存储在全局节点中,可以使用缓存来分担负载。

    跨分片查询并不是数据分片面临的唯一难题,维护数据一致性同样困难。

    ?

    2.3.3、分配数据、分片和节点

    分片和节点不一定是一对一的关系,应该尽可能地让分片的大小比节点容量小很多,这样就可以在单个节点上存储多个分片。保持分片足够小更容易管理,这将使数据的备份和恢复更加容易,如果表很小,那么像更改表结构这样的v奥做回更加容易。小一点的分片也便于转移。

    我们说“易于管理的大小”是指保持表足够小,以便能在5或10分钟内提供日常的维护工作,如ALTER TABLE、CHECK TABLE或者OPTIMIZE TABLE。

    如果将分片设置的太小,会产生太多表,这可能引发文件系统或MySQL内部结构的问题。另外太小的分片还会导致跨分片查询增多。

    ?

    2.3.4、在节点上部署分片

    在节点上部署分片通常有一些办法,推荐使用每个分片一个数据库的方式,并把分片号卸载数据库名和表明中。如:bookclub_23.comments_23。

    这样会增加例如ALERT TABLE这类操作的负责杜,但也有一些优点:

      如果分片全部在一个数据库中,转移分片会比较容易。因为数据库本身是文件系统中的一个目录,所以可以很方便的管理一个分片的文件。如果分片互不关联,则很容易查看分片的大小。全局唯一表明可避免误操作。

      ?

      3.3.5、分配

      将数据分配到分片中有两种主要的方法:固定分配和动态分配。还有一种是混合分配。

      固定分配:

      固定分配使用的分区函数仅仅依赖于分区键的值。哈希函数和取模运算就是很好的例子。

      固定分配的优点是简单,开销低,甚至可以在应用中直接硬编码。

      它的缺点是如果分片很大并且数量不多,就很难平衡不同分片间的负载;固定分片的方式无法自定义数据放到哪个分片上;修改分片策略比较困难。

      我们倾向于为新应用选择动态分配方式,但如果是为已有的应用做分片,使用固定分配策略可能会更容易些。

      动态分配:

      将每个数据单元映射到一个分片。假设有一个有两列的表,包括用户ID和分片ID。

      CREATE TABLE user_to_shard (

      ? ? user_id INT NOT NULL,

      ? ? shard_id INT NOT NULL,

      ? ? PRIMARY KEY (user_id)

      );

      这个表本身就是分区函数。

      更普遍地,直接向USERS表中增加一个shard_id列用于存储分片号。

      动态分配的最大好处是可以对数据存储位置做细粒度的控制。这使得均衡分配数据到分片更加容易,并可提供适应未知改变的灵活性。

      ?

      2.3.6、生成全局唯一ID

      在做分片存储时,经常需要在多台机器上生成全局唯一ID。以下几种方法可以解决这个问题:

        使用auto_increment_increment和auto_icrement_offset

        这个方法简单,并不依赖某个节点,但这需要非常仔细的卑职服务器。

          全局节点中创建表

          在一个全局数据库节点中穿件一个包含AUTO_INCREMENT列的表,应用可以通过这个表生成唯一数字。

            使用memcached

            使用memcached中的incr()函数,可以自动增长一个数字并返回结果。

              批量分配数字

              应用可以从一个全局节点中请求一批数字,用完后再申请。

                使用复合值

                可以使用一个复合值来做唯一ID。

                  使用GUID值

                  ?可以使用UUID()(或UUID_SHORT())函数来生成全局唯一值。

                  ?

                  如果使用全局分配器来产生唯一ID,要注意皮面单点征用称为应用的性能瓶颈。

                  ?

                  2.3.7、分片工具

                  如果没有任何抽象层,直接让应用访问多个数据源,那绝对是一个很差的设计。这个抽象层主要完成以下任务:

                  连接到正确的分片并执行查询。

                  分布式一致性校验。

                  跨分片结果集聚合。

                  跨分片关联操作。

                  缩合事务管理。

                  创建新的数据分片(或者至少在运行时找到新分片)并重新平衡分片。

                  ?

                  Hibernate Shards(http://shards.hibernate.org)是一个支持分片的数据库抽象层。另一个基于Java的分片系统是HiveDB(http://www.hivedb.org)。

                  ?

                  2.4、通过多实例扩展

                  每台服务器上运行过个实例,然后划分服务器的硬件资源,将其分配给每个实例。在一台性能强悍的硬件上可以获得10倍到15倍的合并系数。你需要平衡管理复杂度代价和更有性能的收益。

                  ?

                  2.5、通过集群扩展

                  未来典型的集群数据库可能更像是SQL和NoSQL的混合体,有多重存取机制来满足不同的使用需求。

                    MySQL Cluster(NDB Cluster)?

                    MySQL Cluster是两项技术的结合:NDB数据库,以及作为SQL前端的MySQL存储引擎。NDB是一个分布式、具备容错性、非共享的数据库,提供同步复制以及节点间的数据自动分片。

                    ?

                      Clustrix

                      Clustrix(http://www.clustrix.com)是一个分布式数据库。支持MySQL协议,它可以之际替代MySQL。它是一个无安全支持ACID,支持MVCC的事务型数据库,主要用于OLTP负载场景。

                      ?

                      其他集群数据库:ScaleBase(http://www.scalebase.com)、GenineDB(http://www.geniedb.com)、Akiban(http://www.akiban.com)、NuoDB(http://www.nuodb.com)


                      3、向内扩展

                      处理不断增长的数据和负载最简单的办法是对不再需要的数据进行归档和清理。这种做法并不用来代替其他策略,但可以作为争取时间的短期策略,也可以作为处理大数据量的长期计划之一。

                      做归档和清理时考虑以下几点:

                      对应用的影响要归档的行维护数据一致性避免数据丢失解除归档

                      保持活跃数据独立,即使不真的把老数据转移到别的服务器,也许应用也能受益于活跃数据和飞活跃数据的隔离。可以有一下集中做法:

                      将表划分为几个部分MySQL分区基于时间的数据分区

                      ?

                      四、总结

                      在MySQL扩展策略方面,典型的应用在增长到非常庞大时,通常先从单个服务器转移到向外扩展的拥有读备库的架构,再带数据分片和(或)按功能分区。我们并不同意那些提倡为每个应用“尽早分片,尽量分片”(shard early, shard often)的建议。这很复杂且代价昂贵,并且许多应用可能根本不需要。可以花一些时间去看看新的硬件和新版本的MySQL有那些变化,或者MySQL Cluster有哪些新的进展,甚至去评估一些专门的系统,如Clustrix。

热点排行