写点什么

云原生 MYSQL 数据库架构分享

作者:谐云
  • 2023-07-03
    浙江
  • 本文字数:3213 字

    阅读完需:约 11 分钟

云原生MYSQL数据库架构分享

什么是云原生数据库

云原生定义

云原生技术使组织能够在公共、私有和混合云等现代动态环境中构建和运行可扩展的应用程序。容器、服务网格、微服务、不可变基础设施和声明式 API 就是这种方法的例证。


云原生数据库特性

1. 高扩展性:需要能够根据业务需求,利用云计算的策略对数据库进行扩展,包括硬件资源、集群规模,通常包括滚动升级、实例扩缩容等

2. 易用性:能够让运维人员在不具备专业技能的情况下使用该系统,需要实现声明式 API 与自动化运维。

3. 高可用性:需要能够在宕机等场景下,不会引起业中断,或者短时间内恢复业务访问。通常实现数据的冗余、备份

4. 安全性:数据应该在任何故障的情况下,需要保证数据不会丢失,能够恢复到最近的一个事件点。

MYSQL 数据库

MYSQL 介绍

主从架构— —概念

binlog 日志

MySQL 的二进制日志可以说是 MySQL 最重要的日志了,它记录了所有的 DDL 和 DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间。


复制原理

1. 主库操作保留 binlog 日志

2. 从库的 IO 线程从主库拉取 binlog 日志,并生成中继日志(relay log)

3. 从库的 SQL 线程解析中继日志,并在本身回放

状态检查

主要通过判断 IO 线程和 SQL 线程是否处于 Running 判断复制是否正常,判断 Seconds_Behind_Master 参数代表数据同步是否延迟:


mysql> show slave status\G...       Slave_IO_Running: YesSlave_SQL_Running: YesSeconds_Behind_Master: 0...
复制代码

 主从架构— —衍生各种扩展的主从架构

1. 一主多从

2. 双主复制

3. 级联复制

4. 等等



读写分离

大部分场景下,读的频率比写的频率会高很多。所以可以通过扩展多个 SLAVE 节点提高整体的使用性能。



数据备份

传统的备份包括三种方式:

1. lvm snapshot(LVM 快照备份)

2. mysqldump

3. Xtarbackup

那么要如何实现数据的一致性备份呢(一致性备份是所有数据/文件/磁盘 需要在同一个时间点进行备份)


LVM SNAPSHOT

1. 执行 FTWRL(FLUSH TABLES WITH READ LOCK)

1.1 上全局读锁(lock_global_read_lock)

1.2 清理表缓存(close_cached_tables)

1.3 上全局 COMMIT 锁(make_global_read_lock_block_commit)

2. 执行 lvcreate 创建 lv 快照.

3. UNLOCK TABLES 解锁

MYSQLDUMP

1. 开启可重复读事务隔离

2. 开启事务

3. 建立数据快照(可以理解为 select * from *)

4. 结束事务

XTRABACKUP

1. 不是整体采用备份锁,只有特定阶段。

2. indodb 阶段不需要加锁,ACID 的 C(持续性)是通过 Redo log 实现,通过线程增量记录 redo log 实现。



MYSQL 云原生改造

Oprtator 模式

Operator 模式包含以下是三个重要的机制(属性)

自定义资源

• 定义组件属性:包含期望值 + 状态值

• 需要具备扩展性

Informer 事件机制

• 资源监听:监听自定义资源、以及相关的资源

• 资源过滤:根据 ownerReferences 等过滤非相关的资源

循环控制

• 主要为让期望值(spec)和状态(status)达到一致

• 各种自动化运维的操作以代码的方式沉淀



Operator/Controller 流程简述

以下是 Operator/Controller 的大体流程(可以参考官方的 sample-controller 项目),在 SyncHandler(kubebuilder 或者 operator-sdk 的 reconcile)流程中通常需要实现这么几层逻辑。

AddEventHandler

自定义资源关联的资源

SyncHandler(Reonciler)

1. 资源管理层:自定义资源与内部资源映射维护

2. 组件管理层:通过 SDK/API 对组件进行配置、运维操作等

3. 状态管理层:状态值的检查和记录



云原生 MYSQL 架构

KUBERNETES:集群层,提供容器运行环境

MYSQL-OPERATOR:负责 MYSQL 集群的运维工作

MYSQL 集群:MYSQL 运行实例

中间件管理平台:平台层,负责界面化的中间件管理

MYSQL 资源结构设计

以下是我们针对 MYSQL 集群设置的自定义资源结构。

元数据:包含 k8s 所需要的元数据和自定义的 label 或者 annoations

期望值:用户的期望值属性。包含集群的相关属性和 MYSQL 的相关属性

状态值:MYSQL 的运行状态。包括节点信息、整体运行情况

具体定义如下(仅仅作为参考)


自动化部署

1. 部署 OPERATOR:通过 deployment 部署 MYSQL-Operator 实例和自定义资源

2. 部署 MYSQL:



MYSQL 配置

reset slave;change master to master_host='%s', master_user='%s', master_password='%s',MASTER_PORT=%d,master_auto_position=1 for channel 'replication_applier'start slave;
复制代码

检查复制状态

show slave status;

故障自愈能力

1. MYSQL 进程异常(可能是由于主机、进程奔溃、阻塞等其他原因)

2. 监控检查探针识别到该 MYSQL 异常

3. Operator 开始触发转移操作

4. 如果故障的是主库,则做数据的延迟检查、将打开备库的流量通道,并配置只读配置。读写都在旧的从库上

5. 如果故障的备库,则直接将备库写的流量切换到主库;



扩容技术

通过数据扩容的横向扩容可以提高读数据的能力

1. 修改 MysqlCluster 资源中的 replicas 属性,由 2 修改为 3

2. Operator 发现该值被修改,新建一个 Pod

3. 待 Pod Runnig 以后,Operator 访问新建的 Mysql Pod, 配置复制策略

4. Operator 执行 show slave status 命令,检查所有 Mysql

5. 最后更新 MysqlCluster.status 属性



LVM 存储

CSI-Provisioner: 监听 PVC 并且创建 PV

CSI-Resizer: 监听 PVC 存储的情况,进行扩缩容

LVM-CSI-plugin: 实现 LVM 数据卷的创建和卸载管理。


云原生监控支持

常见的 Prometheus + Grafana + Alermanager 架构 




实时容灾能力

实现了跨机房的 MYSQL 容灾。



数据备份与恢复

数据备份

• 定时备份资源 MysqlBackupSchedule 通过 corn 表达式创建备份资源 MysqlBakcup

• 备份资源资源 MysqlBakcup 创建 job,调度 pod 与 Master 在相同节点,内置 xtrabackup 工具备份 MYSQL 数据,备份完毕后通过 MINIO 客户端 mc 上传备份文件到 MINIO 中

 数据恢复

由于 xtrabackup 的特性,需要基于新的 MYSQL 进行创建,则需要创建一个新的 MysqlCluster 资源,并且导入备份数据进而恢复。



通用备份

基于 LVM 的通用备份工具

采用 csi-plugin 实现通用的 lvm 快照备份,并且上传到 MINIO。

提供备份的 pre-hook 以及 post-hook,可以用于 MYSQL 的备份锁、数据刷盘等策略。其他组件也可以采用类似的方式进行管理。



内核能力扩展

线程池

默认的 Mysql 连接方式是, one-thread-per-connection,也就是每一个连接请求采用一个线程进行处理。这种模式在大量的线程请求下效率会非常差。

为了提升高并发的问题,以插件的形式支持 MYSQL 以线程池的方式应对大连接。

MYSQL 默认连接方式

每个线程除以一个客户端的 socket,并且堵塞接收 client 消息。

MYSQL Thread-pool 连接方式

1. 单个监听线程通过 IO 多路复用(EPOLL),接收线程池里面一个组的所有 IO 请求,并且转发给工作线程

2. 工作线程循环处理请求,如果没有则进入休眠

采用 sysbench 对线程池进行压力测试

随着压测线程的上升的确有了很大的性能提升。

数据回收站

MYSQL 不具备数据删除回收的功能,当发生数据误删除则只能通过备份数据进行恢复,可能导致数据的部分丢失。为了解决这个问题,目前以插件的方式提供数据回收的能力。

mysql 复制插件包含以下扩展结构

• Trans_observer:扩展事务执行

• Server_state_observer:扩展服务状态

• Binlog_storage_observer:binlog 存储

• Binlog_transmit_observer:binlog dump

• Binlog_relay_IO_observer:扩展中继日志

我们针对 Binlog_relay_IO_observer 接口进行了扩展,实现了数据回收的能力。

针对从库中继日志落盘的回调方法中执行相应的操作逻辑,发现如果是删除表/库操作,则针对具体操作的表对象进行 rename 操作,将表移动到回收站,超过一定期限才会删除。

typedef struct Binlog_relay_IO_observer {... // 将事件包写入中继日志后调用此回调  int (*after_queue_event)(Binlog_relay_IO_param *param,                          const char *event_buf, unsigned long event_len,                           uint32 flags);...} Binlog_relay_IO_observer;
复制代码


未来工作

MYSQL 代理接入

1. 采用 MYSQL 代理的方式接入 MYSQL 集群本身,以兼容单体 MYSQL 的方式进行连接

2. MYSQL-PROXY 本身具备故障检查的功能,可以主动剔除异常的 MYSQL 实例。

Operator 分层

减少 Operator 本身的臃肿,将组件的运维功能独立,使用接口调用。



用户头像

谐云

关注

中国数字基础建设云原生软件领导者 2019-09-30 加入

杭州谐云科技有限公司成立于2016年7月,是国内为数不多掌握底层核心技术的容器云提供商,拥有100%国产自主可控的软件产品。谐云从观云台为核心,结合DevOps与微服务等场景,提供应用全生命周期管理。

评论

发布
暂无评论
云原生MYSQL数据库架构分享_MySQL_谐云_InfoQ写作社区