springboot based 主从数据源中间件方案

 

 

 

 

 

先定几个原则/目标:git

原则:

1.必须保证数据逻辑的一致性;github

反例:刚写了数据,(由于主从延迟)查询不到;spring

2.对开发人员透明,对业务代码无侵入性;与单数据源的业务代码调用一致;数据库

反例:对已有业务代码的侵入式改动,显示说明datasource;安全

3.根据调用场景自动选择主从数据源app

场景:涉及写入,读写都在主库进行。只涉及查询,从库查询性能

反例:优化

    3.1写事务调用从库spa

    3.2非必要的从主库查询线程

4.给业务开发选择的权利,能够以最低成本的方式显示进行数据源(类别)选择(如annotation等);

场景:只涉及查询,可是业务须要,必须从主库查询;

5.主从数据源共存,与单数据源方案,能够无缝切换

 

扩展目标:

6.低成本的数据源切换线程安全

反例:全局悲观锁,同步锁实现

7.支持多个从库/从库HA

8.主数据库不可用,从库自动顶上

9.代码级别上,采用spring boot starter方案

 

不考虑场景:

sharding 目前不考虑,若是须要,做单独专题展开。

 

备忘问题:

传播级别:

   调用者上下文显示说明MASTER,被调用者显示说明SLAVE; 或反过来,须要一个合理的切换机制/或者不切换;

 

传播性能够作以下规则:

1.若是外层为master,则内层无论原先级别,都将提高至master级别;

2.级别只升不降

3. 同一个线程,若是不切换主从,同一分类的机器,(主要是指多个slave )实例也不切换

4.更多的调用层级,直接递推便可(传播);

 

case:

  • master → slave        =>     master → master
  • master → master      =>     master → master
  • slave   → master       =>     slave → master
  • slave  → slave           =>     slave → slave

 

Master/Slave 切换场景的几种设定:

 

  默认Slave(性能优先) 默认Master(开发效率优先)

若是调用者未显示说明@Master/Slave,根据事务状态自主选择主从;

不在传播链中生成@Master/Slave

若是调用者未显示说明@Master/Slave,根据事务状态自主选择主从;

在传播链中生成@Master/Slave

优势

1.分担主库负担

2.尽量利用从库,从库只读,HA成本低

1.现有代码无任何改动可正常运行

 

1.用户彻底控制,截断了隐性的@Master

2.更多的@Slave场景机会

1.整个传播链行为一致,使得整个数据行为更一致;

缺点

全部现有的服务,涉及到写或者必须连master的场景,必须显示标明@Master;

不然会有两种状况:

1.涉及写入的时候会默认链接到只读从库,程序会报错;

2. 非写入动做,但可能有数据读取的延时性问题

1.须要显示标明@Slave,才能链接从库

2.从库利用率会较低

1.有可能业务逻辑的不一致;

例子:

a.不标明@Master/Slave 的调用上下文先执行了

写操做;

b.而后调用了@Slave 的读操做服务;

a步骤写入的数据,有可能在b操做中读取不出来

 

这种场景,固然能够经过显示标明调用者为
@Master 来规避;

 

1.对事务的状态判断,并不能单方面很好的决定是否选择主从,因此通常会选择主库;(TODO:看是否能更好优化)

2.为了程序运行逻辑不出异常的状况下,而大多选择了@Master,那么接下来的级别都会是@Master,@Slave 的场景会很是少,从库利用率会很低

 

项目地址:

https://github.com/leochowcomtop/db-proxy

相关文章
相关标签/搜索