转自:兴趣部落​buluo.qq.com

导读: Spider是为MySQL/MariaDB开发的一个特殊引擎,具有内嵌分片功能。现在它已经被集成到MariaDB10.0及以上版本中,作为MariaDB的一个新的主要性。Spider的主要功能是将数据分散到多个后端节点,它的作用类似于一个代理。

1. 表链接

Spider的表链接的技术参考ISO/IEC 9075-9:2008 SQL/MED标准。利用spider的这个特性,你可以像操作本地MariaDB实例的表一样来操作远程MariaDB实例上的表,也可以像操作本地MariaDB实例的表一样来操作分布在多个MariaDB实例上的表。当创建一个spider存储引擎的表时,该表指向远程服务器上对应的一张表或者多个实例上的表,就像UNIX/Linux中的软链接一样。远程服务器上的表可以是任何存储引擎的表。

在执行CREATE TABLE命令创建spider引擎的表时,需要添加COMMENT或CONNECTION语法来指定远程服务器的地址等信息。例如,在远程服务器(该服务器是数据节点,假设IP为192.168.0.1)上创建了如下一张表:

spider节点创建一张表指向该表:

spider节点,表字段定义可以忽略。Spider第一次访问表的时候,如果发现没有表字段定义,会从后端节点拉取相关元数据,然后缓存在本地。

Spider的系统表spider_tables记录了各个数据分片的位置信息,类似于编程语言中指针作用。该系统表可以便利spider跨节点的join操作:访问数据所在的机器,然后把数据拉取到本地进行join操作;如果进行join操作字段不是分片字段,那么需要广播SQL语句将数据拉取到spider节点进行join操作。Spider_tables类似图1所示。

图1. Spider表链接

2.事务

Spider分别针对单机事务与XA事务实现了相应的操作事务的方法。图2列出了部分实现的方法。

图2. Spider部分实现的事务接口

Spider参照分布式事务DTP/XA模型实现了分布式XA事务(见图3)。在这个模型中,存在RM(Resource Manager,资源管理器)、TM(Transaction Manager, 事务管理器)以及AP(Application, 应用程序)三种角色。AP通过RM API来操作和管理资源,通过TM接口开启/终止/结束事务。RM与TM之间需要实现XA接口。XA接口定义了两阶段提交的必要步骤,以及RM与TM之间需要进行的交互。Spider扮演的是TM角色,而后端的数据节点扮演的是RM的角色。

图3. 分布式DTP/XA模型

为了使用分布式XA事务,业界定义的XA命令如下:

Spider会在系统表spider_xa中记录XA事务的状态,同时在另外一张系统表 spider_xa_members 中记录参与该XA事务的节点,以便进行操作。在spider中,XA事务分别有四种状态,如图4所示,对应于NOT YET, PREPAED, ROLLBACK 以及 COMMITTED。 Spider在开始PREPARE阶段之际会在系统表 spider_xa中标记该XA事务的状态为NOT YET。在所有数据节点都接收到PREPARE消息以后, 该 XA事务的状态进入到PREPARED阶段。假如在PREPARE阶段,某一个数据节点发生故障,那么spider会回滚该事务。相应地,事务的状态变成ROLLBACK。最后,如果所有参与事务的节点都返回PREPARE OK,该事务进入提交阶段。图5给出了对应上述命令的每一个步骤,spider向后端节点发送的消息。

图4. Spider XA事务状态转换

图5. 执行XA事务,Spider与后端节点的交互

从图5可以看到spider向后端节点发送XA START命令的时候会设置会话级别的事务特性,同时将XA事务ID发送到后端节点。因为XA事务ID由三部分组成,spider会 将这三个部分的解析出来,然后拼接成对应的字符串发送到后端节点。为了节省网络开销,Spider将XA END与XA PREPARE命令合并起来一起发送。也就是在这个 阶段初始,spider在系统表里面记录事务的状态。如果所有的RM都返回OK,那么spider进入PREPARED 状态,准备提交事务。否则,事务进入到回滚状态。

3.插拨式引擎

MySQL最强大的功能之一以及区别于其他关系型数据库系统的一个主要的特色是不同的表能够采用不同的存储引擎。每一个存储引擎都有其优缺点,用户能够根据自己的需要定制MySQL的存储引擎。存储引擎能够控制在哪里以及如何存放、获取数据。它代表了下面物理层提供的抽象逻辑接口,也是数据库执行实际I/O操作的地方。这是一个组件体系结构。在这个结构中,handler类定义了存储引擎提供的接口和功能。因为所有的存储引擎从基类handler继承而来,所以它们能够提供相同的功能。总的来说,handler类和handlerton结构在整个体系结构中扮演了中间层的角色。你所编写的存储引擎只有满足了handler的要求后,才能顺利插入到运行的MySQL服务器中。所有的网络连接、安全认证、解析和优化由MySQL服务器本身完成,与存储引擎无关。

Spider作为MySQL的一个可插拔引擎,实现了handler类定义的相应的存取方法。Spider本身并不存放数据,而是类似一个代理的功能将访问请求路由到后端的数据节点。Spider提供了两种途径访问后端节点存储的数据。如图6所示,spider可以遵循MySQL传统的查询处理流程来访问数据,也开发了自有的一套来加速数据访问。在传统的查询处理方式下,SQL查询请求经过查询解析、查询重写、查询优化等步骤。按照生成的查询执行计划,spider从后端节点拉取数据,交给MySQL服务器处理。Spider在这种查询处理框架之下的一个缺点是不能很好地利用后端节点可并行化特性,同时需要对SQL查询进行两次解析,带来的性能损耗问题比较严重。在我们的测试中,性能损耗约50%左右。基于这个原因,为了加速聚集、统计等查询,spider开发团队提供了DirectSQL方式执行查询。DirectSQL的原理类似于Map Reduce方案,将查询直接下发到后端节点,无需在MySQL服务器层进行解析(Map阶段);后端节点将结果返回给spider,由spider合并结果集。(Reduce阶段)。这个方式很好地利用后端节点可并行处理查询的特点,消除重复解析SQL语句的行为。

图6. MySQL体系下的spider

上面已经谈到,spider本身并不存储数据,因此需要将数据访问请求转换成其它方式,例如Handler、Handler Socket以及SQL方式。前面两种访问方式更像是一种NoSQL的数据访问方式,允许查询绕过SQL layer层。Spider允许后端的数据节点可以是不同的数据库系统,通过2PC保证事务提交的原子性。

4.读写流程

为了更清楚地了解spider的读写流程,我们有必要研究一下数据库系统的查询执行模型以及MySQL的插拔式引擎如何跟这个模型对接的。数据库系统基本都采用迭代器模型处理查询,也叫volcano查询执行引擎(发明这个词的学者大概是因为查询执行计划树看起来像一座火山,如图7)。执行计划树的上层节点通过get_next方法驱动子节点获取一条元组,子节点递归调用。在叶子节点也就是基本表将数据返回。这个模型的一个好处就是实现起来很优雅,同时数据流与控制流结合在一起方便程序的调试。这个模型的缺点是函数的大量调用使得进程/线程上下文切换频繁,程序的局部性受到损害。因此,后来针对OLAP场景,采用了向量查询执行模型来减少进程上下文的切换以及保证保证高速缓存的命中率。再次以图7为例子,图中的SQL语句的功能是查询一个部门的平均薪资。假如在职工表EMP的员工ID字段Dno上存在索引,MySQL在Server层针对该查询语句生成的查询计划如下:顺序扫描部门表,通过索引访问职工表,然后在两表join操作之后进行投影操作。下一个阶段为分组排序操作。上层的操作算子(例如join),驱动子节点调用get_next方法(表扫描方法)获取一条元组。底层操作算子(表访问方法,handler接口定义)将数据返回。至此,我们可以总结一下MySQL体系的工作原理:查询执行计划由MySQL server层生成,存储引擎受执行计划驱动而访问表。MySQL的handler已经定义好表的访问方法,实现了这些访问方法的存储引擎就可以作为MySQL的插件式引擎而存在。

下面我们对spider的读写流程结合server层代码进行分析。

图7. 查询计划树示例

4.1 SELECT操作

上面提到spider的作用类似一个proxy,本身并不存储数据。因此spider处理SELECT语句(UPDATE与DELETE类似)首先需要根据查询解析的信息生成一个SELECT语句,发送到查询涉及的后端节点,将数据从远端拉到本地,然后进行处理。函数spider_db_append_select_columns根据查询涉及的读集以及写集获取相应的字段,构造一个SQL语句从后端节点拉取数据到本地。如果涉及多个分片, spider将从不同实例获取过来的结果集存放在不同的结果集spider_db_result中。类spider_db_fetch 提供了fetch_next, current_row等方法供上层方法调用。Server层调用get_next方法驱动引擎层获取下一条数据。对于表访问方法,MySQL 实现了索引扫描(ha_index_read)与随机访问(ha_rnd_next)的方法。对于切分为多个分片的DB,索引扫描需要借助优先队列。索引扫描需要区分是否是第一次调用该方法。如果是第一次调用该方法,需要遍历所有的分片读取一条记录,然后插入到优先队列。对应到spider,如果第一次调用访问远端实例表的方法,需要生成SELECT语句,将远端实例的数据拉到本地存放。在使用索引扫描的情况,MySQL 为每个分片保留一个key buffer以及record buffer。server利用队列头部的m_top_entry 获得访问的分片ID。接着,调用get_next方法获取相应的元组,将返回的数据存放在record buffer,并插入到优先队列。函数最后将元组从优先队列返回。为缓解内存等资源的压力,spider实现全表扫描的方法是逐个分片串行扫描(为了加速,spider也提供了并行扫描数据节点的选项)。图8给出了spider对于上述两种表访问方法的实现机制。

图8-1.索引扫描实现

图8-2. 全表扫描

4.2 INSERT操作

MySQL的handler类对于INSERT操作提供的接口函数的名字是write_row。存储引擎想要支持INSERT操作就必须实现write_row方法。Spider对于write_row方法的实现是简单地根据查询解析的信息拼接一条INSERT语句,发往后端节点处理。如果是批量插入操作则需要与MySQL Server层配合,将INSERT语句批量发到后端节点。图9结合一条批量插入的INSERT语句给出MySQL中INSERT操作的具体实现。mysql_insert调用write_row执行具体的插入操作(第8行)。这是存储引擎必须实现的方法。对应于spider,spider根据查询涉及到的列(field)拼成一条INSERT语句(如果是分片数据库,VALUSE中的列必须包含分区键,分区键是自增列的情况除外)。图8中的QUERY将用户ID(ID)和用户名(Name)插入到user表,其中ID是分区键。mysql_insert根据VALUES包含的元组数目,判断是否需要进行批量插入操作。该例子的QUERY的VALUES包含4条元组,所有需要进行批量插入操作。MySQL循环调用write_row方法触发spider生成INSERT语句。Spider的write_row方法实现中会根据分区键将INSERT语句进行分组(第5行~第9行)。图8给出的实例只有两个数据分片,所以SQL语句被分成两组。处理完VALUES以后,spider的INSERT语句也拼接完成。ha_end_bulk_insert方法通知spider完成VALUES处理。此时,spider将INSERT发送到后端节点进行处理(第11行)。

图9. spider中INSERT操作的实现

4.3 DELETE实现

Spider想要支持DELETE操作必须实现MySQL handler类提供的ha_delete_row方法。与INSERT操作不同,DELETE操作需要生成一条SELECT语句将查询涉及的分区键拉到spider节点。这是因为MySQL Server层的“once-a-tuple”的查询执行模型(实际上基本所有的关系数据库系统都采用该模型)会驱动spider逐个拼接DELETE语句,然后发往后端节点。这时候,spider需要知道对应的DELETE语句该往哪个后端节点发送。为了减少网络开销,spider提供了批量发送DELETE语句的功能。

图10给出了spider中delete的实现。MySQL server层首先确定表的访问方法:采用索引扫描或者全部扫描(第5行)。DELETE方法需要执行一次查找操作,调用get_next方法(info.read_record)获取一条元组(第10行)。Spider需要判断是否第一次调用get_next方法。如果是的话,则需要生成SELECT语句,将数据节点的数据拉到本地。否则,spider直接从本地返回数据给上层调用者。接下来,server层调用ha_delete_row方法将数据删除。这是存储引擎需要具体实现的方法。由于Spider本身并不存储数据的缘故,其实现delete操作的主要思想是利用从后端节点拉取过来的数据(分区键,过滤条件等),拼接成一条DELETE语句。然后,发送该请求到数据节点。Spider为了优化网络开销,提供了批量发送DELETE语句的选项。

UPDATE操作的实现类似DELETE,都需要spider生成SELECT语句从后端节点拉取数据。只不过,UPDATE在更新区分键的时候,可能需要多一次DELETE操作(删除原来分区的数据,将新的数据插入到不同的分区)。

图10. DELETE实现

5.总结

Spider的最大亮点是为MySQL的使用者提供分库分表的中间件解决方案,同时在SQL语法上兼容MySQL。这得益于spider作为MySQL的插拔式引擎而存在。 Spider 是一个proxy,其本身并没有存储数据,因此上层的读写表请求需要转换成SQL语句,重新路由到后端的数据节点。相比其它的中间件解决方案,spider的查询解析次数都是两次,并没有过多开销。此外,spider还针对聚集、排序等操作提供了MAP REDUCE的解决方案。总而言之,从兼容性、性能上衡量,spider是MySQL分库分表的一个不错的选项。

mysql 读写引擎_揭秘MySQL存储引擎spider相关推荐

  1. mysql 主从 不一致_揭秘MySQL主从数据不一致

    前言: 目前MySQL数据库最常用的是主从架构,大多数高可用架构也是通过主从架构演变而来.但是主从架构运行时间长久后容易出现数据不一致的情况,比如因从库可写造成的误操作或者复制bug等,本篇文章将会详 ...

  2. 诸葛io的技术架构图_【总结】MySQL技术内幕二:InnoDB存储引擎技术特性

    二.InnoDB存储引擎 InnoDB是事务安全的MySQL存储引擎,通常是OLTP应用中核心表的首选存储引擎.同时,也正是因为InnoDB的存在,才使MySQL数据库变得更有魅力. 从MySQL 5 ...

  3. linux mysql数据库 架构 数据库的分类 存储引擎

    数据库的分类 mysql5.7安装rpm 基础命令      创建删除库和表     插入数据     查看表结构   查看数据 数据类型    int   char 完整性约束条 主键  多列联合主 ...

  4. MySQL 逻辑架构与常用的存储引擎

    文章目录 概述 逻辑架构示意图 Server 层功能模块 连接器 查询缓存 分析器 优化器 执行器 存储引擎层 InnoDB InnoDB 主要特性 InnoDB 引擎下的查询过程 MyISAM My ...

  5. mysql innodb和myisam区别_MySQL?存储引擎简介

    ​大家好,我是anyux.本文介绍MySQL存储引擎. 简介 相当于Linux文件系统,只不过比文件系统强大 功能 数据读写 数据安全和一致性 提高性能 热备份 自动故障恢复 高可用方面支持 引擎类别 ...

  6. 《MySQL高级篇》三、存储引擎

    文章目录 1. 查看存储引擎 2. 设置系统默认的存储引擎 3. 设置表的存储引擎 3.1 创建表时指定存储引擎 3.2 修改表的存储引擎 4. 引擎介绍 4.1 InnoDB 引擎:具备==外键== ...

  7. MySql技术内 幕:InnoDB存储引擎 读书笔记

    书名 <MySql技术内幕:InnoDB存储引擎> 作者 姜承尧 书摘 第一章:MySQL体系结构和存储引擎 定义数据库和实例: 定义数据库和实例 数据库:文件的集合,frm.MYD.MY ...

  8. MySQL(4) 索引、事务与存储引擎

    文章目录 一.MySQL 索引 1.1 索引的概念 1.2 索引的作用及缺点 1.2.1 优点 1.2.2 缺点 1.3 创建索引的原则依据 1.4 索引的分类和创建 1.4.1 普通索引 ●直接创建 ...

  9. mysql外键_mysql系列之存储引擎

    本篇主要介绍mysql的存储引擎,说明主要的几个存储引擎的特性及其差别. 一.存储引擎介绍 在这里插入图片描述 数据库存储引擎是数据库底层软件组件,数据库管理系统使用数据引擎进行创建.查询.更新和删除 ...

最新文章

  1. ubuntu18.04安装mongodb
  2. 面试高频题:Spring和SpringMvc父子容器你能说清楚吗
  3. android开发我的新浪微博客户端-用户授权页面UI篇(3.1)
  4. 第三次学JAVA再学不好就吃翔(part65)--正则表达式
  5. 为什么Python不支持 i ++ 语法
  6. HighChat动态绑定数据 数据后台绑定(三)
  7. 批量关停azure vm_创建Azure自动化以启动Azure VM
  8. WordPress 插件机制的简单用法和原理(Hook 钩子)
  9. Linux驱动系列目录
  10. 二叉树的叶结点/ 树的深度计算
  11. oracle执行计划分析
  12. 计算机科学与因果关系,因果关系,概率和时间
  13. 物联网嵌入式STM32资料大全,超100G
  14. Technorati Grabber:获得您的Technorati排名和权限
  15. DOH(DNS-over-HTTPs)服务器搭建
  16. 网页数据获取小技巧(小白)
  17. Gazebo仿真平台模型搭建与修改
  18. 关于计算机的英语作文带翻译,关于网络的英语作文带翻译
  19. 浙大计算机学些什么,浙江大学首批招收人工智能专业 学什么,要怎么教?
  20. Flutter elevation属性名称的含义

热门文章

  1. jzoj 6302. 提高组
  2. 在 Snoop 中使用 PowerShell 脚本进行更高级的 UI 调试
  3. 算法:老鼠走迷宫问题
  4. Android -- 自定义权限
  5. [转]深入浅出Java设计模式之备忘录模式
  6. Oracle ——如何确定性能差的 SQL
  7. XML基本知识(三)
  8. 我的python学习笔记全集_我的python学习笔记
  9. 安卓app开发工具_怎么开发app软件需要多少钱?主流app开发工具盘点
  10. java 条码识别_条码识别示例代码