一种数据库读写分离解决方案的设计

发布于 2021-01-13 08:45

数据库主从读写分离的开源解决方案很多,特别是开源数据库。实际上,任何数据库经过简单的改造或者设计都可以快速构建主从读写分离的集群。要构建主从读写分离集群,主要要考虑几大要素。
首先,我们的业务是否允许主从读写分离,业务允许的主从库的数据延时是多少。十多年前老白帮助顺丰搞过一个三地三中心的主主三地三活系统,是基于Oracle Streams技术构建的复制环境,业务允许数据复制延时最大是30分钟,当数据复制延时超过30分钟的时候,采用集中式处理的方式,把三地业务全部集中到处理能力最强的数据中心,等复制延时正常时再恢复三地运行。
其次是采用什么样的数据复制技术,逻辑复制还是物理复制。采用逻辑复制技术比较灵活,而且主备库都是正常OPEN状态,可以写入一些临时数据,切换时只需要切换数据库的角色,应用不需要重连。如果采用物理复制,那么在网络、服务器硬件等都健康的情况下复制延时是稳定可靠的,不过备库是只读状态,使用受限,并且备库激活时应用需要能够自动重连。
第三是采用什么样的高可用切换机制,实际上这方面的开源技术也很多,使用的比较多的就是keepalived。
第四是SQL代理网关,这个不是必须项,对于一些小企业,暂时可以不考虑使用SQL代理网关,而对于大企业,最好能从开源产品的基础上开发一个企业自用的SQL代理网关,从而满足企业业务的特殊需要。实际上,一些国产数据库也都有自己的SQL代理网关,2015年我们在做某电力公司的OMS系统异地双活的时候,就是用了达梦的JDBC SQL代理模式,由JDBC的SQL代理自动分发SQL,实现主库写,备库只读的目标。
实际上一个最为简单的主从读写分离环境如下图:
通过SQL拦截器拦截SQL语句,并根据语法判断出该语句是只读还是处于一个写事务中,如果是只读的,可以发往只读从库,如果是写操作,就发往主库。当主库故障时,SQL代理通过预制的自动化工具完成备库数据同步后激活备库,此时只有读操作可以在备库上完成,写操作暂时被挂起,从而保证数据的一致性。等备库数据同步完毕,角色被设置为主库,则写操作也恢复执行。如果从库的数据复制延时超出了业务可忍受的范围,则SQL代理主动暂停往备库的SQL语句发送,所有读写操作都在从库完成。
对于有能力定制化SQL 代理的企业,可以设置一些语法,让开发商能够指定SQL执行的位置。比如有些SQL语句对SQL延时比较敏感的查询语句,也限定只在主库执行,而有些读写事务中的查询语句也可以指定在从库执行。select /* master */就指出该语句只能在主库执行,select /* any */允许在任何节点执行,select /* slave */只允许在slave执行,select /* slave,1 */只能在1号从库上执行。通过这种SQL语句定制,可以让开发商有更大的自主权来主动控制负载的分配。
上面是一个更为复杂的实际案例,这个读写分离集群有三个节点,其中一个主节点,上面部署一个数据库实例,负责读写操作,一个zookeeper实例,一个agent,两个从库上负责读操作,同时这两个节点上部署了一个GW组件,就是SQL PROXY,GW是主从结构,通过keepalived来实现主从切换,float_ip是一个可漂移的虚拟IP,通过keepalived来控制其位置,初始化的时候位于主GW所在节点。所有的客户端都连接float_ip,通过GW来分发SQL语句。每个数据库实例的运行状态和数据复制状态都会定期上报的ZK上,通过对ZK数据的分析可以实时掌握整个集群的运行状态,并根据需要调整GW的运行策略,从而确保在系统运行中遇到各种特殊情况,集群都能自动应对,不需要人工干预。
实际上绝大多数的国产数据库和开源数据库都可以通过这样的改造,使之在可用性,自动化运维能力、负载能力上达到替代Oracle的目的。

本文来自网络或网友投稿,如有侵犯您的权益,请发邮件至:aisoutu@outlook.com 我们将第一时间删除。

相关素材