高并发下的读写分离:

在生产环境高峰期,MySQL主库有很高的写入,这个时候,主从复制可能会有很大的延时。发现总有一些sql在主库写入更新成功,在select查询从库的时候,由于主从复制存在延迟,读取从库的数据和主库不一致,导致业务产生bug。

业务产生bug的原因是因为数据库采用单一的主从异步复制的架构。

异步模式指的是MySQL主服务器上I/O thread 线程将二进制日志写入binlog文件之后就返回客户端结果,不会考虑slave数据库是否完整的同步数据,同样不会考虑二进制日志是否完整传输到从服务器以及是否完整存放到从服务器上的relay日志中,这种模式一旦高并发下或者主服务器宕机,数据就可能产出主从不一致或者可能会发生丢失。

异步模式是一种基于偏移量的主从复制,实现原理是:

主库开启binlog功能并授权从库连接主库,从库通过change master得到主库的相关同步信息然后连接主库进行验证,主库IO线程根据从库slave线程的请求,从 http:// master.info 开始记录的位置点向下开始取信息,同时把取到的位置点和最新的位置与binlog信息一同发给从库IO线程,从库将相关的sql语句存放在relay-log里面,最终从库的sql线程将relay-log里的sql语句应用到从库上,至此整个同步过程完成,之后将是无限重复上述过程。
 

当我们在写代码的时候,需要sql插入数据然后立刻查询出结果做判断。在读写分离的情况下,如果了解到,在运行的生产的数据库存在主从数据延迟,对这种查询可以设置直连主库,也就是说,这种情况下,读也是读取的主库。

下面是ThinkPHP6.0的解决办法:

有些情况下,需要直接从主库读取数据,例如刚写入数据之后,从库数据还没来得及同步完成,你可以使用

Db::name('user')
    ->where('id', 1)
    ->update(['name' => 'thinkphp']);
Db::name('user')
    ->master(true)
    ->find(1);
不过,实际情况远比这个要复杂,因为你并不清楚后续的方法里面是否还存在相关查询操作,这个时候我们可以配置开启数据库的read_master配置参数。

// 开启自动主库读取
'read_master' => true,
开启后,一旦我们对某个数据表进行了写操作,那么当前请求的后续所有对该表的查询都会使用主库读取。

当然这样操作,读写分离就失去了部分意义.

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐