原文来源: https://tidb.net/blog/bf9f3adc

作者介绍:

徐成选,伴鱼基础架构负责人。后端8年,基础架构6年,传统、互联网行业均有涉猎,曾就职于小米、阿里、初创公司等,目前在伴鱼负责基础架构团队,从0到1组建了伴鱼服务器基础架构、大数据基础架构和数据应用等团队。

本篇文章整理自 TiDB 的 TOC 成员、伴鱼基础架构负责人徐成选在 PingCAP Infra Meetup 上的演讲实录,演讲视频回顾可以在 这里 观看。 本文主要介绍了伴鱼基于 TiDB 自主开发的数据库中间件 Weir 的技术细节,文章将从 Weir 系统架构、核心特性、未来规划等三个方面进行分享。

背景概况

伴鱼从 2018 年开始 all in TiDB。但伴鱼在使用 TiDB 的过程当中遇到一系列 TiDB 早期的问题,比如不合理的 SQL(应用上有问题的 SQL )、索引失效(有索引,但是它不走索引)等。这些问题会带来数据库不可用或者恢复特别慢等情况,对于伴鱼来说是比较严重的。

伴鱼是基于互联网的在线学习平台,在线教育这个行业比较特殊,有明显的流量波峰和低谷,在上课时如果出现问题,不是简单地恢复服务就可以,它是要赔钱的,不但要赔钱,老师的工资还要照付,这个是比较棘手的问题。

于是伴鱼就在想如何尽量提高数据库的稳定性,解决这类问题。直接能想到的解决方法是基于伴鱼的 SDK 进行包装。

基于 SDK 进行包装,能够精准到库表级别进行控制,但是要是精准到 SQL 范式级别是很困难的。它能解决一部分问题,但不足之处有以下三个方面:

  • 第一,熔断粒度不够细。不能精确到 SQL 范式或者叫 SQL 指纹层面。
  • 第二,影响范围不可控。基于 SDK 做包装,很多服务集成了 SDK,分别去做熔断,可能大家的配置都一样,但是因为分散在各个服务的实例里面,其范围是比较大的,对于保护 TiDB 来讲效果上会有一定的折扣。
  • 第三,多语言如何兼容。公司内的算法团队经常有 Python 、 Java 的程序需要访问数据库,也有熔断的需求。

所以后面就想将熔断能力下沉到中间层,架构形式如下图:

上述 架构带来了许多优点

  • 第一,可以按照库表进行熔断。
  • 第二,可以按照 SQL 的范式或指纹统一熔断,这样控制力更充足,并且控制的粒度也足够精细。
  • 第三,能够满足多语言的诉求。

同时,如果某一 SQL 范式出现了熔断,但其他 SQL 范式,就算对应相同的表,也是可以正常通过的。熔断之后误杀的几率或者范围会更小。

基于此思想,伴鱼开发出了一款不一样的开源数据库中间件—— Weir。

为什么说 Weir 是不一样的数据库中间件呢?

  • 首先, Weir 是面向 NewSQL 的。
  • 其次, Weir 是一款侧重数据库治理的中间件。

当然,它同样具有分库分表解决容量问题(基于 TiDB)以及作为连接池保护数据库的能力。

Weir 的系统架构

组件构成

Weir 主要分为三部分。

从图中可以看到标黄的部分是 Weir 的三个组件

  • 最左边的 DB platform,是 Weir 的 web 管控平台。
  • 中间是 Weir Controller,主要负责一些代理的配置或者后端TiDB的配置管理。
  • 最主要的部分是 Weir Proxy,主要承接线上 SQL 流量。伴鱼在这薄薄的一层 Proxy 做了很多功能,包括路由、熔断、限流、SQL Waf 等。SQL Waf 主要是指限定某类 SQL 请求,比如某些有 update 或者 delete 操作,但是又不带着 where 条件的请求。当然还可以做更多的功能,像影子库压测之类的。

配置管理的部分,有加载配置,还有触发配置变更等操作,这个主要与配置的形式有关。伴鱼把配置存在 etcd 里面,但是没有用其 Watch 机制,更多是采用主动触发的方式发一遍通知,同时得到配置变更的反馈以及验证配置的指纹来保证所有实例的配置保持一致。

模块构成

下面将分别介绍这三个组件。上面是从请求的角度分析,这里是从模块的层次角度再把 Proxy展开一下。

最上层是各个应用,包括了 Go、Java 等语言,最底层是 DB 层,是 TiDB 的各个集群。中间是 Weir 的几个关键组件,右边标蓝的三部分是周边管理组件,包括监控、Web 平台、管控服务等,最左侧中间这一块是 Weir 的 Proxy 层。

最上面的部分由会话层做连接接入,最下面有后端连接池,以起到保护的作用。中间上下行都会涉及到 MySQL 协议解析层,因为伴鱼主要用 TiDB,所以这里以 TiDB 为例展开讲。

中间会有租户授权的功能,这里除了做 MySQL 协议的握手,还会有租户的分配,再就是 SQL 解析。在 SDK 层面,想做 SQL 解析是比较重的,但是在 Proxy 层,SQL 解析就比较好做一些。

图中间橙色的部分就是功能层。当伴鱼做了以上各种功能以及 SQL 解析之后,还要把请求转发到后面。 Proxy 基于 SQL 的状态机来驱动逻辑处理 ,比如根据事务开启的状态及其当前的状态,以及接到的命令决定下一步做什么,失败的时候转到什么状态等,基于这样状态机去驱动请求直接转发到后端。

绿色代表请求方向,浅蓝色代表应答方向。这个过程和传统的 MySQL 中间件的还不太一样,许多传统的中间件在结果处理的时候会做结果的拼接。而 Weir 没有那么重,它可以直接判断结果的类型,除了网络错误,还可以根据 MySQL 逻辑层面的 Error Packet 进行错误计数触发熔断。不管是 TiDB 还是 MySQL 都会有 text 文本类型的应答以及 binary 应答,处理两种逻辑(分库分表时)还是比较麻烦的。但是在 Weir 里面不需要做这类事情,因为不需要做结果拼接。

Weir 的核心特性

Weir 有 四个核心特性

  • 第一,柔性多租户,区别于 K8s 这种会分配物理资源。
  • 第二,自适应的熔断和限流,这个功能是打造 Weir 这个项目的初衷。
  • 第三,连接池,这个是一般中间件都会有的功能。
  • 最后,周边 SQL 的统计、监控,比如一些基于 SQL 的统计可以做像 SQL 审计等功能。

柔性多租户

这里有几个概念:第一,把 Namespace 作为租户,同时,Weir 的集群可以有多个租户。这样一来,一套 Weir Proxy 集群可以代理多个 TiDB 的集群,部署起来会更加简单。

第二,租户的资源,每个租户对应一个 TiDB cluster,一个 TiDB cluster 可以对应多个租户。这里的意思是,租户代表 TiDB 集群,当 TiDB 集群被多个应用访问的时候,也可以分配多个 Namespace 来分别被不同的应用去使用。

第三,租户的关联。MySQL 在认证的时候有几个要素,用户名、密码、IP 等等,Weir 是根据用户来绑定到租户的。伴鱼没有相同的用户名,不存在用户名冲突的现象,也可以做成根据用户名加密码来绑定租户。

自适应的熔断与限流

熔断过程本质上归纳为三个状态机: 开启状态、关闭状态、半开启状态 。半开启状态是指,触发了熔断之后要有恢复过程,不能一直熔断。

下图是 Weir 的 SQL 熔断过程,图中标注了熔断的粒度。Weir 与基于 SDK 的熔断最不一样的一点是:能够精确到 SQL 范式的精度,粗粒度可以达到 Namespace 的级别。

图中最上面是正常的请求,后面开始产生一些报错。这个报错有两类,一类是网络报错,第二类当前没有做,但可以基于 MySQL 的 Error packet 来做逻辑上的报错统计。

当报错达到到一定次数的时候,就开始触发熔断(中间红色部分)。触发熔断之后,请求在 Proxy 层会返回固定的错误,而不会打到后端的 TiDB cluster。同时,熔断触发之后可以尝试去看有无恢复,如果没有恢复,即仍停留在熔断状态,继续阻断往 TiDB 的请求。

如果发现 TiDB 慢慢恢复了,可以开始继续往下走正常的流程,然后转发到 TiDB 集群,这里跟伴鱼在 RPC 层面的熔断是类似的,起到防止雪崩、防止事情变得更坏的作用。这避免了之前出现的直接把集群 CPU 打满、恢复特别慢的问题,一有间歇性报错,就立刻恢复了,剩下的需要去找原因。限流的情况也是类似的,这里就不展开了。

连接池

连接池在中间件里面很通用,但是他们之间又有所不同,左边是普通命令的连接池,右边是事务 + Prepare 的连接池。大家如果了解 MyCat 这一类中间件会发现它们对于 Prepare 也会单独做处理,尤其是涉及到分库分表。

  • 普通命令连接池

先讲普通命令,普通命令是当请求从客户端进来之后,获取到了连接,然后可以去后端 TiDB 集群对应的连接池中,任意取得一个连接,比如前端可能是 1,后端可能取的是 26,然后来完成请求,再应答就可以了。但是对于事务的连接来讲就不一样了,因为事务是有状态的,这时候就需要持有这个事务,所以下图右边就不太一样,前面拿到 1,后面可能就一直要以 client 1‘ 这样的连接来处理事务里面的 SQL 语句。

  • 事务 + Prepare 连接池

在事物 + Prepare 连接中,Prepare 是二进制协议的,跟普通的 Query 比如 SQL 还不太一样,如果是在分库分表中实现 Prepare,往往是在每个命令 Prepare 阶段的时候 session 持有这个连接,在执行阶段将其转成文本协议走分库分表的判断逻辑。如果不这样做,Prepare 就会有一坨分库分表的逻辑处理,转化成文本协议和直接处理 prepare 的分库分表逻辑都是比较复杂的。但是因为 Weir 不做分库分表,所以我们可以简化处理,Prepare 的前后端连接处理与事务连接处理保持一致。绑定连接后对于 Prepare 各阶段的每个命令都是直接转发,最后关闭连接,实践起来很简单,并且正确性容易验证,最重要的是不涉及协议的转换,也就是文本协议和二进制协议互相转的问题。

成熟的管控平台

以下将分享一下我们的管控平台。有了这样的管控平台,可以做到流程化和规范化,业务在平台申请,DBA 在平台上分配,分配完成后,业务可以拿着平台提供的信息去使用。同时平台还可以提供监控的链接,可以直接跳转查看 Namespace 的监控情况。

SQL 的统计监控的这里有两部分,一是 Proxy 集群本身的监控,如 QPS、时延、Namespace 、连接数、报错等。

下面是某 Namespace 的监控,里面也包含了具体业务的表,QPS、SQL 的连接数、事务的数量等等一些统计,对于排查问题提供了很大的便利。

Weir 的未来规划

前面主要介绍了 Weir 的功能特性,下面主要介绍一下 Weir 的未来规划。下图蓝色的部分是伴鱼当前已经实现的功能,绿色是当前正在做的一些功能,黑色是未来要做的事情。

首先,Waf 功能。当需要针对某个 SQL 范式做禁止的时候,DBA 就可以在 Web 平台上配置、下发,之后可以针对这个 SQL 去做禁止。或者,当 update 或者 delete 操作时没有带 Where 条件,默认不予执行。

第二,多机房的感知和路由,在机房双活路由的时候感知本地机房能够提升一部分效率。

正在做的有 SQL 的审计、慢 SQL 的统计、影子库压测等。影子库压测是比较有用的特性,现在压测经常需要造一批假数据单独标记出来,或者要做单独的 TiDB 集群等等,但是如果有影子库压测的话一方面业务可能感知不到这些事情,另外管理上会更加集中和方便。

最后是部署形态上,Weir 还想做 Database 的 mesh 层,进一步往云原生靠,这能够带来一些性能的提升,这也是未来行业发展的一个趋势。

结语

Weir 的 GitHub 地址是 https://github.com/tidb-incubator/weir,伴鱼整个的开发过程是基于这个仓库来完成的,这个项目跟伴鱼内部用的是完全一样的,感兴趣的同学可以关注。

拓展阅读

  • 伴鱼与 PingCAP 达成战略合作 推动开源社区生态共建
  • 伴鱼数据库选型的思考,为什么我们 all in TiDB
  • TiDB X 伴鱼 | 「宁花机器一分,不花程序员一秒」,用户增幅 300% 背后的秘密武器

? 更多 TiDB、TiKV、TiSpark、TiFlash 等技术问题可登录 AskTUG.com ,与全球 TiDB User 随时随地交流使用心得~ 另外,AskTUG 「 认证功能 」最新上线,完成团队认证可额外获得 +200 经验值和 200 积分 ,授予 “认证会员”徽章。更有问题处理「 加急 」特权等你~详情了解请点击「 阅读原文 」!

Ps:发布技术文章可获得100-200经验值及积分奖励。内容深度、文章结构完整度、图文并茂都是加分项哟~

Weir:原生 TiDB 支持的数据库中间件相关推荐

  1. 数据库中间件漫谈——看看云时代,它会走向何方

    来源 | 阿丸笔记 封图| CSDN 下载于视觉中国 前言 随着业务的发展,MySQL数据库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作的开销也会越来越大:另外,无论怎样升级硬件资源, ...

  2. 云原生在京东丨ASF顶级分布式数据库中间件项目——Apache ShardingSphere

    云妹导读: 不知不觉[云原生在京东]已经进行了两期,在先前<云原生在京东丨揭秘五大云原生项目在京东的落地实践>和<云原生在京东丨最适合云原生的分布式存储平台--ChubaoFS> ...

  3. 数据库中间件支持数据库集群方案

    咏南数据库中间件支持数据库集群方案 通过咏南数据库中间件作为PROXY(数据库代理)实现的数据库集群,非数据库层面集群. 数据库可以分库分表进行水平或垂直拆分成数据库集群. 咏南中间件作为数据库集群代 ...

  4. java中间件是什么意思_数据库中间件漫谈

    1.前言 随着业务的发展,MySQL数据库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作的开销也会越来越大:另外,无论怎样升级硬件资源,单台服务器的资源(CPU.磁盘.内存.网络IO.事 ...

  5. 分布式数据库实战第六节 数据库中间件的研究

    21 知识串讲:如何取得性能和可扩展性的平衡? 这一讲我们来总结一下模块三.经过这个模块的学习,相信你已经对分布式数据库中分布式系统部分常见的技术有了深刻的理解.这是一节知识串讲的课,目的是帮助你将所 ...

  6. 开源分布式数据库中间件

    转自:https://www.csdn.net/article/2015-07-16/2825228 MyCat:开源分布式数据库中间件 为什么需要MyCat? 虽然云计算时代,传统数据库存在着先天性 ...

  7. 数据库中间件MyCat学习总结(1)——MyCat入门简介

    为什么需要MyCat? 虽然云计算时代,传统数据库存在着先天性的弊端,但是NoSQL数据库又无法将其替代.如果传统数据易于扩展,可切分,就可以避免单机(单库)的性能缺陷. MyCat的目标就是:低成本 ...

  8. (转载)MyCat:开源分布式数据库中间件

    发现MyCat这个东西,觉得还是有很多应用场合,之前为了mysql读写分离.分布等伤透脑筋,没想到有现成的中间件工具,看来很多有经验的公司是受到过折磨,才整出好工具.方法和工具的发明,总是因为问题的存 ...

  9. 手把手带你用数据库中间件Mycat+SpringBoot完成分库分表

    一.背景 随着时间和业务的发展,数据库中的数据量增长是不可控的,库和表中的数据会越来越大,随之带来的是更高的磁盘.IO.系统开销,甚至性能上的瓶颈,而一台服务的资源终究是有限的,因此需要对数据库和表进 ...

最新文章

  1. python登录网页账号密码_python03网页用户名密码登录
  2. Docker镜像制作规范
  3. 前端学习(1605):组件传值
  4. ashx一般处理程序
  5. python 包 子文件夹调用_15步,你就能拥有自己的Python程序包
  6. kali Linux Web 渗透测试视频教程— 第六课 网络扫描-nmap与zmap
  7. weex android 滑动事件,【报Bug】weex编译模式下slider组件 @scroll 事件, 滑块左右滑动, @scroll 回调的值始终是负数, 判断不了左右动作...
  8. 轻量级监控系统 - Monitorix
  9. 使用redis做缓存处理时出现的问题
  10. cad2016中选择全图字体怎么操作_PPT有哪些可以一劳永逸的操作?
  11. 基于CameraLink的串行口通讯
  12. Linux--1 初识
  13. 有关private T
  14. 大话卫星导航中的信号处理系列文章——目录
  15. 二进制+位操作 总结
  16. 打印机使用的驱动语言
  17. ubuntu从本地上传文件到云服务器、从云服务器下载文件到本地的命令(亲测有效)
  18. GVM 内存结构 垃圾回收
  19. datatables数据表格的数据csv本地导出
  20. 涨停板打开是不是下跌信号?

热门文章

  1. Fast R-CNN论文原理+目标检测笔记(二)
  2. 《论语》全译——季氏篇第十六
  3. 关于浅拷贝、深拷贝的探究
  4. 汇编语言中word ptr | byte ptr分别是什么意思
  5. 2020年系统规划与管理师上午真题及答案解析
  6. Kubernetes 忘记token解决方案
  7. 推荐系统实践读书笔记-01好的推荐系统
  8. 【论文阅读】Paraformer工业级非自回归端到端语音识别模型
  9. 辐射76 服务器位置,《辐射76》确认没有NPC 但将开放私人服务器与MOD
  10. ERROR [KafkaApi-1] Number of alive brokers ‘1‘ does not meet the required replication factor ‘2‘ for