mysql分布式性能优化

上面已经介绍了主从的方式,在这里完善一下。

主从分布的优点是实现了备份和读写分离,master只需要专门负责写操作,读操作交给slave来执行,然后主从数据库通过bin_log来异步更新,当然这样也会有一个数据不同步的情况,那可以改成同步的吗?当然,mysql有一个半同步的方式,当写请求来到master上之后,必须保证至少一台slave更新了数据,才会返回写成功的信号,当然这种情况下,对于效率会有一些破坏,所以一般例如支付场景之类的必须保证数据的可以用这种方式。对于数据不是那么敏感的不需要用这种方式。

多主多从

对于上面的单主单从的方式,只是分散了读写的压力,但是针对写并没有做什么优化,于是有了多主多从。

多从比较好理解,多主其实就是数据分片的概念,一条数据只会在一个主机中。

如何进行数据分片?我们可以采用hash+mode分片。当有多台master的时候,传来一个insert命令,那么我们需要有一层来决定路由到哪个master上。举个例子:我们需要确定用哪个字段来分片,例如id,我们可以对id进行hash(数字格式的也可以不做),用生成的字符串最后一位进行取模,例如有2台,那么就取模2,得出的数就对应那台master。自然的,读请求也是hash+mode的方式来决定是哪台master。

接下来说一下分片的维度,也就是根据什么样的规则进行分片。我们之所以做分库分表,就是为了减缓插入和查询的压力,但如果一次请求涉及到了多个库,且不说查询一致性,单说查询的消耗,需要横跨多个数据库的节点,那显然是不划算的。因此对于分片的原则,就是一次请求尽可能全部命中在一个数据库上。基于这个原则,我们有两个维度:固定路由位、时间自增分片。固定路由位就是我们上面说的,根据id去取模然后路由到不同的节点上。对于时间自增,顾名思义,例如每隔一年放到一个库中。

另外还有一个概念就是数据分片冗余。举个例子,一个用户查自己的一些记录,那么根据id就可以定位到相对的路由位上进行查询,而如果是一个商户,那么他的用户可能在不同的分片上,那么他就需要横跨所有的路由位来进行查询,这个情况我们就需要做数据分片的冗余。

上图中,当请求发送一个insert后,master1以user id记录到这条数据,同时通过MQ发送一条消息给另一个应用中,应用受到该消息后以business id的方式存到master2中,这样当用户查询的时候,就去查master1,商户查就查master2即可。当然也可以不用MQ,用bin_log,当然肯定不会有MQ好。

接下来说说分库的扩展,一旦拓展库以后,相对的mode的hash也会发生变化,这也就需要我们进行数据迁移,那么对于数据迁移,我们有几种方案:mod位数据迁移、弹性自增。重点讲一下弹性自增,老数据不变,新数据放到别的库中,例如上图master1需要发生扩展,那么我们访问的时候可以以时间为条件进行路由,例如2019年的都只访问master1,2020年和之后的用新的路由算法进行路由。

最后说一下一致性原理,在单机状态下,mysql遵从acid,自然不用担心一致性,但在分布式环境下,一致性就变的非常需要注意了。对于一致性可以分为:强一致性、弱一致性、最终一致性。强一致性:数据库(或集群)对外是完完全全一致的,最典型的就是acid的事务,要么全部成功,要么全部失败。弱一致性:例如上图,通过MQ进行同步,那么难免会有master1和master2库不一致的时候,这就是弱一致性。最终一致性:还是上图,尽管master12的数据会有不同步的情况,但是由于MQ的事务性消息,最终终会一致,这就是最终一致性。那如果我想进行强一致性怎么做?二阶段提交,牺牲可用性来保证。

在分布式的情况下,我们不追求ACID,而是追求cap理论(c:一致性,a:可用性,p:分片性)。在分布式的环境下,c和a只可得两者,不可得三者。这也就衍生出了base理论(basic avaliable:基本可用,s:软状态(瞬时状态,例如上图用户下单,用户可看到,商户看不到时),e:最终一致性)。

发布了97 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/haozi_rou/article/details/105201582
今日推荐