发布时间:2023-01-20 13:30
使用场景:建议一般在读远远多于写,且读的时候一般对数据时效性要求没那么高的时候采用。
从DB了解我们MySQL数据库读写分离使用的是MySQl自带的replication。MySQL自带2种同步方法,一种异步同步方法,另一种是半同步。我们现在使用半同步(DB说)。
半同步:主库写入binlog日志后,就会强制此时立即将数据同步到从库,从库将日志写入自己本地的relay log后,会返回一个ack给主库,主库接收到至少一个从库的ack之后才会认为写操作完成。
MySQL主从同步原理:
Replication是让insert,update,delete及事务操作去主库操作。
Select查询操作走从库。
MySQL的复制是基于binlog的。 MySQL复制包括两部分,IO线程 和 SQL线程。 IO线程主要是用于拉取接收Master传递过来的binlog,并将其写入到relay log。 SQL线程主要负责解析relay log,并应用到slave中 不管怎么说,IO和SQL线程都是单线程的,然后master却是多线程的,所以难免会有延迟。
现在有个大问题读写分离同步时延:
若我们实现读写分离,一个线程执行update修改mysql数据(主库操作),现在主库还没有同步从库。另一个线程进来访问这个数据。造成数据不一致。
我们现在数据库有2种数据,一种是主从数据库不需要实时同步数据,另一种是需要实时同步数据
不需要实时同步数据,则不需要做处理 后期MySQL会自动处理
需要实时同步数据,则需要处理:
办法一:对需要实时同步数据的加事务
办法二:使用中间件对需要实时同步数据做处理,比如sharding-jdbc的HintManager。只要对需要实时同步数据的方法中加HintManager hintManager = HintManager.getInstance(); hintManager.setMasterRouteOnly(); 则可以让其强行读主库。 也可以使用自定义注解封装HintManager。
办法三: DB配置并行复制来进行主从同步。从库开启多个线程,并行读取relay log中不同库的日志(DB手动配置,配置了则一直是多个线程。Db说现在这样配置还没有遇到危害)
办法四:分库 : 将一个主库拆分为4个主库,每个主库的写并发就很小,此时主从延迟可忽略不计。