Skip to content

Zebra读写分离介绍

junior_xin edited this page Dec 5, 2018 · 5 revisions

1 读写分离介绍

在单台mysql实例的情况下,所有的读写操作都集中在这一个实例上。当读压力太大,单台mysql实例扛不住时,此时DBA一般会将数据库配置成集群,一个master(主库),多个slave(从库),master将数据通过binlog的方式同步给slave,可以将slave节点的数据理解为master节点数据的全量备份。关于如何配置mysql主从同步,可以参考mysql官方文档:https://dev.mysql.com/doc/refman/5.7/en/replication.html

从应用的角度来说,需要对读(select、show、explain等)、写(insert、update、delete等)操作进行区分。如果是写操作,就走主库,主库会将数据同步给从库;之后有读操作,就走从库,从多个slave中选择一个,查询数据。上述流程如下图所示:

2 读写分离优点

  1. 避免单点故障
  2. 负载均衡,读能力水平扩展。通过配置多个slave节点,可以有效的避免过大的访问量对单个库造成的压力。

3 读写分离挑战

  1. 对sql类型进行判断。如果是select等读请求,就走从库,如果是insert、update、delete等写请求,就走主库。
  2. 主从数据同步延迟问题。因为数据是从master节点通过网络同步给多个slave节点,因此必然存在延迟。因此有可能出现我们在master节点中已经插入了数据,但是从slave节点却读取不到的问题。对于一些强一致性的业务场景,要求插入后必须能读取到,因此对于这种情况,我们需要提供一种方式,让读请求也可以走主库,而主库上的数据必然是最新的。
  3. 事务问题。如果一个事务中同时包含了读请求(如select)和写请求(如insert),如果读请求走从库,写请求走主库,由于跨了多个库,那么jdbc本地事务已经无法控制,属于分布式事务的范畴。而分布式事务非常复杂且效率较低。因此对于读写分离,目前主流的做法是,事务中的所有sql统一都走主库,由于只涉及到一个库,jdbc本地事务就可以搞定。
  4. 高可用问题。主要包括:
    • 新增slave节点:如果新增slave节点,应用应该感知到,可以将读请求转发到新的slave节点上。
    • slave宕机或下线:如果其中某个slave节点挂了/或者下线了,应该对其进行隔离,那么之后的读请求,应用将其转发到正常工作的slave节点上。
    • master宕机:需要进行主从切换,将其中某个slave提升为master,应用之后将写操作转到新的master节点上。

4 zebra与读写分离

zebra提供了GroupDataSource来完成读写分离功能,解决了上述所有问题,且对业务方透明。开发人员可以像操作单个库那样,去访问mysql数据库集群,底层细节完全由zebra屏蔽。GroupDataSource还额外提供了就近路由、限流等多种功能。

  关于zebra读写分离功能的实现,请参考:主流数据库中间件设计方式

  关于读写分离功能接入,请参考:Zebra读写分离接入指南

  关于分库分表的基础知识,请参考:Zebra分库分表接入指南

Clone this wiki locally