数据库中间件系列架构实战-架构实现

整体架构

在这里插入图片描述

  • Proxy最主要是要连接CLIENT和MYSQL,通信至关重要,以Netty作为通信组件,封装MYSQL协议,主要解决粘包和拆包问题
  • MYSQL协议层,解析mysql协议,主要负责将Netty接收的TCP包,按照MYSQL协议,解析成SQL语句;还有就是将处理完合并后的SQL语句解析成MYSQL协议发送到指定的地方
  • MYSQL协议解析成SQL语句之后,使用SqlParser组件将MYSQL解析成语法树,获取SQL的各个部分的信息
  • 然后使用SqlRouter组件读取配置的分库分表或者其他策略,重写SQL语句,并且选择路由的节点
  • 然后把这些SQL放到SqlExecutor组件中,选择合适的执行策略,例如线程池,栅栏,信号量等
  • 最后再通过通信层将这些需要执行的SQL发送到MYSQL
  • mysql处理完成之后,返回的数据通过通信层接收,SqlExecutor组件执行,最后的结果可能需要通过ResultMerger组件进行合并之后,再通过通信层发送回客户端

MYSQL 协议

在这里插入图片描述
mysql协议基础packet

  • payload length 代表此packet的装的数据是多少byte,最大2的24次方=16M
  • sequence_id packet的顺序,一旦顺序乱了,mysql客户端就会报错,这个尤其在ResultMerger进行协议重组的过程中需要注意,这个当初我在这上面栽了很多跟头
  • payload 真实的传输数据

Connection 协议

在这里插入图片描述

客户端和Mysql本身就是一个握手协议,只有当Mysql发送OK协议之后,Client才能发送SQL语句

在这里插入图片描述

  • 当我只想限制发送到MYSQL的请求量时,此时就不需要解析SQL语句,只需要在转发的过程中添加一些限制;
  • 可以使用信号量来控制去往MYSQL的流量,可以动态控制的MYSQL的负载情况
  • 可以屏蔽掉一些危险SQL

注意:连接数并没有降低

在这里插入图片描述

  • 为了降低连接数,自己必须实现一个连接池,注意连接池中的连接的保活策略,MYSQL默认每隔8小时会自动kill掉连接
  • 连接池中加入每一个连接之前都要先进行握手协议
  • 对于Client,PROXY要模拟成MYSQL进行通信,对于MYSQL,PROXY要模拟成Client进行通信
  • 由PROXY保存所有的MYSQL数据源密码,同样以MYSQL的加密方式保存
  • 当执行一个SQL语句时,从连接池中选择一个连接来执行,执行完了之后,立即归还回连接池。这样能极大地降低MYSQL的连接数。
  • 如果执行的SQL语句处于事务当中,那么此连接不能释放,必须事务完成之后才能归还回连接池

验证过程

在这里插入图片描述

  • 公式:Client_Secure_Password= SHA1( password ) XOR SHA1( “20-bytes random data from server” SHA1( SHA1( password ) ) )
  • MYSQL存储密码:Server_Password = SHA1( SHA1( password ) )
  • 推论:Stash_Password=SHA1( password )
  • 验证:SHA1(Stash_Password) =?= Server_Password
  1. ”20-bytes random data from server”,这个是PROXY生成发送给客户端的数据
  2. Server_Password,这个是根据密码生成,并配置到PROXY中的
  3. Client_Secure_Password,这个数据是,mysql客户端根据20bit 随机数生成的,然后发送到PROXY

MYSQL Query协议

在这里插入图片描述

  • column definitions 包括 field-count, 多个field,最后会有一个 EOF,表示结束
  • row definitions 包括多个row数据,最后会有一个 EOF,表示结束

Netty线程模型

在这里插入图片描述

线程模型

在这里插入图片描述
早期线程模型

  • 调度和执行混合,层次不分明
  • 并发处理太复杂
  • 错误处理太繁琐

在这里插入图片描述
现在的线程模型

  • 调度和执行分离,只有一个执行池
  • session的所有执行动作封装成task
  • 相同session的task串行执行

Worker线程池实现

在这里插入图片描述

  • task继承Runnable和comparable接口
  • SchedulerWorker 中有n个连接池,session创建计算对应索引
  • 所有的业务逻辑都继承manager接口
  • 使用优先级队列,实现task优先级
发布了49 篇原创文章 · 获赞 31 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/zengqiang1/article/details/103758686