在 Pisa-Proxy 中,如何利用 Rust 实现 MySQL 代理

 一

背景

在 Database Mesh 中,Pisanix 是一套以数据库为中心的治理框架,为用户提供了诸多治理能力,例如:数据库流量治理,SQL 防火墙,负载均衡和审计等。在 Pisanix 中,Pisa-Proxy 是作为整个 Database Mesh 实现中数据平面的核心组件。Pisa-Proxy 服务本身需要具备 MySQL 协议感知,理解 SQL 语句,能对后端代理的数据库做一些特定的策略,SQL 并发控制和断路等功能。在这诸多特性当中,能够理解 MySQL 协议就尤为重要,本篇将主要介绍 MySQL 协议和在 Pisa-Proxy 中 MySQL 协议的 Rust 实现。

Why Rust

为什么要选用 Rust 语言呢?我们的考量有以下几个必要条件。

  • 安全性: 首先作为数据库治理的核心组件,其语言的安全性是居首位的。Rust 中,类型安全实现内存安全,如所有权机制、借用、生命周期等特性避免了程序开发过程中的空指针、悬垂指针等问题,从而保证了服务在语言层面的安全性。
  • 优秀的性能表现: Rust 的目标在性能方面对标 C 语言,但在安全和生产力方面则比 C 更胜一筹。 其无 GC,不需要开发人员手动分配内存等特性,极大程度地减少内存碎片,简化内存管理。
  • 低开销: 从开发效率和可读可维护性上来说,有足够的抽象能力,并且这种抽象没有运行时开销(runtime cost)。零开销抽象,通过泛型和 Trait 在编译期展开并完成抽象解释。
  • 实用性: 有优秀的包管理器工具 Crate、文档注释支持、详细的编译器提示、友好的错误处理等,在开发过程中能够高效帮助程序员快速开发出可靠、高性能的应用。

整体架构,模块设计

整体架构。

图 1 Pisa-Proxy 工作流程图

工作流程

在图 1 中我们可以看出整个 Proxy 服务可以概括为以下几个阶段。

1. 首先 Pisa-Proxy 支持 MySQL 协议,将自己伪装为数据库服务端,应用连接配置只需修改访问地址即可建连 Pisa-Proxy 通过读取应用发来的握手请求和数据包;

2. 得到应用发来的 SQL 语句后对该 SQL 进行语法解析,并得到该 SQL 的 AST;

3. 得到对应 AST 后,基于 AST 实现高级访问控制和 SQL 防火墙能力;

4. 访问控制和防火墙通过后 SQL 提交执行,SQL 执行阶段的指标将采集为 Prometheus Metrics,最后根据负载均衡策略获取执行该语句的后端数据库连接;

5. 如果连接池为空将根据配置建立和后端数据库的连接,SQL 将从该连接发往后端数据库;

6. 最后读取 SQL 执行结果,组装后返回给客户端。

如何用 Rust 快速实现 MySQL 代理服务

如图 2,在整个代理服务中总体分为两部分:服务端和客户端,即代理服务作为服务端处理来自客户端的请求。和服务端,需要对服务端发起认证,并将客户端端命令发送给 MySQL 数据库。在这两部分中我们需要创建两套 Socket 来完成网络数据包的处理。

图 2

技术选型

介绍

在网络报处理和运行时处理上,我们选用了 Rust 实现的 Tokio(
https://github.com/tokio-rs/tokio )框架。Tokio 框架是 Rust 编写的可靠、异步和精简应用程序的运行时。并且 Tokio 是一个事件驱动的非阻塞 I/O 平台,用于使用 Rust 编程语言编写异步应用程序。在高层次上,它提供了几个主要组件:

  • 一个多线程、基于工作窃取的任务调度程序( https://docs.rs/tokio/latest/tokio/runtime/index.html )。
  • 由操作系统的事件队列(epoll、kqueue、IOCP 等)支持的响应式编程。
  • 异步 TCP 和 UDP( https://docs.rs/tokio/latest/tokio/net/index.html )套接字。

同时,Tokio 还提供了丰富的工具链,例如编解码工具包、分帧包等等,可以使我们更加方便快捷地处理 MySQL 中各种各样的数据报文。

项目地址:
https://github.com/tokio-rs/tokio

优势

a. 快速: Tokio 的设计旨在使应用程序尽可能都快。

b. 零成本抽象: Tokio 以 Future 为基础。虽然 Future 并非 Rust 独创,但与其他语言的 Future 不同的是,Tokio Future 编译成了状态机,用 Future 实现常见的同步,不会增加额外开销成本。Tokio 的非阻塞 IO 可以充分发挥系统优势,例如实现类似 Linux Epoll 这种多路复用技术,在单个线程上的多路复用允许套接字并批量接收操作系统消息,从而减少系统调用,所有这些都可以减少应用程序的开销。

c. 可靠: Rust 的所有权模型和类型系统可以实现系统级应用程序,而不必担心内存不安全。

d. 轻量级: 没有垃圾收集器,因为 Tokio 是基于 Rust 构建的,所以编译后的可执行文件包含最少的语言运行时。这意味着,没有垃圾收集器, 没有虚拟机,没有 JIT 编译,也没有堆栈操作。这样在编写多线程并发的系统时,能够有效避免阻塞。

e. 模块化: 每个组件都位于一个单独的库中。如果需要,应用程序可以挑选所需的组件,避免依赖不需要的组件。

代码实现

Rust 中数据包处理

#[derive(Debug)]
pub st
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值