在 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,代理服务包含服务端和客户端的协议解析、SQL 解析、访问控制、连接池等模块。

在这里插入图片描述

工作流程
在图 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 来完成网络数据包的处理。

在这里插入图片描述

技术选型

介绍

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

同时,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 struct Packet {
    pub sequence: u8,
    pub conn: BufStream<LocalStream>,
    pub header: [u8; 4],
}

以上为 Proxy 数据包处理逻辑中核心的结构体,结构体中包含了三个字段分别为:

  • sequence:报文中的序列号 ID

  • conn:处理链接的 Socket

  • header:存储消息头报文的数组,长度为 4 字节

在包处理逻辑中主要定义了以下函数,在整个代理服务中网络数据交换都由以下方法来完成。

Pisa-Proxy 作为服务端

pub struct Connection {
    salt: Vec<u8>,
    status: u16,
    collation: CollationId,
    capability: u32,
    connection_id: u32,
    _charset: String,
    user: String,
    password: String,
    auth_data: BytesMut,
    pub auth_plugin_name: String,
    pub db: String,
    pub affected_rows: i64,
    pub pkt: Packet,
}

上面的结构体描述了 Pisa- Proxy 作为服务端处理来自于客户端请求时所包含的字段。例如,其中包含了和 MySQL 客户端进行认证信息,和所包含数据包处理逻辑的 Packet。

Pisa-Proxy 作为客户端

#[derive(Debug, Default)]
pub struct ClientConn {
    pub framed: Option<Box<ClientCodec>>,
    pub auth_info: Option<ClientAuth>,
    user: String,
    password: String,
    endpoint: String,
}

Tokio 提供的编解码器

在 Pisa-Proxy 中,大量使用了 Tokio 工具包中的编解码器,使用 codec Rust 会自动帮助开发者将原始字节转化为 Rust 的数据类型,方便开发者处理数据。使用编解码器,只需要在代码中为定义好的类型实现 Decoder 和 Encoder 两个 Trait,就可以通过 stream 和 sink 进行数据的读写。下面通过一个简单的示例来看一下 Tokio 编解码器的使用步骤。

使用 Tokio 编解码器一共分为三步:

  1. 首先要自定义一个错误类型,这里定义了一个 ProtocolError,并为它实现一个 from 方法,能够让它接收错误处理。
pub enum ProtocolError {
    Io(io::Error),
}

impl From<io::Error> for ProtocolError {
    fn from(err: io::Error) -> Self {
        ProtocolError::Io(err)
    }
}
  1. 定义一个数据类型,这里我们声明一个 Message 为 String,然后定义一个结构体,也就是我们要解析的是原始字节流要实际转换成的结构体,也即 Tokio 中 framed(帧的概念),这里定义一个空结构体 PisaProxy;
type Message = String;
struct PisaProxy;

接下来就是为 PisaProxy 分别实现 Encoder 和 Decoder 这两个 Trait。这里的示例,实现的功能为将数据转为 byte 数组,追加到 buf 中。在编码器中,我们首先要指定 Item 类型为 Message 和错误类型,编码处理逻辑这里将字符串进行拼接并返回给客户端。

在这里,Encoder 编码是指将用户自定义类型转换成 BytesMut 类型,写到 TcpStream 中,Decoder 解码指将读到的字节数据序列化为 Rust 的结构体。

impl Encoder<Message> for PisaProxy {
    type Error = ProtocolError;

    fn encode(&mut self, item: Message, dst: &mut BytesMut) ->Result<(), Self::Error> {
        dst.extend(item.as_bytes());
        Ok(())
    }
}

impl Decoder for PisaProxy {
    type Item = Message;
    type Error = ProtocolError;

    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
        if src.is_empty() {
            return Ok(None);
        }
        let data = src.split();
        let mut buf = BytesMut::from(&b"hello:"[..]);
        buf.extend_from_slice(&data[..]);
        let data = String::from_utf8_lossy(&buf[..]).to_string();

        Ok(Some(data))
    }
}
  1. 当实例化 PisaProxy 结构体后,就可以调用 framed 方法,codec 的 framed 方法(codec.framed(socket))将 TcpStream 转换为 Framed<TcpStream,PisaProxy>,这个 Framed 就是实现了 tokio 中的 Stream 和 Sink 这两个 trait,实现的这两个 Trait 的实例就具有了接收(通过 Stream)和发送(通过 Sink)数据的功能,这样我们就可以调用 send 方法发送数据了。
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let addr = "127.0.0.1:9088";
    let listener = TcpListener::bind(addr).await?;
    println!("listen on: {:?}", addr);

    loop {
        let (socket, addr) = listener.accept().await?;

        println!("accepted connect from: {}", addr);

        tokio::spawn(async move {
            let codec = PisaProxy {};
            let mut conn = codec.framed(socket);
            loop {
                match conn.next().await {
                    Some(Ok(None)) => println("waiting for data..."),
                    Some(Ok(data)) => {
                        println!("data {:?}", data);
                        conn.send(data).await;
                    },
                    Some(Err(e)) => {
                    },
                    None => {},
                }
            }
        });
    }
}

四、MySQL 协议在 Pisa-Proxy 中的实现

MySQL 协议简介
MySQL 数据库本身是一个很典型的 C/S 结构的服务,客户端和服务端通信可以通过 Tcp 和 Unix Socket 的方式进行交互。在本篇中,我们主要说明通过网络 Tcp 的方式来实现 MySQL 代理。

MySQL 客户端和服务端的交互主要包含了两个重要的过程:1. 握手认证,2.发送命令。本篇会主要围绕这两个过程来介绍相关的实现。在客户端和服务端交互的过程中主要包含了以下几种类型报文:数据包、数据结束包、成功报告包以及错误消息包,在后面的章节中会为大家详细介绍这几种报文。

交互过程
MySQL 客户端和服务端在交互的过程中主要包含了两个过程,即握手认证阶段和执行命令阶段,当然在这两个过程之前首先要经历 TCP 三次握手的过程。在三次握手结束后首先进入握手认证阶段,在交换完信息并且客户端正确登录服务端后,进入执行命令阶段,图 3 完整描述了整个交互过程。

代码链接:https://github.com/database-mesh/pisanix/blob/master/pisa-proxy/protocol/mysql/src/server/conn.rs
在这里插入图片描述

握手认证

在握手认证阶段是 MySQL 客户端和服务端建联非常重要的阶段,该阶段发生在 TCP 三次握手之后。首先服务端会给客户端发送服务端信息,其中包括协议版本号、服务版本信息、挑战随机数、权能标志位等等。当客户端接收到服务端发来的响应之后,客户端开始发起认证请求。认证请求中,会携带客户端用户名、数据库名以及通过服务端响应中的挑战随机数将客户端密码加密后,一同发送给服务端进行校验。校验过程中,除了会对用户名密码进行校验,还会匹配客户端所使用的认证插件,如果不匹配则会发生插件的自动切换,以及判断客户端是否使用了加密链接。当以上阶段全部正常完成后,客户端则登录成功,服务端返回客户端 OK 数据报文。

上述过程分别在 runtime 和 protocol 的 server 中实现。在 runtime 中的 start 函数等待请求进入,Tcp 三次握手结束后,从 handshake 函数如图 3,开始握手阶段。在 handshake 中分别包含了三个过程,首先由 write_initial_handshake 给客户端发送服务端信息,然后在 read_handshake_response 客户端拿着服务端信息开始认证请求。

pub async fn handshake(&mut self) -> Result<(), ProtocolError> {
        match self.write_initial_handshake().await {
            Err(err) => return Err(err::ProtocolError::Io(err)),
            Ok(_) => debug!("it is ok"),
        }

        match self.read_handshake_response().await {
            Err(err) => {
                return Err(err);
            }
            Ok(_) => {
                self.pkt.write_ok().await?;
                debug!("handshake response ok")
            }
        }

        self.pkt.sequence = 0;

        Ok(())
    }

执行命令

当握手和认证阶段完成后,此时客户端才算是真正意义上的与服务端完成建立链接。那么此时则进入执行命令阶段。在 MySQL 中,能够发送命令的指令类型有很多种,我们会在下文中为大家进行介绍。

代码链接: https://github.com/database-mesh/pisanix/blob/master/pisa-proxy/runtime/mysql/src/server/server.rs

在下面的代码中可以看到,Pisa-Proxy 在这里会对不同类型的指令进行不同的逻辑处理。例如,初始化 db 的处理逻辑为 handle_init_db,处理查询的逻辑为 handle_query。

match cmd {
          COM_INIT_DB => self.handle_init_db(&payload, true).await,
          COM_QUERY => self.handle_query(&payload).await,
          COM_FIELD_LIST => self.handle_field_list(&payload).await,
          COM_QUIT => self.handle_quit().await,
          COM_PING => self.handle_ok().await,
          COM_STMT_PREPARE => self.handle_prepare(&payload).await,
          COM_STMT_EXECUTE => self.handle_execute(&payload).await,
          COM_STMT_CLOSE => self.handle_stmt_close(&payload).await,
          COM_STMT_RESET => self.handle_ok().await,
          _ => self.handle_err(format!("command {} not support", cmd)).await,
}

MySQL 协议基本数据类型
在 MySQL 协议中主要有以下几种数据类型:

  • 整型值:MySQL 报文中整型值分别有 1、2、3、4、8 字节长度,使用小端传输。

  • 字符串(以 NULL 结尾)(Null-Terminated String):字符串长度不固定,当遇到’NULL’(0x00)字符时结束。

  • 二进制数据(长度编码)(Length Coded Binary)

参考链接:https://dev.mysql.com/doc/internals/en/basic-types.html

报文结构
在 MySQL 客户端和服务端所交互的数据最大长度为 16MByte,其基本数据报文结构类型如下:

在这里插入图片描述

图 4
在这里插入图片描述

图 5

在图 4 和图 5 中描述了 MySQL 报文的基本结构。报文包括了两部分,消息头和消息体。其中在消息头中,3 字节表示数据报文长度,1 字节存储序列号,消息体中存储实际的报文数据。

消息头

用于标记当前请求消息的实际数据长度值,以字节为单位,占用 3 个字节,最大值为 0xFFFFFF,即接 2^24-1。

序列号

序列 ID 从 0 开始随每个数据包递增,并且当进入新的命令时重置为 0。序列号 ID 有可能会发生回绕,当发生回绕时,需将序列号 ID 重置为 0,并且重新开始计数递增。

报文数据

消息体用于存放请求的内容及响应的数据,长度由消息头中的长度值决定。

客户端请求命令报文

该指令用于标识客户所要执行命令的类型,以字节为单位占用 1 个字节。请求命令报文常用到的有 Text 文本协议和 Binary 二进制协议。这里可以参考【执行命令】中的代码,代码中描述了对不同指令的处理逻辑。

在文本协议中常用到的有以下指令:

值指令功能
0x01COM_QUIT关闭连接
0x02COM_INIT_DB切换数据库
0x03COM_QUERYSQL 查询请求
0x04COM_FIELD_LIST获取数据表字段信息
0x05COM_CREATE_DB创建数据库
0x06COM_DROP_DB删除数据库
0x08COM_SHUTDOWN停止服务器
0x0ACOM_PROCESS_INFO获取当前连接的列表
0x0BCOM_CONNECT(内部线程状态)
0x0ECOM_PING测试连通性

更多请参考:https://dev.mysql.com/doc/internals/en/text-protocol.html

在二进制协议,即 Prepare Statement 中常用到的有以下指令:

值指令功能
0x16COM_STMT_PREPARE预处理 SQL 语句
0x17COM_STMT_EXECUTE执行预处理语句
0x18CCOM_STMT_SEND_LONG_DATA发送 BLOB 类型的数据
0x19COM_STMT_CLOSE销毁预处理语句
0x1ACOM_STMT_RESET清除预处理语句参数缓存

更多请参考:https://dev.mysql.com/doc/internals/en/prepared-statements.html

响应报文

  • OK 响应报文

  • Error 响应报文

  • Field 结构

  • EOF 结构

  • Row Data 结构

…

例如,下面代码中展示了如何给客户端写 OK 和 EOF 报文。

#[inline]
pub async fn write_ok(&mut self) -> Result<(), Error> {
  let mut data = [7, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0];
  self.set_seq_id(&mut data);
  self.write_buf(&data).await
}
  
#[inline]
pub async fn write_eof(&mut self) -> Result<(), Error> {
  let mut eof = [5, 0, 0, 0, 0xfe, 0, 0, 2, 0];
  self.set_seq_id(&mut eof);
  self.write_buf(&eof).await
}

com_query 请求流程

如图 6 为 com_query 的请求流程,com_query 指令可能会返回以下结果集:

  • ERR 报文

  • OK 报文

  • Protocol::LOCAL_INFILE_Request 报文

  • Resultset 报文

在(https://github.com/database-mesh/pisanix/blob/master/pisa-proxy/protocol/mysql/src/client/resultset.rs)文件中主要为对 ResultSet 结果集的处理,可以看到在这里定义了 ResultSet 结构,同样对 ResultSetCodec 分别实现了 Encoder 和 Decoder 两个 Trait,这样就可以通过编解码器来处理 ResultSet 的报文。

#[derive(Debug, Default)]
pub struct ResultsetCodec {
  pub next_state: DecodeResultsetState,
  pub col: u64,
  pub is_binary: bool,
  pub seq: u8,
  pub auth_info: Option<ClientAuth>,
}

在这里插入图片描述

图 6

五、总结

以上,就是本篇文章的全部内容。在本篇文章中我们介绍了使用 Rust 实现 MySQL 代理的动机,介绍了 MySQL 协议中一些常用到的概念和 MySQL 中数据报文在网络中是如何进行交换数据的;并在最后介绍如何使用 Rust 去快速实现一个 MySQL 代理服务。更多实现细节请关注 Pisanix 代码仓库。

欢迎点击链接查看相关教学视频:https://www.bilibili.com/video/BV1B54y1o7EC?spm_id_from=333.999.0.0

六、相关链接

Pisanix
项目地址:https://github.com/database-mesh/pisanix

官网地址:https://www.pisanix.io/

Database Mesh:https://www.database-mesh.io/

Mini-Proxy:一个最小化的 MySQL Rust 代理实现
项目地址:https://github.com/wbtlb/mini-proxy

社区
目前 Pisanix 社区每两周都会组织线上讨论,详细安排如下,欢迎各位小伙伴一起参与进来。

表列 A表列 B
邮件列表https://groups.google.com/g/database-mesh
英文社区双周会(2022年2月27日起),周三 9:00 AM PSThttps://meet.google.com/yhv-zrby-pyt
中文社区双周会(2022年4月27日起),周三 9:00 PM GMT+8https://meeting.tencent.com/dm/6UXDMNsHBVQO
微信小助手pisanix
Slackhttps://databasemesh.slack.com/
会议记录https://bit.ly/39Fqt3x

作者介绍

王波,SphereEx MeshLab 研发工程师,目前专注于 Database Mesh,Cloud Native 研发。Linux、llvm、yacc、ebpf user, Gopher & Rustacean and c bug hunter。

GitHub:https://github.com/wbtlb

相关推荐

官宣|Apache ShardingSphere 5.0.0 正式发布

11 月 10 日,是 Apache ShardingSphere 进入 Apache 基金会的三周年纪念日。在这特殊的一天,我们很高兴的宣布 Apache ShardingSphere 迎来了 5.0.0 GA 版本的正式发布。经过近两年的优化和打磨,ShardingSphere 5.0.0 GA 版正式开启了以可插拔架构为核心的全新阶段,实现了由过去数据分片单一应用场景到现在复杂应用环境下综合数据治理的身份转变与能力提升。5.0.0 具体版本发布信息如下:1 新特性 支持注释解析 .

SphereEX的博客 733

SphereEx 获数百万美元天使融资,接力 ShardingSphere 开启 Database Plus 新篇章

5月14日,数据前沿技术领域初创公司 SphereEx 获得来自红杉中国种子基金、初心资本的数百万美元天使轮融资。SphereEx是一家致力于构建新型分布式数据基础设施的公司,秉承开源、共享、生态、平台理念,致力于数据领域前沿技术创新。其研发的分布式中间件ShardingSphere,具备“平台化、可插拔、云原生”等核心技术特点,是大规模数据应用、数据增值应用的理想解决方案。SphereEx的核心创始团队来自Apache顶级项目 ShardingSphere、头部互联网公司、及知名基础设施软件提供商。.

SphereEX的博客 644

DBPlusEngine 1.7.2 发布:数据安全闭环与联邦查询突破

ShardingSphere 原厂企业版,支撑企业核心系统安全治理与联邦查询升级。

SphereEX的博客 390

SphereEx-DBPlusEngine 1.5.0 功能解读:CDC

数据库日志(以 MySQL 为例) binlog 是 MySQL 记录变更数据的"二进制日志",它可以看做是一个消息队列,队列中按顺序保存了 MySQL 中详细的增量变更信息,通过消费队列中的变更条目,下游系统或工具实现了与 MySQL 的实时数据同步。前一段时间,面向新一代数据架构的数据库增强引擎 SphereEx-DBPlusEngine 正式发布 1.5.0 版本,新增 CDC 和数据库防火墙两大重磅功能,本篇文章笔者就给大家详细介绍 CDC 功能的实现逻辑和技术细节。使用网络通道的情况下需要。

SphereEX的博客 472

SphereEx-DBPlusEngine 1.5.0 版本发布

近日,面向新一代数据架构的数据库增强引擎 SphereEx-DBPlusEngine 正式发布 1.5.0 版本,新增 CDC 和数据库防火墙两大重磅功能,并在数据安全方面做了重要的增强。增加了对实时数据变更的捕获和管理能力,并增强了对数据访问的监控和拦截能力,帮助企业降低业务风险,提升效率。

SphereEX的博客 365

【版本更新】Apache ShardingSphere 5.4.0 版本正式发布!

SphereEX的博客 580

畅聊新版本!尽在本周六 ShardingSphere 线上圆桌会!

👏 欢迎大家「预约」直播,提前锁定精彩内容,与三位资深社区贡献者一起共究 ShardingSphere 5.4.0 与 ShardingSphere-On-Cloud 0.3.0 的技术魅力!😉 就在本周六(7 月 1 日), ShardingSphere 线上圆桌(第二期)栏目内容即将播出啦!👋 嗨~ ShardingSphere 社区的小伙伴们下午好!🤩 转载议程海报还能赢取「互动福利」!惊喜多多,详情见下方海报哦~👇 👇。

SphereEX的博客 203

围“桌”详谈|本周六直播,一起聊聊「发版」那些事儿!

🎉围“桌”详谈|本周六,来一起聊聊「发版」那些事儿!⏰7 月 1 日下午两点,我们邀请了 ShardingSphere PMC 端正强、ShardingSphere Committer 江龙滔、ShardingSphere Committer 苗立尧三位资深的社区贡献者做客「社区线上直播间」,将为大家详细解答新版本带来的重点功能更新及对应的性能突破!🌟 活动还设有「技术实战」、「有奖问答」等趣味环节,期待与大家一起解锁!

SphereEX的博客 245

倒计时 1 天 | SphereEx 在 2023 亚马逊云科技中国峰会等你来打卡!

📢倒计时 1 天 | SphereEx 即将亮相 2023 亚马逊云科技中国峰会!✨SphereEx 联合创始人 & CTO 潘娟 将在大会期间将向业界介绍如何充分发挥弹性伸缩、自动备份、容错处理等云计算的优势,提高分布式数据库的可靠性和性能。同时,也将分享在分布式数据库应用中安全性的重要性和实践方法,从多个方面保护数据的安全性。👏扫描下方二维码预约参观,通过二维码进行预约的小伙伴在上海展会现场可凭借手机号领取精美礼品一份!还可以在现场参与抽奖,更多好礼等你拿!

SphereEX的博客 300

倒计时2天,解锁亚马逊云科技中国峰会 Dev Lounge 玩法

在此次圆桌讨论中,ShardingSphere PMC & SphereEx 联合创始人兼 CTO 潘娟受邀与多位行业专家共同分享他们在利用开源进行数据分析和挖掘方面的研究成果、经验和启示。开发者们将有机会与专家面对面交流,同时了解最新的数据分析和挖掘技术洞察,掌握趋势和机遇。数据对于企业和个人来说都至关重要,而大数据和人工智能的不断发展,为各种应用场景带来了更多的机会。那么,如何利用开源分析和挖掘数据价值,成为了许多开发者关注的话题。海报二维码扫码报名,6月27-28日,我们上海等你,不见不散!

SphereEX的博客 281

逛开发者集市啦,ShardingSphere 在亚马逊云科技中国峰会等你!

2023亚马逊云科技中国峰会将于6月27日-28日在上海世博中心盛大开幕。本次峰会以“共见·价值成就”为主题,与合作伙伴展望云计算趋势及合作发展战略,分享行业解决方案,共同探讨协同销售策略和全新的 APN 计划,助力合作伙伴成就更多价值。同时,峰会将聚焦构建新技术加速的产品创新、新架构提升的业务弹性、云计算引领的创新模式,围绕价值加速实现,企业敏捷稳健,行业全新机遇等热门话题,携手众多业内技术领导者,践行者一同,把握时代机遇。本次峰会特设开发者会客厅区域,为开发者提供一站式等丰富体验。

SphereEX的博客 399

ShardingSphere 荣获一等奖!2022 年中国开源创新大赛成绩单公布

2022年中国开源创新大赛”在国家中央网信办信息化发展局的指导下,由中国互联网发展基金会、中国网络空间研究院、中国互联网投资基金联合主办,大赛以“开源创新,共建生态”为主题,围绕国家在开源人才培养和开源生态建设方面的重大战略需求,聚焦“卡脖子”相关技术领域,旨在助力开源生态的高质量发展,激发开源创新活力,推动我国科技创新及产业转型升级。5 月 31 日,“2022 年中国开源创新大赛”正式颁奖。

SphereEX的博客 309

创新能力加速产业发展,SphereEx 荣获“中关村银行杯”『大数据与云计算』领域 TOP1

SphereEx 凭借自身在数据库领域产品与理念的双重创新优势,荣获2022 中关村国际前沿科技创新大赛“中关村银行杯”『大数据与云计算』领域的第一名。

SphereEX的博客 348

Pisanix v0.2.0 发布|新增动态读写分离支持

Pisanix 于今天发布了 v0.2.0 版本,在此前版本基础上,本次更新新增了动态读写分离支持,下面将进行详细介绍。

SphereEX的博客 375

Database Plus 的云上之旅:SphereEx 正式开源 ShardingSphere on Cloud 解决方案

作为 Database Plus 设计哲学的最佳实践,Apache 顶级开源项目 ShardingSphere 通过各行业多年的生产环境检验,受到了众多社区爱好者的关注和追捧。而随着 Kubernetes 成为容器编排的事实标准,其引领的云原生风暴迅速席卷了技术世界。Apache ShardingSphere 作为一个拥有开放生态的数据库增强引擎,其设计理念和 Kubernetes 有着诸多相似之处,而在这股云原生浪潮之下,社区对 ShardingSphere 上云的呼声也越来越高,于是 **SphereE

SphereEX的博客 303

DistSQL 深度解析:打造动态化的分布式数据库

本文将以数据分片为例,深度解析 Sharding 相关 DistSQL 的应用场景和使用技巧。同时,通过实践案例将一系列 DistSQL 语句进行串联,为读者展现一套完整实用的 DistSQL 分片管理方案。

SphereEX的博客 409

Pisa-Proxy SQL 解析之 Lex & Yacc

在上篇文章《Pisa-Proxy 之 SQL 解析实践》中介绍了 Pisa-Proxy 的核心模块之一 SQL 解析器的相关内容。在 MySQL 和 PostgreSQL 中 SQL 解析是通过 Yacc 实现的,同样 Pisa- Proxy 的 SQL 解析器是由类似 Yacc 这样的工具实现的,所以本篇文章会围绕 SQL 解析器为大家介绍一些编译原理和 Lex & Yacc 的使用,同时也会为读者展示如何通过 Lex & Yacc 实现一个简单的 SQL 解析器。从而帮助大家更好地理解 Pisa-Pro

SphereEX的博客 993

终于可以一行代码也不用改了!ShardingSphere 原生驱动问世

ShardingSphere-JDBC 驱动的出现,使 ShardingSphere 的易用性获得了前所未有的加强

SphereEX的博客 827

开源者的自我修养|为 ShardingSphere 贡献了千万行代码的程序员,后来当了 CEO

浅谈开源人的17年成长路线,热爱才能坚持

SphereEX的博客 376

开源二三事|ShardingSphere 与 Database Mesh 之间不得不说的那些事

前段时间,以 Apache ShardingSphere 核心团队组建的创业公司 SphereEx,正式对外推出了 Database Mesh 2.0 概念以及与之相配套的开源产品 Pisanix,这引发了社区间对于 ShardingSphere 和 Database Mesh 的不少争论与思考。许多用户都很清楚,SphereEx 是由 Apache ShardingSphere 核心团队创立的。那么有部分用户就提出了疑问,既然已经有了 Apache ShardingSphere 这样一个如此成功的开源项目

SphereEX的博客 366

Pisa-Proxy 之 SQL 解析实践

本文将以 Pisa-Proxy 实践为例,为大家展现 Pisa-Proxy 中的 SQL 解析实现,遇到的问题及优化

SphereEX的博客 543

基于 ShardingSphere 的得物数据库中间件平台“彩虹桥”演进之路

得物与 ShardingSphere 的完美结合实践

SphereEX的博客 571

Apache ShardingSphere 5.1.2 发布|全新驱动 API + 云原生部署,打造高性能数据网关

此次更新带来 ShardingSphere 原生驱动、Helm Chart、SQL 翻译等全新功能,打造极具生产力的数据网关

SphereEX的博客 600

ShardingSphere 异构迁移最佳实践:将3.5亿量级的顾客系统 RTO 减少60倍

Apache ShardingSphere 助力当当 3.5 亿用户量级顾客系统重构,由 PHP+SQL Server 技术栈无缝转型为 Java+ShardingSphere+MySQL,性能、可用性及维护性均得到显著提升,是 ShardingSphere 异构迁移最佳实践。

SphereEX的博客 329

SphereEx 正式开源面向 Database Mesh 的解决方案 Pisanix

今天,SphereEx 正式对外推出了面向 Database Mesh 的开源解决方案-- Pisanix v0.1.0 版本。Pisanix 从设计之初就吸收了 Database Mesh 的核心思想:通过可编程实现高性能扩展,应对云上数据库治理挑战。这标志着 Database Mesh 不再停留于纸上,而成为了一个真正可以实现和落地的框架。.........

SphereEX的博客 523

做数据时代的加油站,ShardingSphere 为易车数据库架构演进提供新动力

做数据时代的加油站,ShardingSphere 为易车数据库架构演进提供新动力

SphereEX的博客 255

数据库治理的云原生之道 —— Database Mesh 2.0

本文将带领各位读者回顾 Database Mesh 诞生的背景,重新审视 Database Mesh 1.0 的价值,并为大家介绍 Database Mesh 2.0 的新概念、新思路和新特性,共同探讨 Database Mesh 的未来之路。

SphereEX的博客 508

ShardingSphere 在东南亚|与科技保险公司 Fuse 的技术融合

ShardingSphere 在东南亚|与科技保险公司 Fuse 的技术融合

SphereEX的博客 247

SphereEx 正式成为 CNCF 会员,持续完善云原生环境下的数据库基础设施

近日,SphereEx 正式成为全球知名开源组织 CNCF(云原生计算基金会,Cloud Native Computing Foundation)银牌会员。

SphereEX的博客 285

覆盖 70% 核心业务,ShardingSphere 如何成为喜马拉雅架构演进的催化剂

覆盖 70% 核心业务,ShardingSphere 如何成为喜马拉雅架构演进的催化剂

SphereEX的博客 244
上一篇: ShardingSphere 异构迁移最佳实践:将3.5亿量级的顾客系统 RTO 减少60倍
下一篇: Apache ShardingSphere 5.1.2 发布|全新驱动 API + 云原生部署,打造高性能数据网关
SphereEx
SphereEx 企业官方账号 企业官方账号
博客等级 码龄6年 69粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值