如何扩展MySQL

本文详细介绍了MySQL的扩展方法,包括提升硬件、读写分离、垂直拆分、数据分片等策略。数据分片涉及到分区键选择、跨分片查询和分配策略,如固定分配、动态分配等。此外,还讨论了归档存储、多实例扩展以及集群扩展,以应对不同场景下的性能需求和数据规模挑战。

一、什么是可扩展性

单台MySQL的服务能力终归是有限的,当单台机器服务不过来时,就需要对MySQL进行扩展。高性能mysql中对可扩展性的定义:可扩展性是当增加资源以处理负载和增加容量时系统能够获得的投资产出率。也就是说想要提升同等的性能,需要投入相应数据量的资源,越到后面,提升性能的性价比越低。在不同的场景下,选择最合适的扩展方案,能够获得更大的性价比。下文将介绍几种常见的扩展思路。

二、提升硬件

单节点扩展意味着购买更加强悍的硬件设备,以提高该机器上运行的软件的性能,更多更好的CPU,更大的内存,更快的硬盘。在一般数据量比较小的情况下,这是一个不错的选择。单台服务器更好维护和开发,降低系统的复杂性。但是如果确定知道数据量规模庞大,必定不可能以单台服务器去承载的,那么不应该浪费大量精力和财力在垂直扩展上,而应该提前做好集群规划。

三、读写分离

通过MySQL的复制,将主库上的数据同步到从库,主库承担所有的写请求,由从库去承担读请求,达到读写分离,可以根据读请求的量级来配置从库的数量。满足如下三个条件的场景可以考虑用读写分离:第一、数据规模有限,单台服务器能够容纳。第二、读多写少,读写分离不能扩展写操作,如果写操作过多,数据同步会有压力。第三、对读一致性要求不高,能够容忍一定的延时。对于某些场景下的业务数据,可以让写之后一小段时间的查询走主库查。比如用户对一部电影的评论,用户发表评论后,用户本身关心能否立即看到评论。但是其余用户并不需要立刻看到该用户的评论。

四、垂直拆分

这里的垂直拆分其实和应用层的服务拆分是一个意思,服务拆分必定会拆数据库,拆数据库并不一定是服务拆分。按照职责,将一定功能范围的库拆成独立的节点。比如,用户数据与商品数据拆成独立的数据库实例。还有一种读写分离后的拆分,其实就是有多个从库,不同职责读不同的数据库,可以更好的利用缓存,并且各类型的查询之间互不影响。比如OLAP,一般查询会很大,并且比较慢,将其单独走一个从库会更好。

五、数据分片

如果只有一个主库,不管有多少备库都不会对写请求有任何的帮助。在超大型数据量的应用中,数据分片是首选解决方案。数据分片通常会有一个数据访问层,用以降低应用和分片数据之间的通信的复杂度。数据分片会面临几个不可回避的问题,如下。

1.分区键的选择

既然数据要分片,那么得有一个分片规则,以什么标准来分片,这就涉及分区键的选择。分区键的选择很重要,数据的分布以及查询,都和分区键密切相关。分区键通常是一个实体的主键。选择分区间的时候,尽可能选择那些能够避免跨分片查询的,并且能够小粒度的进行分片。比如用户id,一般通过用户id分片,并且查询也都是通过用户id查询,通过用户id能直接定位到数据在哪个分片。

2.跨分片查询

数据分片之后大多数场景都应该是通过分区键去查询数据,这样更加的高效。但是也难免有全局查询到的情况。在数据访问层,作一定的封装。有两种思路去解决这个问题:第一、并行向所有的分片发出请求,将结果合并然后返回。elasticsearch就是这么做的。第二、根据查询条件建立一张索引表,记录数据所在的分片,先查索引表,在查数据分片表。第三、提取数据作全局缓存。如果一个高频查询,查询的是部分的字段,单节点能够容纳,可以考虑这么做,绕开了跨分片查询这个问题,但是它会导致更新的复杂度升高。

3.分片与节点的对应关系

分片与节点的对应关系不一定是一对一的关系,应该尽可能让分片的大小比节点容量小很多。这样就可以在单个节点上存储多个分片。如果分片太大,就很难通过移动分片来平衡容量,就可能涉及重新分片。分片小,可以通过移动分片来平衡容量。移动分片比重新分片更加简单。
还需要考虑分片如何部署的问题,一个mysql实例上可以放一个库一个分片,也可以放多个库多个分片。一般倾向于使用每个分片一个数据库的方式,并且把分片号写在数据库名和表名中。

4.分配策略

a.固定分配

固定分配使用的分区函数仅仅依赖于分区键的只。比如通过哈希和取模,当需要插入一个用户时,根据用户id进行哈希,再根据分片总数取模,就能定位到插入的分片。当查询用户信息时,同样的过程,先哈希,再取模,得到数据所在分片,然后到对应的分片上查询。这种方式有一些缺陷:第一、如果分片很大,且数量不懂,就很难平衡不同分片之间的负载。
第二、无法自定义哪些数据放在哪个分片上。第三、修改分片策略很困难,涉及不同分片之间的数据迁移。

b.动态分配

动态分配是建立一张表,存储分区键与分片号之间的关系。这个表本身就相当于一个分区函数。插入数据时在这里新增一条记录,查询数据时先查这张表,拿到分片号再查分片数据。由于只存储了分区键和分片号,可以考虑将整个表做全局缓存。这种方式的优势在于可以更加灵活的控制分片,均衡分片之间的负载。还可以根据一定的策略将亲和性比较强的数据放在一起,这样就可以减少跨分片查询。比如同一篇文章的评论,放在一个分片上,肯定是利于查询的。如果仅仅用评论id做哈希和取模,那么查询一篇文章的评论就得跨分片查询了。动态分配的缺点在于需要多增加一次查询。

c.混合固定与动态

如果分区键太大,可以先对分区键做哈希,固定分配,然后在通过动态分配映射到分片上。

e.显示分配

显示分配是在应用插入新的数据时,显示的选择分片,并且将数据分片号编码到id中。比如创建一个用户,id为345,分片号为8。id采用bigint保存,可以用前8个bit用来保存分片号,那么最终的id是345 << (64 - 8) + 345。显示分配的优点在于可以减少一次网络请求。显示分配可以和固定分配与动态分配相结合,相当于将动态分配这张表放到了每一个id中。
在这么多分配方式中,最常用的是动态分配,合理利用显示分配,也是一个不错的选择。

5.分布式ID

数据做了分片后就不能使用自增主键作为数据的唯一标识了,因为多个分片之间会出现id重叠。这时候就需要用到分布式id。详见 分布式ID策略

六、归档存储

根据数据特性,可以将不再需要的数据进行归档和清理,给数据瘦身。这可以作为处理大数据量的一种思路,在一些场景下适用,但并不能替代数据分片。归档是一种冷热隔离的思想,将两者分开,把更多的资源分配给少量的热点数据,以提升整体性能。归档有如下注意事项。
1.归档不应对应用本身有影响
归档需要查询出不需要的数据,保存到别处,并在原表中删除。这些操作应该悄悄的发生,不能产生很大动作,对应用本身产生影响。从一个高负载的OLTP中归档,可以小批量的查询,小批量的删除,并且归档任务要尽可能的给事务让步。
2.数据一致性
归档数据可能涉及多个表,归档时要按照一定的逻辑顺序进行归档,否则出现归档时数据不一致。
3.避免数据丢失
从原表中删除数据时,确保目标机器上已经保存了数据。

七、多实例扩展

当硬件性能提升到一定程度,单个mysql实例并不能完全利用硬件资源。可以在一台性能强悍的机器上运行多个mysql实例,以发挥高性能机器的处理能力。

八、集群扩展

理想的方案是单一逻辑数据库能够容纳所有的数据,处理更多的查询,从而避免客户端来做数据分片。MySQL作为一个整体的集群对外提供统一的服务,实现自动扩容,而不用客户端处理,应用层所看到的就是一个逻辑上完整的MySQL。MySQL Cluster还有其他很多技术正在朝这个方向迈进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值