MySQL Proxy整体架构说明

背景

众所周知,MySQL数据库因为其具备一些优秀的特性,被大量互联网公司使用。优秀的功能,活跃的社区,丰富的工具等等,但最重要的一点莫过于在其诞生超过20年的时间里,众多企业应的应用对其功能和稳定性进行了充分的验证,使得它成为互联网企业关系型数据存储的首选。但也正因为这样的历史,mysql包含了过多传统IT产品的特点,单机的可用性受到质疑,单机的容量受到限制,无法动态变更容量等等。

目前,阿里巴巴,京东,360等等大公司因为业务需求,各自在mysql之上构建了一套数据库代理层,以支持自身海量关系型数据存储的需求,并且在提高数据库稳定性的同时,降低数据运维的成本,其中阿里巴巴还其产品化并在阿里云上直接提供分布式关系型数据库服务。

笔者在关系型数据存储有几年的经验,现在结合当前一些开源系统的设计,对分布式关系型数据存储的架构做一个说明,并且对几个核心模块的逻辑做一些基本的介绍。

目的

统一数据库运维

MySQL Proxy构建在业务服务器和数据库中间,代理业务的数据访问请求。运维人员通过proxy配置的修改,达到在不影响应用的前提下,变更存储节点的目的。

提高可用性

MySQL Proxy后端连接多个mysql存储节点,能够在多个数据节点之间做负载均衡和容灾切换,相比原始的应用和数据库一对一直连的方式,能有效提高数据访问的可用性。

提高数据存储上限以及访问性能

可以在proxy上构建分库分表逻辑,达到在业务系统无感知的情况下,将原本单个数据节点承担的请求,分散到多个节点,在突破单个节点存储限制的同时,提升数据库访问的性能。

整体的系统设计

mysql_proxy_architecture_new.png?raw=true

黄色的框框表示现有的服务,包括
  • 应用服务器,可能使用不同编程语言编写,使用mysql提供的客户端lib库发起数据库访问请求。
  • mysql数据库,负责最终业务数据的存储,并接受来自proxy的数据请求。
蓝色的框框表示需要构建的服务,包括
  • proxy,以mysql协议对外提供服务,代理业务的mysql数据库请求。将数据库请求做一定处理之后,发送负责存储数据的mysql数据库节点,并将返回值合并后返回调用者。针对proxy的处理逻辑,后续会有详细说明。
  • config server,保存了所有数据库节点信息以及应用的数据拓扑元信息。该系统直接面向配置需求者的服务,负责在关联系统启动时为其提供所需要的配置信息,并且在配置发生变更时,主动将最新的配置发送到关联系统。
  • config manager,这是一个控制台系统,为运维人员和系统管理员提供配置查看和修改的入口,进一步地,它为其他系统提供配置查询和变更的API,主要针对自动化运维的需求。
  • topology server,它是一个数据库元信息的管理服务,它在config的配置之上做了一层封装,可以方便地查看和管理各个应用当前的数据拓扑结构,更进一步地,使用它提供的SDK,某个应用的数据拓扑可以被其他关联应用直接查询,并且在该应用的数据拓扑发生变化时,将变更情况及时通知到其他关联系统。这样的业务场景其实比较多,比如某个应用的数据每天定期地同步到数据仓库做数据分析,这个同步操作是由另一个数据同步系统负责去做的,那么如果这个应用做了数据库迁移或者扩容,为了保证数据同步正常,数据同步系统就需要及时知道这个应用新的数据库地址或者扩容后新的拓扑。
  • transfer server,数据库在运行过程中可能遇到磁盘损坏,机器硬件性能达到瓶颈等等问题,这时候通常的解决方案是换一台性能更好更稳定的机器来存储。另一种情况是,因为业务持续不断发展,当前的数据存储节点达到性能瓶颈,这时候需要进行扩容,比如需要从8台机器一共32张表扩展到16台机器128张表。以上两种情况,产生的需求就是在不影响在线应用的前提下,完成数据的一对一迁移或者一对多扩容,transfer就是为了应对这样一类需求而产生的系统。
  • event server,应用中经常加入消息系统来达到系统解耦的目的,通常做法是在业务完成时将消息发送出去,或者进一步地,通过消息的两阶段提交和状态回查保证事件消息发送出去。不论以上哪种做法,应用产生了对消息系统的依赖以及些许影响了性能。event server是一类特殊的消息系统或者消息源系统,通过对数据库二进制日志实时读取并分析,得到数据变更的事件,进一步地,以消息的形式,通知到所有关注该类消息的系统。该系统进一步降低应用系统的依赖,并且提升应用系统业务逻辑的性能(减少了发消息的步骤)。
  • monitor服务,监控以上除了应用服务器以外的所有服务。利用monitor实现故障的发现,告警以及自动化切换。

config服务

config server

保存所有数据库信息以及应用的拓扑结构信息:

  • 所有数据库地址信息,包括ip,端口,数据库名称
  • 所有数据库连接信息,包括数据库用户密码,连接参数,连接池配置
  • 所有应用的拓扑信息,包括主备关系,分库分表拓扑
  • 所有鉴权信息,包括应用方使用proxy的用户名和密码信息
  • proxy部署配置,包括哪个proxy提供哪个应用的服务

需要具备以下2个核心功能:

  • 在proxy以及其他配置需求者启动时,向其提供所需要的配置内容
  • 在配置变更时,主动通知到配置需求者,并推送最新配置
config manager

是config server的运维平台,能够对存放在config server上的配置进行增删改查,是所有配置的统一运维入口。

proxy服务

权限控制
  • 包括应用和proxy通信创建连接的认证逻辑以及执行SQL需要的权限控制,具体在执行控制部分介绍。
资源控制
  • 控制应用方连到proxy的连接数量,拒绝一些超出负载的连接创建请求,以保证proxy提供稳定的服务。
  • 控制proxy到mysql的连接数量,可以直接使用连接池技术,在控制总的连接数同时,保证连接复用,提高访问性能。
执行控制
  • 协议解析

    协议解析就是识别一串的字符信息,区分消息头、消息体,进一步地,识别消息体的具体内容,获取请求参数和响应参数等等。
    协议解析最主要的输出是还原用户输入的SQL。

  • 权限控制

    在应用方创建连接时,识别应用方身份,判断其是否有权创建连接。mysql规范中,连接创建时,会将用户名和密码传递到服务端,因此需要在服务端做身份识别和权限范围控制。
    运行时,对SQL权限做进一步控制,比如DDL权限和DML权限,只读还是可修改等。权限控制的输出结果是本次请求是否被接受。

  • SQL解析

    包括词法解析,语法解析,语义解析,基本就是编译原理那一套。SQL本质上就是用户用一个字符串表达自己想对数据做的操作,这里又把这个字符串做了下翻译,用数据结构来表示操作语义。
    SQL解析的输出是一棵抽象语法树。后续会有例子说明。

  • 路由计算

    根据SQL解析的结果,以及预定义的数据分布规则,计算出需要执行的节点,结果可能涉及单个存储节点也可能涉及多个。
    路由计算的主要输出是本次请求需要哪些数据节点执行查询。

  • 策略生成(执行计划)

    包含两个步骤,1是执行一些SQL结构上的优化,主要目的减少执行节点的数量,减少SQL内嵌的层级数量,以期降低SQL执行的时间。2是根据优化后的数据结构以及路由计算的结果,构造一个执行计划,该计划描述了执行步骤的先后以及每个步骤具体执行的内容。
    该步骤的输出是一棵执行树,每个叶子节点表示最先开始独立的执行步骤,非叶子节点需要在其所有叶节点执行结束之后,才能执行。

  • 执行计划

    根据执行计划,执行本次SQL的逻辑,又分为串行执行和并行执行。
    该步骤的输出就是各个节点的执行的结果。

  • 结果合并

    当执行策略要求对多个数据节点执行查询时,需要将多个返回值按照逻辑进行合并,比如分组,排序等等操作。

一个数据分片的例子

配置初始化

数据库配置,这里定义了2个数据库的信息,数据库标识为db1和db2,配置的内容是ip,端口和数据库名。

db1:{ip:192.168.1.1,port:3306,dbName:test}
db2:{ip:192.168.1.2,port:3306,dbName:test}

连接信息配置,这里定义了2个用户信息,分别对应上述2个数据库,包括用户名,密码(生产环境通常需要加密保存),和连接的一些基本参数。

db1:{user:root,passwd:123456,connectionProperties: characterEncoding=utf8}
db2:{user:root,passwd:123456,connectionProperties: characterEncoding=utf8}

应用拓扑配置,一个叫做MEIPAI_APP的应用,使用db1和db2这2个数据库节点,这个应用下有一张叫做user的表,分布情况是db1和db2各自一张,表名都叫做user,这个表的如有规则是字段user_id取模2的值加上1,然后加上前缀"db"。这是一个分库部分表的例子。

MEIPAI_APP:{databases:db1,db2}
MEIPAI_APP:{table:user,topology:{db1:user,db2:user},rule:{"db"+ user_id%2+1}}

proxy部署配置,表示代理服务器的地址,端口和负责的应用名。

ip:192.168.1.100,port:3306,app:MEIPAI_APP

鉴权信息,该信息表示使用者通过用户名meipai,密码meipai123456可以访问MEI_APP这个应用。

MEIPAI_APP:{user:meipai,passwd:meipai123456}

创建连接

用户创和proxy之间的连接

jdbc:mysql://192.168.1.100:3306?user=meipai&passwd=meipai123456

proxy创建和数据库之间的连接

jdbc:mysql://192.168.1.1:3306?user=root&passwd=123456
jdbc:mysql://192.168.1.2:3306?user=root&passwd=123456

执行查询

用户执行SQL

select * from user where user_id = 1 or user_id = 2

proxy收到SQL后的执行过程

解析SQL,得到抽象语法树

sql_abstract_syntax_tree.jpg?raw=true

路由计算,得到执行的数据库节点

"db" + 1%2+1 = db2
"db" + 2%2+1 = db1
db2 or db1 = {db1,db2}

得到执行计划

db2:select * from user where user_id = 1
db1:select * from user where user_id = 2
merge(db1, db2)

执行查询

db2: user_id=1,name=jack,age=22
db1: user_id=2,name=lily,age=25

结果合并

idnameage
1jack22
2lily25

业界的实现

Atlas

Atlas 是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平 台,每天承载的读写请求数达几十亿条。MySQL-Proxy是C语言编写,支持嵌入性脚本语言Lua。主要功能:

  • 读写分离
  • 从库负载均衡
  • IP过滤
  • SQL语句黑白名单
  • 自动分表

详细说明:github地址

kingshard

kingshard是一个由Go开发高性能MySQL Proxy项目,kingshard在满足基本的读写分离的功能上,致力于简化MySQL分库分表操作;能够让DBA通过kingshard轻松平滑地实现MySQL数据库扩容。主要功能:

  • 读写分离。
  • 跨节点分表。
  • 客户端IP访问控制。
  • 平滑上线DB或下线DB,前端应用无感知。

详细说明:github地址

Mycat

基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。业界优秀的开源项目和创新思路被广泛融入到MYCAT的基因中,使得MYCAT在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产品。

MYCAT背后有一支强大的技术团队,其参与者都是5年以上资深软件工程师、架构师、DBA等,优秀的技术团队保证了MYCAT的产品质量。

MYCAT并不依托于任何一个商业公司,因此不像某些开源项目,将一些重要的特性封闭在其商业产品中,使得开源项目成了一个摆设。

详细说明:github地址 | 官方网站

转载于:https://www.cnblogs.com/qiuzm/p/6626829.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值