TiDB 源码编译之 TiProxy 篇

作者: ShawnYan 原文来源: https://tidb.net/blog/3d57f54d

no-alt

TiProxy 简介

TiProxy 是一个基于 Apache 2.0 协议开源的、轻量级的 TiDB 数据库代理,基于 Go 语言编写,支持 MySQL 协议。 TiProxy 支持负载均衡,接收来自应用程序的请求,然后将其发送到 TiDB 集群。支持自动故障转移,当后端 TiDB Server 发生故障,可以自动将连接转移到其他节点,以提高应用程序的可用性。

no-alt

TiProxy 编译

TiProxy 是轻量级组件,编译步骤很简洁,编译环境同前 《TiDB 源码编译之 TiUP 篇》 。

编译步骤如下:

git clone https://github.com/shawn0915/tiproxy --depth=1
cd tiproxy
go mod download -x
go mod tidy -v
export VERSION='v0.1.1-ShawnYan'
make

日志输出:

$ make
go build -gcflags '' -ldflags ' -X github.com/pingcap/TiProxy/pkg/util/versioninfo.TiProxyVersion=v0.1.1-ShawnYan -X github.com/pingcap/TiProxy/pkg/util/versioninfo.TiProxyGitHash=b944a8fe77a56bd39a7de3bf17d7deb1da039494' -tags '' -o ./bin/tiproxy ./cmd/tiproxy
go build -gcflags '' -ldflags ' -X github.com/pingcap/TiProxy/pkg/util/versioninfo.TiProxyVersion=v0.1.1-ShawnYan -X github.com/pingcap/TiProxy/pkg/util/versioninfo.TiProxyGitHash=b944a8fe77a56bd39a7de3bf17d7deb1da039494' -tags '' -o ./bin/tiproxyctl ./cmd/tiproxyctl

检查版本号:

$ ./bin/tiproxy -v
./bin/tiproxy version v0.1.1-ShawnYan, commit 81f4897fcf859154255adc86f875eda3f7e5c8a0
$ ./bin/tiproxyctl -v
./bin/tiproxyctl version test, commit test commit

这里遇到第一个问题, tiproxyctl 不识别 VERSION 变量,原因是在代码中出现硬编码。( Hard code in tiproxyctl#340 )

修改后,版本号获取正常。

$ ./bin/tiproxy -v
./bin/tiproxy version v0.1.1-ShawnYan, commit b944a8fe77a56bd39a7de3bf17d7deb1da039494-dirty
$ ./bin/tiproxyctl -v
./bin/tiproxyctl version v0.1.1-ShawnYan, commit b944a8fe77a56bd39a7de3bf17d7deb1da039494-dirty

TiProxy 尝鲜

TiProxy 的日志格式支持 TiDB 原生格式、 json 格式和 console 格式。 下面启动 TiProxy 服务,日志采用 json 格式和 DEBUG 级别。

./bin/tiproxy --config ./conf/proxy.toml --log_encoder console --log_level debug

tiproxy 启动后尝试连接:

mysql --comments --host 127.0.0.1 --port 6000 -u root

值得注意的是,TiDB 服务端与客户端之间默认采用非加密连接 [1] ,TiDB 启动时默认也不会生成 TLS 证书 [2] ,但是 tiproxy 启动时默认启用 tls 认证,这里为了简化测试,选择修改默认配置项,不要求配置 tls。

vi conf/proxy.toml[proxy]
require-backend-tls = false

否则会连接失败,遇到报错:

$ mysql --comments --host 127.0.0.1 --port 6000 -u root
ERROR 1105 (HY000): Unknown error%!(EXTRA string=TiProxy fails to connect to TiDB, please check network)

以及控制台打印日志:

2023/08/23 12:00:27.645 +09:00  INFO    main.proxy      proxy/proxy.go:159      new connection  {"connID": 0, "client_addr": "127.0.0.1:42944"}
2023/08/23 12:00:27.645 +09:00  DEBUG   main.proxy.conn.be.authenticator        backend/authenticator.go:135    frontend send capabilities unsupported by proxy {"connID": 0, "client_addr": "127.0.0.1:42944", "common": "CLIENT_LONG_PASSWORD|CLIENT_LONG_FLAG|CLIENT_LOCAL_FILES|CLIENT_PROTOCOL_41|CLIENT_INTERACTIVE|CLIENT_TRANSACTIONS|CLIENT_SECURE_CONNECTION|CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS|CLIENT_PLUGIN_AUTH|CLIENT_CONNECT_ATTS|CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA|CLIENT_DEPRECATE_EOF", "frontend": "CLIENT_PS_MULTI_RESULTS|CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS|CLIENT_SESSION_TRACK|CLIENT_QUERY_ATTRIBUTES|MULTI_FACTOR_AUTHENTICATION", "proxy": "CLIENT_FOUND_ROWS|CLIENT_CONNECT_WITH_DB|CLIENT_ODBC|CLIENT_RESERVED"}
2023/08/23 12:00:27.646 +09:00  INFO    main.proxy.conn.be      backend/backend_conn_mgr.go:218 connected to backend    {"connID": 0, "client_addr": "127.0.0.1:42944", "ns": "default", "backend_addr": "127.0.0.1:4000"}
2023/08/23 12:00:27.646 +09:00  DEBUG   main.proxy.conn.be.authenticator        backend/authenticator.go:200    backend does not support capabilities from proxy        {"connID": 0, "client_addr": "127.0.0.1:42944", "common": "CLIENT_LONG_PASSWORD|CLIENT_FOUND_ROWS|CLIENT_LONG_FLAG|CLIENT_CONNECT_WITH_DB|CLIENT_LOCAL_FILES|CLIENT_PROTOCOL_41|CLIENT_INTERACTIVE|CLIENT_TRANSACTIONS|CLIENT_SECURE_CONNECTION|CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS|CLIENT_PLUGIN_AUTH|CLIENT_CONNECT_ATTS|CLIENT_DEPRECATE_EOF", "proxy": "CLIENT_ODBC|CLIENT_RESERVED|CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA", "backend": "CLIENT_SSL"}
2023/08/23 12:00:27.646 +09:00  INFO    main.proxy.conn client/client_conn.go:61        new connection failed   {"connID": 0, "client_addr": "127.0.0.1:42944", "proxy-protocol": false, "backend_addr": "127.0.0.1:4000", "quit source": "proxy error", "error": "require TLS config on TiProxy when require-backend-tls=true"}

使用 TiUP 启动 TiProxy

TiUP 下个版本应该就会包含这个功能,感谢 @xhebox 大佬的贡献,得以让我们使用 tiup 来调用 tiproxy 组件,这里先抢先体验一下如何使用 tiup playground 启动 tidb 和 tiproxy,当然 tiup cluster 也是支持的。

由于含有该功能代码的 tiup 还没发布,所以需要自行编译 tiup,编译步骤可参考 《TiDB 源码编译之 TiUP 篇》 。

编译后的 tiup 版本信息如下:

$ tiup --version
1.12.5 tiup
Go Version: go1.21.0
Git Ref: master
GitHash: a9580bd

tiproxy 组件尚未发布到官方的镜像库,所以要想使用 tiup 调度 tiproxy 组件,需要先将 tiproxy 包上传至当前使用的 tiup 镜像库,这里使用的是本地镜像库,使用如下命令进行上传:

tiup mirror publish tiproxy v0.1.1 ./tiproxy.tar.gz tiproxy --desc tiproxy
tiup mirror publish tiproxy nightly ./tiproxy.tar.gz tiproxy --desc tiproxy

具体操作步骤可参考 《TiUP:TiDBAer 必备利器》 ,提示,需要同时提交 nightly 版本,否则会提示错误信息。

Error: Playground bootstrapping failed: component tiproxy doesn't have nightly version on platform linux/amd64

上述步骤完成后,可以看到 tiup-playground 已经增加了 tiproxy 相关选项。

$ ./tiup-playground --version
tiup version 1.12.5 tiup
Go Version: go1.21.0
Git Ref: master
GitHash: a9580bd$ ./tiup-playground --help | grep tiproxy
--tiproxy int                      TiProxy instance number
--tiproxy.binpath string           TiProxy instance binary path
--tiproxy.config string            TiProxy instance configuration file
--tiproxy.host host                Playground TiProxy host. If not provided, TiProxy will still use host flag as its host
--tiproxy.port int                 Playground TiProxy port. If not provided, TiProxy will use 6000 as its port
--tiproxy.timeout int              TiProxy max wait time in seconds for starting, 0 means no limit (default 60)

启动演示如下:

tiup playground 7.0 --tag 7.0 --without-monitor --tiflash 0 --tiproxy 1

no-alt

通过端口 6000 连接 tiproxy:

no-alt

到此,tiproxy 已经启动成功,并成功通过 tiproxy 连接到后端 tidb 集群。由于篇幅有限,tiproxy 的功能演示、测试内容另行成文。

期许

1. 源码 repo 命名小写

目前的 repo 名为 [pingcap/TiProxy],建议改为小写 pingcap/tiproxy ,统一命名方式。 毕竟是 pingcap/tidb 而非 [pingcap/TiDB],是 tikv/tikv 而非 [tikv/TiKV],是 tikv/pd 而非 [tikv/PD]。

2. tiproxy 端口非 4000

我相信大家已经达成共识,端口 4000 就是 TiDB Server 的默认端口,所以真的不建议在 tiproxy 和 tidb server 同时启动时,将 tidb server 的端口改成其他端口,而将 tiproxy 的端口改成 4000。AskTUG 论坛中有相关贴子: 闲聊贴 | 数据库端口的问题

3. tiproxy 可以独立启动

对 TiDB 深入了解的同学都知道,TiDB 的三大核心组件 TiDB Server / TiKV / PD 都可以独立启动。希望 TiProxy 也可以做到这点,不依赖 PD 也可以独立启动,而不是找不到 PD 就原地“躺平”,无时间限制不断重试连接 PD。

[2023/08/22 11:47:46.122 +09:00] [WARN] [main.infosync.etcdcli] [v3@v3.5.6/retry_interceptor.go:62] [retrying of unary invoker failed]  [target=etcd-endpoints://0xc000802380/127.0.0.1:2379] [attempt=0] [error="rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing dial tcp 127.0.0.1:2379: connect: connection refused\""]
[2023/08/22 11:47:46.122 +09:00] [INFO] [main.infosync.etcdcli] [v3@v3.5.6/client.go:210] [Auto sync endpoints failed.]  [error="context deadline exceeded"]

tiproxy 连接 pd 异常时,通过客户端连接 6000 端口会报错:

$ mysql -uroot -hlocalhost -P6000
ERROR 1105 (HY000): Unknown error%!(EXTRA string=No available TiDB instances, please check TiDB cluster)

4. 包版本升级

建议升级包的版本,比如 【 go 1.19 】 升级到 【go 1.21】,跟核心组件对齐,参考帖子:【 Announcing upgrade to Go 1.21 】。

还有其他包,比如:

github.com/go-mysql-org/go-mysql v1.6.0
github.com/pingcap/tidb v1.1.0-beta.0.20230103132820-3ccff46aa3bc
github.com/pingcap/tidb/parser v0.0.0-20230103132820-3ccff46aa3bc

相关 Issue 如, upgrade go-sql-driver/mysql version to v1.7.1#2246 。

5. 监控面板

TiProxy 已经提供了一些 API 来对其进行管理,但还是期望可以有一个极简的 Web 页面来达到可视化的目的。 毕竟 HAProxy 有 http://localhost:9999/haproxy-status , ProxySQL 也有 http://localhost:6080 。 甚至,TiDB Lightning 都有 http://localhost:8289 ,参见文档: TiDB Lightning Web 界面 。

6. 操作系统支持

由于 tiproxy 尚未上载到 tiup mirror,所以想要测试 tiproxy 只能从 github repo asset 下载,或者自行编译。测试 github 上的包时发现,在 CentOS 7 上无法运行,相关讨论帖参见: tiproxy 无法使用 。 这只是一个点,tiproxy 兼容性测试也要加油啊。

no-alt

7. 编译参数

建议加上 make clean 选项,或者 make file 可以再完善一下,如果能做到像 tiup 那样一个 make 命令搞定就很棒了。( support make clean option#343 )

另外,希望将环境变量 GO111MODULE="on" 也写进 make file。

8. 错误日志

error code 建议细化一下,不然使用者真的容易 UNKNOWN

ERROR 1105 (HY000): Unknown error%!(EXTRA string=TiProxy fails to connect to TiDB, please check network)

有些日志的告警级别希望调整一下,比如查询错误现在是 DEBUG ,可以改为 WARN ,或者单独输出到一个日志文件。

2023/08/22 23:51:33.138 +08:00    DEBUG    main.proxy.conn.be    backend/backend_conn_mgr.go:283    got a mysql error    {"connID": 0, "client_addr": "127.0.0.1:41942", "ns": "default", "error": "ERROR 1105 (HY000): conflict hypo index name hypo_a", "cmd": "Query"}2023/08/22 23:59:08.745 +08:00    DEBUG    main.proxy.conn.be    backend/backend_conn_mgr.go:283    got a mysql error    {"connID": 0, "client_addr": "127.0.0.1:41942", "ns": "default", "error": "ERROR 8108 (HY000): Unsupported type *ast.DropProcedureStmt", "cmd": "Query"}

此外,开启 DEBUG 日志后,有大量的 main.infosync.etcdcli 日志输出,每 3s 打印一次,建议优化掉。

2023/08/22 23:59:02.799 +08:00    DEBUG    main.infosync.etcdcli    v3@v3.5.6/retry_interceptor.go:53    retrying of unary invoker  {"target": "etcd-endpoints://0xc000980000/127.0.0.1:2379", "attempt": 0}

总结

据说 TiProxy 的云化版本已经用在了 TiDB Cloud 中,期待 TiProxy 早日 GA,并且最终可以到达能够替换 HAProxy 或 ProxySQL 的水准。

附:

no-alt

End.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/54909.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【滑动窗口】leetcode209:长度最小的子数组

一.题目描述 长度最小的子数组 二.思路分析 题目要求:找出长度最小的符合要求的连续子数组,这个要求就是子数组的元素之和大于等于target。 如何确定一个连续的子数组?确定它的左右边界即可。如此一来,我们最先想到的就是暴力枚…

Linux 多线程基础

文章目录 前言一、多线程基础函数1. pthread_create2. pthread_self3. pthread_exit4. pthread_join5. pthread_cancel6. pthread_detach 二、线程间的共享数据三、多线程 &#xff0c;进程对比总结 前言 一、多线程基础函数 1. pthread_create 创建新的线程。 #include <…

使用EventLog Analyzer 进行路由器监控

路由器是任何计算机网络的构建块&#xff0c;引导网络中的流量&#xff0c;管理员需要确保路由器已配置并正常工作&#xff0c;以确保网络安全。 监控路由器中的用户活动 在网络安全方面&#xff0c;与路由器相关的风险是一个严重的问题。具有松散安全策略的网络使入侵者可以…

kafka--技术文档--基本docker中安装<单机>-linux

安装zookeeper 阿丹小科普&#xff1a; Kafka在0.11.0.0版本之后不再依赖Zookeeper&#xff0c;而是使用基于Raft协议的Kafka自身的仲裁机制来替代Zookeeper。具体来说&#xff0c;Kafka 2.8.0版本是第一个不需要Zookeeper就可以运行Kafka的版本&#xff0c;这被称为Kafka Raf…

3 自制一个集群分发脚本

1. 随便取了一个名字&#xff1a;xsync 2. 在一个配置环境变量的目录下&#xff0c;我是放在了/opt/software下&#xff0c;这个路径我是配置了环境变量的。 3. 编辑脚本&#xff1a;vim xsync #!/bin/bash#1. 判断参数个数 if [ $# -lt 1 ] thenecho Not Enough Arguement!…

【⑮MySQL | 视图】概述 | 创建 | 查看 | 更新 | 修改 | 删除

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL视图概述 | 创建 | 查看 | 更新 | 修改 | 删除的分享✨ 目录 前言1.视图概述2.创建视图3.查看视图4.更新视图数据5.修改视图6.删除视图总结 1.视图概述 1.1 为什么使用视图&#xff1f; 视图一方面可以帮我们使…

如何构建多域名HTTPS代理服务器转发

在当今互联网时代&#xff0c;安全可靠的网络访问是至关重要的。本文将介绍如何使用SNI Routing技术来构建多域名HTTPS代理服务器转发&#xff0c;轻松实现多域名的安全访问和数据传输。 SNI代表"Server Name Indication"&#xff0c;是TLS协议的扩展&#xff0c;用于…

2023年国赛 高教社杯数学建模思路 - 案例:随机森林

文章目录 1 什么是随机森林&#xff1f;2 随机深林构造流程3 随机森林的优缺点3.1 优点3.2 缺点 4 随机深林算法实现 建模资料 ## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林&#xff…

数据结构(Java实现)-二叉树(下)

获取二叉树的高度 检测值为value的元素是否存在(前序遍历) 层序遍历 判断一棵树是不是完全二叉树 获取节点的路径 二叉树的最近公共祖先

Docker基本部署和相关操作

1.安装docker服务&#xff0c;配置镜像加速器 1、yum安装并且添加源信息 yum install yum-utils device-mapper-persistent-data lvm2 -y yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo2、修改一些配置信息 sed…

Kaggle回归问题Mercedes——Benz Greener Manufacturing

目录 前言1 题目介绍2 数据清洗3 数据可视化分析4 模型训练5 源码 前言 这是我在大三选修课的课程设计&#xff0c;内容参考了Kaggle上高赞的代码&#xff0c;有详细批注&#xff0c;整体比较基础&#xff0c;结构相对完整&#xff0c;便于初学者学习。这个是一个回归问题&…

⌈算法进阶⌋图论::拓扑排序(Topological Sorting)——快速理解到熟练运用

目录 一、原理 1. 引例&#xff1a;207.课程表 2. 应用场景 3. 代码思路 二、代码模板 三、练习 1、210.课程表Ⅱ&#x1f7e2; 2、2392.给定条件下构造举证&#x1f7e1; 3、310.最小高度树 &#x1f7e1; 一、原理 1. 引例&#xff1a;207.课程表 就如大学课程安排一样&…

21.2 CSS 三大特性与页面布局

1. 开发者工具修改样式 使用开发者工具修改样式, 操作步骤如下: * 1. 打开开发者工具: 在浏览器中右键点击页面, 然后选择检查或者使用快捷键(一般是 F12 或者 CtrlShiftI)来打开开发者工具.* 2. 打开样式编辑器: 在开发者工具中, 找到选项卡或面板, 一般是Elements或者Elemen…

【Go Web 篇】从零开始:构建最简单的 Go 语言 Web 服务器

随着互联网的迅速发展&#xff0c;Web 服务器成为了连接世界的关键组件之一。而在现代编程语言中&#xff0c;Go 语言因其卓越的性能和并发能力而备受青睐。本篇博客将带你从零开始&#xff0c;一步步构建最简单的 Go 语言 Web 服务器&#xff0c;让你对 Go 语言的 Web 开发能力…

线性代数的学习和整理14: 线性方程组求解

目录 1 线性方程组 2 有解&#xff0c;无解 3 解的个数 1 线性方程组 A*xy 3根直线的交点&#xff0c;就是解 无解的情况 无解&#xff1a; 三线平行无解&#xff1a;三线不相交 有解 有唯一解&#xff1a;三线相交于一点有无数解&#xff1a;三条线重叠 2 齐次线性方程组…

Vue的使用

Vue的使用 Vue到底是啥&#xff1f;Vue中包含了两部分虚拟DOM 模块化编程虚拟DOM&#xff0c;在我们重用模板的时候&#xff0c;在Vue中存在虚拟DOM 虚拟DOM是为了更好的去重用我们的DOM (增加元素的时候&#xff0c;先去虚拟DOM找是否存在&#xff0c;如果有那么不用生成&am…

VUE笔记(六)vue路由

一、路由的简介 1、实现生活中的路由 路由&#xff1a;路由其实就是一个key-value对应关系 路由器&#xff1a;用于管理多个路由关系的设备被称为路由器 2、前端的路由 目前使用的前端项目都是单页面的应用&#xff08;SPA&#xff09;&#xff0c;一个项目中只有一个html页…

c语言中编译过程与预处理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、c语言的编译与链接1、编译与链接概述2、编译与链接详解 二、c语言预处理1.c语言中内置的预定义符号2、#define定义标识符3、#define定义宏4、#define 替换规…

CSS scoped 属性的原理

scoped 一、scoped 是什么&#xff1f;二、实现原理 一、scoped 是什么&#xff1f; 在 Vue 组件中&#xff0c;为了使样式私有化&#xff08;模块化&#xff09;&#xff0c;不对全局造成污染&#xff0c;可以在 style 标签上添加 scoped 属性以表示它的只属于当下的模块&am…

数组和指针练习解析(6)

题目&#xff1a; int main() { char *c[] {"ENTER","NEW","POINT","FIRST"}; char**cp[] {c3,c2,c1,c}; char***cpp cp; printf("%s\n", **cpp); printf("%s\n", *--*cpp3)&#xff1b; printf("%s\n&…