暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

TDSQL MySQL 私有化部署体验

1581

因客户用到 TDSQL MySQL
 数据库且期望能够提供支持,所以这里也研究一下 TDSQL
 这款数据库。本文主要分享 TDSQL MySQL 10.3
数据库私有化部署。

TDSQL MySQL
 简介
 

TDSQL
 是腾讯的数据库品牌,包含很多数据库,TDSQL MySQL
 是其中一款面向 OLTP
 场景的关系型数据库,包含分布式版本(V10)和集中式版本(V8)两款。分布式版本其前身就是以前腾讯云的 DRDS
 数据库。

跟其他云厂商一样,TDSQL
 数据库类型众多,软件管控也很严格,非 TDSQL
 客户很难拿到软件。不过 腾讯云官网提供了丰富的文档(见本文原文链接)。本文测试的是网上网友分享的 TDSQL MySQL 10.3.17
 版本,相比最新的 10.3.22
版本可能有些差距。但 TDSQL MySQL
 总体架构变化不大,运维方法也基本不变。

TDSQL MySQL
采用分布式集群架构,如下图所示。该架构有多款组件组成,架构虽然复杂但也很灵活。TDSQL MySQL
的架构也经过多年积累演进,也做到了简化各个节点间通信、硬件需求,使得集中式实例、分布式实例、分析型实例可以混合部署在同一个集群中,同时也支持x86
ARM
服务器,也可以搭建类似于 IOE 架构一样稳定的分布式数据库。TDSQL MySQL
 架构前身就是分布式数据库中间件,分布式原理以前也叫“分库分表”。曾经我对这种架构在大规模集群下复杂业务下的强一致性、高可用和性能都比较怀疑,不过 TDSQL MySQL
 后来也拿到 TPC
 的 TPC-C
 测试的 TOP 1
。对于 TDSQL MySQL
 的能力也就没啥怀疑的。

TDSQL MySQL 架构

TDSQL MySQL
 只兼容 MySQL
,底层的 TXSQL
内核就是 MySQL(MariaDB
分支或者Percona MySQL
分支,腾讯数据库团队做了很多BUG修复和功能增强),开发和运维人员大多懂一些 MySQL,所以接受起来比较容易。实际的业务比 TPC-C
 更复杂但规模没有那么大,所以金融客户使用 TDSQL MySQL
的时候,大多只创建集中式实例。而在金融核心业务场景,业务逻辑反而相对简单,适合做分布式设计,当交易规模很大的时候,才会考虑用分布式实例。

TDSQL MySQL
 私有化部署有两种方法:图形化部署和命令行部署。图形化部署需要安装额外的一个组件,这里没有,所以选择的是命令行部署。推测图形化部署的原理还是调用命令行部署参数。所以更建议研究命令行部署,这可以观察到更多的部署细节和原理。TDSQL MySQL
 的命令行部署技术才用的 ansible
 自动化部署技术(这点各个大厂都有自己独特的自动化部署技术,历史积累不尽相同)。由于涉及到的组件很多,安装脚本里针对常用部署场景已经编写好了ansible playbook
的脚本。如果熟悉 TDSQL MySQL
各个组件(其中不少组件都是开源组件),也可以自己编写自定义的部署脚本。这属于高级运维技能。

TDSQL MySQL
 部署架构
 

TDSQL MySQL
测试环境的组件说明和资源要求如下。

组件名称
组件中文名
功能介绍
数量
建议配置(CPU/内存/磁盘)
LVS
虚拟负载网络
LVS
(TUN
模式),开源产品,提供负载均衡和高可用能力,为每个数据库实例提供一个 VIP。
可选,1-2台
4C8G 200G
Chitu
赤兔运维平台
提供 TDSQL Web
 化管理
1-2台,可混部
4C8G 200G
Zookeeper
/Monitor
决策集群
提供高可用和一致性能力
1或3台
4C8G 200G
Scheduler
/Manager
调度集群
提供主备切换、扩缩容、资源管理等能力
可混部
4C8G 200G
DB
数据库模块
包括 Proxy
Agent
MySQL
、存储和计算核心节点。
2*N
 或 3*N
16C64G 1T
HDFS
数据库冷备存储
提供数据库长期备份,包括 binlog
的备份,为故障恢复提供数据存储服务
1
 台或 3
 台
4C16G 6T+

在生产环境里,LVS
 建议用商用负载硬件(如 F5
A10
)替换,HDFS
 可用 NAS
 或商用对象存储替换。

在生产环境里,还要考虑多机房容灾部署。下面是常用的两地三中心部署架构图。

TDSQL 两地三中心部署架构

详细说明如下:

  • 同城双机房的数据同步使用的是 MySQL 原生的同步(TXSQL
    有增强数据复制功能),异地机房之间的数据同步使用的是DCN
     同步(也是逻辑同步,使用专用的同步软件,类似于云产品 DTS
    )。
  • 每个机房都有负载均衡设备(F5
    LVS
    ) 以及数据库访问代理 Proxy
  • 同城双机房的数据库是 1主多备
    ,可以设置是否需要强同步。异地机房的MySQL
    是 1主1备
    ,这里也有一个主,所以异地机房的同步使用的不是原生的 MySQL
     主从复制。
  • 同城双机房的 Zeekeeper
    集群跨多机房,异地机房内有独立的zookeeper
     集群。zookeeper
    集群为其他组件提供故障判断能力。zookeeper
    集群的节点数应该是奇数,否则无法在机房故障时为其他组件提供高可用能力。所以,在主机房的zookeeper
    集群在异地机房还有一个节点 zk5

各大云厂商的分布式数据库(MySQL
)的多机房部署基本上都是上面这个原理。

TDSQL MySQL
 部署步骤
 

解压缩TDSQL MySQL
的软件包会得到 3 个文件夹,每个文件夹里又有很多子文件夹,对应相关的组件。

[root@obtest tdsql_10.3.17.3.0]# tree -L 2
.
├── group_files
│   ├── tdsql_ansible
│   ├── tdsql_checkalive
│   ├── tdsql_common
│   ├── tdsql_es
│   ├── tdsql_filebeat
│   ├── tdsql_hdfs
│   ├── tdsql_jdk
│   ├── tdsql_kafka
│   ├── tdsql_lib
│   ├── tdsql_lvsmanager
│   ├── tdsql_monitorcmd
│   ├── tdsql_nginx
│   ├── tdsql_php
│   ├── tdsql_python
│   ├── tdsql_testtools
│   └── tdsql_zk
├── tdsql_install
│   ├── group_vars
│   ├── playbooks
│   ├── roles
│   ├── scripts
│   ├── tdsql_add_hosts
│   ├── tdsql_hosts
│   └── tdsql_update_hosts
└── tdsql_packet
    ├── global_version.ini
    ├── tdsql_analysis
    ├── tdsql_auto_test
    ├── tdsql_chitu
    ├── tdsql_clouddba
    ├── tdsql_collector
    ├── tdsql_consumer
    ├── tdsql_mc
    ├── tdsql_oc
    ├── tdsql_onlineddl
    ├── tdsql_oss
    ├── tdsql_scheduler
    └── tdsql_tdsqlinstall

子文件夹group_files
 下是TDSQL
 依赖组件的安装包,tdsql_packet
TDSQL
组件的安装包。这点比较好,安装过程中基本不用担心缺什么。安装脚本都在文件夹tdsql_install
 下。

[root@obtest tdsql_install]# tree -L 2
.
├── group_vars
│   ├── all
│   ├── tdsql_chitu
│   └── tdsql_newchitu -> tdsql_chitu
├── playbooks
│   ├── roles -> ../roles
│   ├── tdsql_add_chitu.yml
│   ├── tdsql_add_clouddba.yml
│   ├── tdsql_add_onlineddl.yml
│   ├── tdsql_add_scheduler.yml
│   ├── tdsql_consumer.yml
│   ├── tdsql_envcheck.yml
│   ├── tdsql_es7.yml
│   ├── tdsql_hdfs.yml
│   ├── tdsql_kafka.yml
│   ├── tdsql_lvs.yml
│   ├── tdsql_mc.yml
│   ├── tdsql_newdb.yml
│   ├── tdsql_part1_site.yml
│   ├── tdsql_part2_site.yml
│   ├── tdsql_reinstall_db.yml
│   ├── tdsql_test.yml
│   ├── tdsql_update_mysqlagent.yml
│   └── tdsql_update_tdsqlinstall_packet.yml
├── roles
│   ├── tdsql_ansible_test
│   ├── tdsql_auto_test
│   ├── tdsql_backup_chitu_init_sync
│   ├── tdsql_beginning
│   ├── tdsql_chitu
│   ├── tdsql_clouddba
│   ├── tdsql_collector_analysis
│   ├── tdsql_consumer
│   ├── tdsql_db_module
│   ├── tdsql_env_check
│   ├── tdsql_es7
│   ├── tdsql_filebeat_helper
│   ├── tdsql_filebeat_init
│   ├── tdsql_hdfs
│   ├── tdsql_hdfs_conf
│   ├── tdsql_kafka
│   ├── tdsql_lvs
│   ├── tdsql_mc
│   ├── tdsql_mc_conf
│   ├── tdsql_onlineddl
│   ├── tdsql_oss
│   ├── tdsql_proxy_module -> tdsql_db_module
│   ├── tdsql_scheduler
│   ├── tdsql_testtools
│   ├── tdsql_update_clouddba
│   ├── tdsql_update_mysqlagent
│   ├── tdsql_update_tdsqlinstall_packet
│   └── tdsql_zk_cluster
├── scripts
│   ├── conf
│   ├── environment_set
│   ├── install_ansible.sh
│   ├── ip_passwd_list
│   ├── nokey.sh
│   └── test
├── tdsql_add_hosts
├── tdsql_hosts
└── tdsql_update_hosts


这里使用的是 ansible-playbook
 技术,部署逻辑都在子文件夹playbooks
下的 yaml
文件中,部署组件对应的服务器在 tdsql_hosts
 中定义。每个组件的部署方法在子文件夹roles
 下定义,组件部署过程中用到的环境变量在子文件夹group_vas
里定义。

  • TDSQL MySQL
    部署主逻辑
[root@obtest tdsql_install]#catplaybooks/tdsql_part1_site.yml
---
-name:checkenvserver
hosts:tdsql_allmacforcheck
remote_user:root
gather_facts:false
roles:
    -tdsql_env_check
tags:envcheck

-name:installallmacbeginning
hosts:tdsql_allmacforcheck
remote_user:root
gather_facts:false
roles:
    -tdsql_beginning
tags:beginning

-name:installzk_clusterserver
hosts:tdsql_zk
remote_user:root
gather_facts:false
roles:
    -tdsql_zk_cluster
tags:zk

-name:installchituserver
hosts:tdsql_chitu
remote_user:root
gather_facts:false
roles:
    -tdsql_chitu
tags:chitu

-name:installdb_moduleserver
hosts:tdsql_db
remote_user:root
gather_facts:false
roles:
    -tdsql_db_module
tags:dbproxy

-name:installproxyserver
hosts:tdsql_proxy
remote_user:root
gather_facts:false
roles:
    -tdsql_proxy_module
tags:dbproxy

-name:installschedulerserver
hosts:tdsql_scheduler
remote_user:root
gather_facts:false
roles:
    -tdsql_scheduler
tags:scheduler

-name:installossserver
hosts:tdsql_oss
remote_user:root
gather_facts:true
roles:
    -tdsql_oss
tags:oss

  • 部署环境变量
[root@obtest tdsql_install]# cat group_vars/all |grep .
---
# scheduler,oss机器网卡
tdsql_sche_netif: ens192
# 操作系统账号tdsql的明文密码
# 如果有规划要部署两个集群做DCN同步, 则这两个集群的tdsql密码要一致
tdsql_os_pass: 123456
# tdsql在zk上的根路径, 保持默认不允许修改
tdsql_zk_rootdir: tdsqlzk
# zk机器的域名配置, 会写入各配置文件, 并将域名配置到/etc/hosts中
# 正式环境必须用机房或者地区的关键字, 有意义的关键字来命名
# 如果部署多套TDSQL集群, 则名字需要唯一
# 例如: 深圳机房zk的域名可以定义为tdsql_sz_zk
tdsql_zk_domain_name: tdsql_zk
# zk端口配置, 保持默认不要改,如果是自建的zk, 则和已有zk端口保持一致
tdsql_zk_clientport: 2118
tdsql_zk_serverport1: 2338
tdsql_zk_serverport2: 2558
# 赤兔监控库配置, 赤兔初始化完成后需要将监控库信息在这里更新
tdsql_metadb_ip: 10.0.0.64
tdsql_metadb_port: 15001
tdsql_metadb_ip_bak: 10.0.0.64
tdsql_metadb_port_bak: 15001
tdsql_metadb_user: hanlon
tdsql_metadb_password: 123456
# hdfs机器的ssh端口
tdsql_hdfs_ssh: 22
# hdfs数据目录, 正式环境要求mount挂载比较大的数据盘
tdsql_hdfs_datadir: data2/hdfs,/data3/hdfs,/data4/hdfs
# kafka日志目录,正式环境要求mount挂载比较大的数据盘
tdsql_kafka_logdir: data2/kafka,/data3/kafka,/data4/kafka
# 多源同步消费服务的机器网卡
tdsql_consumer_netif: ens192
# es7配置
tdsql_es7_mem: 4
tdsql_es7_base_path: data1/es
tdsql_helper_cluster_name: tdsql
# 一致性读MC机器的网卡, 需要安装MC时配置
tdsql_mc_netif: ens192
update_tdsqlinstall_packet: mysqlagent

  • 组件部署对应的服务器
[root@obtest tdsql_install]# cat tdsql_hosts
[tdsql_allmacforcheck]
tdsql_mac1 ansible_ssh_host=10.0.0.61
tdsql_mac2 ansible_ssh_host=10.0.0.62
tdsql_mac3 ansible_ssh_host=10.0.0.63
tdsql_mac4 ansible_ssh_host=10.0.0.64

[tdsql_zk]
tdsql_zk1 ansible_ssh_host=10.0.0.61
tdsql_zk2 ansible_ssh_host=10.0.0.62
tdsql_zk3 ansible_ssh_host=10.0.0.63

[tdsql_scheduler]
tdsql_scheduler1 ansible_ssh_host=10.0.0.62
tdsql_scheduler2 ansible_ssh_host=10.0.0.63

[tdsql_oss]
tdsql_oss1 ansible_ssh_host=10.0.0.62
tdsql_oss2 ansible_ssh_host=10.0.0.63

[tdsql_chitu]
tdsql_chitu1 ansible_ssh_host=10.0.0.64

[tdsql_monitor]
tdsql_monitor1 ansible_ssh_host=10.0.0.62
tdsql_monitor2 ansible_ssh_host=10.0.0.63

[tdsql_db]
tdsql_db1 ansible_ssh_host=10.0.0.61
tdsql_db2 ansible_ssh_host=10.0.0.62
tdsql_db3 ansible_ssh_host=10.0.0.63

[tdsql_proxy]
tdsql_proxy1 ansible_ssh_host=10.0.0.61
tdsql_proxy2 ansible_ssh_host=10.0.0.62
tdsql_proxy3 ansible_ssh_host=10.0.0.63

[tdsql_hdfs]
tdsql_hdfs1 ansible_ssh_host=10.0.0.61

[tdsql_lvs]
tdsql_lvs1 ansible_ssh_host=10.0.0.62
tdsql_lvs2 ansible_ssh_host=10.0.0.63

[tdsql_kafka]
tdsql_kafka1 ansible_ssh_host=10.0.0.61
tdsql_kafka2 ansible_ssh_host=10.0.0.62
tdsql_kafka3 ansible_ssh_host=10.0.0.63

[tdsql_consumer]
tdsql_consumer1 ansible_ssh_host=10.0.0.61

[tdsql_es]
tdsql_es1 ansible_ssh_host=10.0.0.61

[tdsql_mc]
tdsql_mc1 ansible_ssh_host=10.0.0.64

[tdsql_newdb]
tdsql_newdb1 ansible_ssh_host=10.0.0.61
tdsql_newdb2 ansible_ssh_host=10.0.0.62
tdsql_newdb3 ansible_ssh_host=10.0.0.63

[tdsql_ansible_test]
tdsql_ansible_test1 ansible_ssh_host=10.0.0.61
tdsql_ansible_test2 ansible_ssh_host=10.0.0.62
tdsql_ansible_test3 ansible_ssh_host=10.0.0.63

部署命令很简单:

ansible-playbook -i tdsql_hosts playbooks/tdsql_part1_site.yml -v

最后参数 -v
 是为了将过程日志输出到文件,文件默认是 /var/log/ansible.log
 。 部署成功后输出如下信息:

2025-02-03 19:01:44,248 p=24548 u=root n=ansible | PLAY RECAP *********************************************************************************************************
2025-02-03 19:01:44,248 p=24548 u=root n=ansible | tdsql_chitu1               : ok=39   changed=28   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,248 p=24548 u=root n=ansible | tdsql_db1                  : ok=9    changed=9    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,249 p=24548 u=root n=ansible | tdsql_db2                  : ok=9    changed=9    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,249 p=24548 u=root n=ansible | tdsql_db3                  : ok=9    changed=9    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,249 p=24548 u=root n=ansible | tdsql_mac1                 : ok=61   changed=54   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,249 p=24548 u=root n=ansible | tdsql_mac2                 : ok=49   changed=43   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,249 p=24548 u=root n=ansible | tdsql_mac3                 : ok=49   changed=43   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,250 p=24548 u=root n=ansible | tdsql_mac4                 : ok=49   changed=43   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,250 p=24548 u=root n=ansible | tdsql_oss1                 : ok=15   changed=12   unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
2025-02-03 19:01:44,250 p=24548 u=root n=ansible | tdsql_oss2                 : ok=12   changed=9    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
2025-02-03 19:01:44,250 p=24548 u=root n=ansible | tdsql_proxy1               : ok=9    changed=8    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,250 p=24548 u=root n=ansible | tdsql_proxy2               : ok=9    changed=8    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,250 p=24548 u=root n=ansible | tdsql_proxy3               : ok=9    changed=8    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,251 p=24548 u=root n=ansible | tdsql_scheduler1           : ok=30   changed=28   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,251 p=24548 u=root n=ansible | tdsql_scheduler2           : ok=21   changed=19   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,251 p=24548 u=root n=ansible | tdsql_zk1                  : ok=13   changed=12   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,251 p=24548 u=root n=ansible | tdsql_zk2                  : ok=12   changed=11   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
2025-02-03 19:01:44,251 p=24548 u=root n=ansible | tdsql_zk3                  : ok=12   changed=11   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

如果有组件报错,则可能是前面某一步配置不对,或者资源不够等。

上面部署成功后还只是将 TDSQL MySQL
 的相关组件部署成功,还需要初始化赤兔的元数据库才能使用。访问地址:http://10.0.0.64/tdsqlpcloud/index.php
用户名:admin
,密码:123456
 。

赤兔使用 

登录后会进入初始化向导。

  • 环境检测
  • 集群接入
集群接入

这里为集群指定名称,指定 OSS
服务地址(注:这个OSS
不是对象存储,是前面部署的组件,提供一些 API
),然后会根据 OSS
 服务自动获取到 Zookeeper
 集群相关信息。

  • 集群初始化

这里信息很多,需要维护机房(IDC
)信息、服务器机型信息、服务器信息、网关信息(Proxy
 可以跟 DB
 混部,但是也要单独维护服务器节点信息)。

  • 集群初始化指定机型

赤兔运维思路也是先将数据库主机资源管理起来,这里需要自己指定机型信息,包括数据目录、日志目录(指binlog
目录)、软件目录等。

  • 初始化非分布式实例 最后需要初始化一个非分布式实例给元数据库用。

数据库版本可以选:5.7
8.0
,实例规格可以选择为机器规格的子集或者自定义。

  • 容灾设置

这里可以设置实例的备库数量,以及强同步,备库所处的机房信息等。

  • 设置元数据库

元数据库可以使用 TDSQL 实例,也可以使用普通实例。显然应该选前者。

  • 软件授权 最后一步软件授权是可选步骤,测试目的不需要授权。有些国产数据库搞严格的软件授权,非常影响测试,TDSQL
     这里不强要求。

至此,TDSQL MySQL
 的赤兔就算部署完成了。业务数据还需要分配单独的数据库实例,不要跟元数据共用。

多实例一般是在同一个服务器节点上分配的,这取决于实例的规格需求和服务器的可用资源情况。早期的 RDS MySQL
 都是这个特点,单机多实例。

赤兔运维界面概览 

TDSQL 的运维尽量通过赤兔平台。

重要菜单功能如下:

资源管理
设备资源管理

如果创建实例分配失败,就要查看这里的设备资源使用情况。

大部分运维功能都在实例详情里面。

实例详情
实例详情2
用户权限
在线SQL
数据库参数

可以在Proxy
环节设置一些规则防止危险 SQL 的执行。

网关的擦拭你好

一些运维操作也是以任务流方式进行。

新建用户的任务流

总体上感觉赤兔的功能该有的也都有,就是使用体验不好。不过这个版本已经很老了,据说新版本功能好用很多。

总结 

比较各个大厂的数据库自动化部署产品就可以发现大厂的数据库团队技术沉淀各不相同,高下难分。华为高斯使用的是 shell
脚本,阿里云 polardb-x
 使用的是 python
 脚本,腾讯 tdsql
使用的是 ansible
 脚本。每个产品的部署脚本都是一个很好的学习范例。

最新消息:阿里云的 PolarDB MySQL
 刷新了 TDSQL MySQL
 之前打下的 TPC-C
 榜首位置。后面有空再研究看看 PolarDB MySQL
 的细节。

TPC-C 榜单
更多阅读:

文章转载自数据库技术闲谈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论