上节中将,Redis如何存储一些与用户关系不大的系统,效果特别好。因为这些系统中,每个人看到的内容都是一样的。缓存命中率非常高,没有多少请求能穿透到MySQL。

但是和用户相关的系统,缓存就没那么好了。比如订单系统,账户系统,购物车系统。这些系统查询的信息,都是和用户息息相关的。缓存命中率就不是很高了。

那么怎么办呢?

读写分离提升MySQL并发的首选方案

一个简单而且非常有效的方案是,我们不对数据分片,而是使用多个具有相同数据的 MySQL 实例来分担大量的查询请求,这种方法通常称为“读写分离”。

读写比一般都在几十左右,平均每发生几十次查询请求,才有一次更新请求。换句话来说,数据库需要应对的绝大部分请求都是只读查询请求。

一个分布式的存储系统,想要做分布式写是非常非常困难的,因为很难解决好数据一致性的问题。但实现分布式读就相对简单很多,我只需要增加一些只读的实例,只要能够把数据实时的同步到这些只读实例上,保证这这些只读实例上的数据都随时一样,这些只读的实例就可以分担大量的查询请求。

读写分离的另外一个好处是,实现简单,只需要修改DAO代码,把对数据库的读写请求分开,请求不同的MySQL实例就好了。

image.png

实施读写问题,需要做两步:

  1. 部署一主多从MySQL示例,并让他们之间保持数据实时同步
  2. 分离请求程序的读写请求,分别发送给从库和主库

分离请求程序的读写请求,有三种方法:

  1. 纯手工,修改DAO层,定义两个数据源,读写数据库时指定数据源
  2. 组件方式:例如使用sharding-JDBC,将组件集成在应用程序中,代理数据库请求,自动请求路由到对应的数据库实例上。
  3. 代理方式:在应用程序和数据库示例之间部署代理示例,比如Atlas或者MaxScale。代理分离读写请求,转发的对应数据库实例中。