TiDB整体体系架构

  • 水平扩容&缩容
  • 金融机高可用
  • 实时HTAP
  • 云原生的分布式数据库
  • 兼容MySQL 5.7 协议

image-20230829172543201

image-20230831155149667

  • 前端(TiDB Server集群)Stateless
  • 后端(TiKV集群、PD集群)Stateful(Raft)

TiDB Server

image-20230829173512475

TiDB Server主要功能

  • 处理客户端的连接

  • SQL语句的解析和编译

  • 关系型数据与KV的转化

    • region大小:96M~144M
  • SQL语句的执行

  • 执行online DDL

    • 不阻塞线上业务
  • 垃圾回收 GC

  • 热点小表缓存V6.0

    • Cache table

TiDB Server架构

image-20230831161239131

  • 无状态,可横向扩展

  • 利用LVS、HAProxy、F5提供统一接入地址,负载均衡

  • 不存储数据,所有数据存在TiKV上

  • 组件作用

    • Protocol Layer| Parse | Compile:生成SQL语句的执行计划
    • Executor|DistSQL|KV:执行计划的执行
    • Transaction|KV:事务
    • PD Client:与PD交互
    • TiKV Client:与TiKV交互
    • Schema load|worker|start job:处理online DDL
    • memBuffer:缓存元数据、登录信息等
    • cache table:小表缓存

SQL语句的解析和编译

解析

image-20230830154455875

编译

image-20230830154635919

  • AST:Abstract Syntax Tree,抽象语法树

Key-Value转化

image-20230830155029615

image-20230830155116892

  • Key的形式:tablePrefix{TableID}_recordPrefixSep

  • 如果声明的主键不是INTEGER数据类型,TiDB会为表创建非聚簇索引

    • _tidb_rowid:非聚簇索引的键
  • 如果没有声明主键,TiDB会为表创建一个隐式主键

    • _tidb_rowid:隐式键值
  • 主键聚簇索引(Clustered):表的主键即为聚簇索引,存储一行至少需要一个键值对

  • 主键非聚簇索引(Non-clustered):行数据的键由隐式分配的_tidb_rowid构成,主键在_tidb_rowid上额外再建立索引,存储一行至少需要2个键值对

    image-20230904150017387

Region

image-20230830155237739

SQL读写相关模块

image-20230831161332637

  • 复杂SQL走DistSQL,KV处理简单的请求(如点查)

在线DDL相关模块

image-20230830155634072

  • DDL不会阻塞

  • 同一时刻只能有一个TiDB Server可以做DDL操作

  • start job把任务放到job queue中,workers角色是owner时,才会去执行job,执行完放到history queue ,owner有任期,任期结束重新选举

  • schema load在当workers成为owner后,缓存所有表的元数据,用于执行任务

GC机制与相关模块

image-20230831161439206

  • safe_point

  • GC_life_time:数据的存活时间,默认10min

TiDB Server的缓存

  • 缓存组成

    • SQL结果

      image-20230830160400799

    • 线程缓存

    • 元数据,统计信息,用户信息

  • 缓存管理

    • tidb_mem_quota_query:控制每条SQL占用缓存的大小
    • oom-action:决定内存超过阀值后的操作

热点小表缓存

  • 表的数据量不大:64M以下
  • 只读表或者修改不频繁的表
  • 表的访问很频繁

image-20230830160521221

原理

image-20230830160725489

  • tidb_table_cache_lease:缓存租约,单位秒,默认5

  • 租约时间内,无法进行写操作

image-20230831152405788

  • 租约到期,数据过期
  • 写操作不再被阻塞
  • 读写直接到TiKV节点上执行

image-20230831152450187

  • 数据更新完毕,租约继续开启

image-20230831152541454

应用

  • 缓存表限制大小为64MB
  • 适用于查询频繁、数据量不大、极少修改的场景
  • 在租约(tidb_table_cache_lease)时间内,写操作会被阻塞
  • 当租约(tidb_table_cache_lease)到期时,读性能会下降
  • 不支持对缓存表直接做DDL操作,需要先关闭
  • 对于表加载较慢或者极少修改的表,可以适当延长租约(tidb_table_cache_lease)保持读性能稳定

TiKV

主要功能

  • 数据持久化

  • 副本的强一致性和高可用性(分布式一致性)

  • MVCC(多版本并发控制)

  • 分布式事务支持

  • Coprocessor(协同处理器)

    • 提供算子下推能力,把计算工作下放到TiKV节点进行,节省带宽和IO,过滤/投影/计算

image-20230830161456029

  • 各组件作用
    • rocksdbraft:存日志
    • rocksdbkv:存数据
    • Raft:高可用
    • MVCC:多版本控制,读取控制
    • Transation:支持事务

持久化

TiKV底层持久化使用了RocksDB,RocksDB针对Flash存储进行优化,延迟极小,使用LSM存储引擎

  • 高性能的Key-Value数据库
  • 完善的持久化机制,同时保证性能和安全性
  • 良好的支持范围查询
  • 为需要存储TB级别数据到本地FLASH或者RAM的应用服务器设计
  • 针对存储在高速设备的中小键值进行优化,可以存储在FLASH或者直接存储在内存
  • 性能随CPU数量线性提升,对多核系统友好

RocksDB写入

image-20230831161625709

  • sync_log=true:会调用系统fsync直接将日志写入操作系统的磁盘中,而不会通过操作系统的内存

  • write_buffer_size:控制当memTable内存达到多少时将数据flush进immutable

  • immutable的存在可以防止memTable直接写磁盘时IO慢导致memTable写阻塞

  • writeStall:当immutable达到5个时,会限制memTable的写入速度,并记录日志,以保护RocksDB,可以通过优化存储性能或调大参数进行优化

image-20230831161754430

  • Level 0就是immutable的复刻

  • 磁盘上的是SST(Sort String Table)文件

  • 当文件达到4个时,会进行compaction(压缩&排序),将文件存进下一层,查找时用二分查找法

  • 写入时需要一次磁盘io,一次内存io,顺序写

  • 对写友好,删除时只要写个delete即可,更新同理

RocksDB查询

image-20230831161839621

  • 查询时,先找对应文件里key的最小值和最大值,如果需要查找的key在这个范围,就用二分查找法查找数据,并且利用布隆过滤器查询数据是否存在
    • 布隆过滤器判断数据不在就一定不在,判断数据在不一定在

Column Families

image-20230831161939165

  • 列簇(CF),数据分片技术

  • 写入:write(cf1,id,name,age),write(cf2,id,addr,tell)

  • 默认列簇为default

  • 日志WAL不区分,多个列簇共享同一个日志文件

分布式事务

image-20230831162034188

image-20230830170113866

  • 2PC
    • prewrite
    • commit
  • 分成3个CF
    • Deafult:存储超过255字节长度的数据
    • Lock:存储锁信息
    • Write:存储提交信息和小于255字节长度的数据
  • 只给事务的第一行加锁,其他行的锁指向主锁
  • 在写入之前,别人感知不到,叫做乐观锁;提前将锁写入TiKV节点中,叫做悲观锁。

MVCC

image-20230831162144373

image-20230830170520692

  • id=1,可读不可写

    image-20230830170810556

  • id=2,可读可写

    image-20230830170946195

  • id=4,可读不可写

    image-20230830171018080

Raft

image-20230830171517984

  • 初始化时,会写入同一个region,当region达到96MB时,会写入下一个region,存储的key是左闭右开区间
  • 修改数据过程中,当某个 Region 的大小超过一定限制(默认是 144 MiB)后,TiKV 会将它分裂为两个或者更多个 Region,当某个 Region 因为大量的删除请求而变得太小时(默认是 20 MiB),TiKV 会将比较小的两个相邻 Region 合并为一个

Raft日志复制

image-20230830171707624

过程

  1. propose:将请求转成日志

    image-20230830172902941

  2. append:将日志持久化至RocksDB raft中

    image-20230830172916298

  3. replicate:leader将日志复制到其他follower节点

    append:follower节点将日志持久化到RocksDB Raft

    image-20230830172849549

  4. committed:超过50%节点告知leader节点已完成日志持久化

    image-20230830172334728

    Raft层committed与应用程序事务的committed不一样,这里只是说Raft多副本协议的committed

    image-20230830172529278

  5. apply:将数据真正写入到RocksDB KV中

    image-20230830172723775

    应用程序committed成功

    image-20230830172828101

Raft Leader选举

image-20230830173015544

  • term :时间段,没有固定长度

  • follower在特定情况下会变成candidate,candidate会发起投票,只要收到一半以上投票就成为leader,其他follower节点发现condidate节点的term比自己大,就投1票

  • heartbeat_time_interval:等待leader心跳的最长时间,超过时间收不到心跳就会发起选举

    • TiDB参数:raft-heartbeat-ticks,默认10
  • election_timeout:无主状态下多长时间发起选举,实际上每个节点是随机时间random(100ms-300ms)

    • TiDB参数:raft-election-timeout-ticks,不能小于raft-heartbeat-ticks
  • raft-base-tick-interval:raft每个ticks的大小,默认1s

数据的写入

image-20230830174530318

数据的读取

ReadIndex Read

image-20230830175302935

  • raftstore pool:日志线程池

  • apply pool:写入线程池

  • 去PD查数据存放位置

  • 读的时候发心跳确认是否为Leader

  • 需要保证读取线性一致性

image-20230831100315352

  • readIndex 记录当前 raft commit 的位置

  • applyIndex 记录当前 apply 的位置

  • 读取时,需要记录readIndex,等待applyIndex执行到readIndex位置,才可以正常读取数据

Lease Read

也叫local read

image-20230831101300650

image-20230831101008005

  • 记录一个开始时间,在一个时间周期内(election timeout)可以获取到follower节点的心跳,就可以认为一直是leader节点,就可以一直在该节点读取数据

Follwer Read

image-20230831101447322

  • follower向leader获取leader当前的commitIndex,然后follower等到applyIndex执行到commitIndex,才可以读取数据

leader

image-20230831101502174

follower

image-20230831101539397

  • 有可能follower的apply速度比leader快,所以follower的读取可能比leader快,如下图

    image-20230831102123341

Coprocessor

image-20230831102144005

image-20230831102215842

image-20230831102359935

  • coprocessor有以下三种情景
    • 执行物理算子,如:tableScan、indexScan、selection、limit、aggreate
    • 分析统计信息 analyze
    • 对表进行校验

Placement Driver

主要功能

  • 整个机器TiKV的元数据存储

  • 分配全局ID和事务ID

  • 生成全局时间戳TSO

  • 收集集群信息进行调度(TiKV、TiFlash按一定时间间隔向PD节点进行信息汇报)

  • 提供label,支持高可用

  • 提供TiDB Dashboard服务

image-20230829174340909

架构

image-20230831102639287

  • 集成etcd raft存储数据
  • TiDB机器大脑
    • 元数据存储
    • 全局时钟TSO
    • Region调度

路由功能

image-20230831103229141

  • back off:region cache信息过旧,导致region转移导致路由失败

TSO

TimeStamp Oracle

概念

  • TSO=physical time + logical time
    • physical time:物理时间,取值是unix时钟
    • logical time :逻辑时间,1ms分成262144个
    • int64类型

分配

image-20230831103908566

  • 异步
  • PD Client有批处理功能

时间窗口

image-20230831110251112

  • 将1段时间窗口的TSO放到缓存中,避免经常访问存储,解决性能问题

高可用

image-20230831110710890

  • 在获取TSO时,如果PD的leader节点宕机,另外的PD节点不管之前的TSO是什么,都会重新生成TSO

调度

总流程

image-20230831110737153

信息收集

image-20230831111219183

生成调度

  • Balance
    • Leader
    • Region
  • Hot Region
  • 集群拓扑
  • 缩容
  • 故障恢复
  • Region merge

执行调度

image-20230831111033337

Label与高可用

image-20230831111133048

Label配置

image-20230831111531390

TiFlash

主要功能

  • 异步复制

  • 一致性读取

  • 计算加速

    • 列式存储提高分析查询效率
    • 计算下推
  • 业务隔离

    • TiKV承载OLTP业务

    • TiFlash承载OLAP业务

  • 引擎智能选择

    • TiDB Server通过SQL预测决定使用的引擎

架构

image-20230831145221143

  • TiFlash是只读的,靠异步复制
  • TiFlash与TiKV也是一致性读取的,快照隔离级别
  • QPS不高,小于50

异步复制

image-20230831145607233

一致性读取

image-20230831145716878

image-20230901095046514

image-20230831150001569

image-20230831150325453

image-20230831150104719

image-20230831150140860

image-20230831150226723

智能选择

image-20230831150418963

TiDB数据库SQL执行流程

DML语句读流程概要

image-20230831141015548

DML语句写流程概要

image-20230831141050953

  • 先读出来再修改

DDL流程概要

image-20230831141321831

SQL的Parse与Compile

image-20230831141540182

读取的执行

image-20230831141823456

image-20230831142017861

  • snapshot:快照,只能查到当前时刻的数据
  • UnifyRead Pool:查询线程池,按优先级到rocksdb kv查

image-20230831142317040

  • Cop task:算子下推到TiKV的任务
  • Root task:TiDB Server的任务

写入的执行

image-20230831142441178

  • 将需要修改的数据提前读取到memBuffer中,再进行写入操作

image-20230831142745980

  • Scheduler:管理并发写入请求,使用latch管理
  • Raftstore:将写请求转换为raft log

DDL的执行

image-20230831142924378

  • start job判断当前TiDB Server是否为owner,如果是,直接将任务交给workers执行,否则就将任务提交到TiKV的job queue中

image-20230831143231380

  • owner是轮询的,由PD节点控制
  • 加索引的操作是单独放到add index queue中

TiDB数据库的HTAP概述

HTAP技术

image-20230831143440084

传统的OLTP和OLAP方案

image-20230831143616992

HTAP的要求

  • 可拓展性
    • 分布式事务
    • 分布式存储
  • 同时支持OLTP与OLAP
    • 同时支持行存和列存
    • OLTP与OLAP业务隔离
  • 实时性
    • 行存与列存数据实时同步

TiDB的HTAP架构

image-20230831143832400

  • TiFlash作为Raft Group的learner角色,只参与复制,不参与投票

TiDB的HTAP特性

  • 行列混合
    • 列存(TiFlash)支持基于主键的实时更新
    • TiFlash作为列存副本
    • OLTP与OLAP业务隔离
  • 智能选择(CBO自动或者人工选择)
  • MPP架构

MPP

  • 大量数据的join聚合查询
  • 所有MPP计算都在TiFlash节点内存中完成
  • 目前只支持等值链接
  • Enforce_mpp帮助验证是否可以使用MPP

image-20230831144133642

每个TiFlash节点称之为MPP Worker

例子

image-20230831144312042

先做过滤

image-20230831144503741

数据交换

image-20230831144534586

取hash

join操作

image-20230831144707033

group by再做数据交换

image-20230831144739347

聚合

image-20230831144832773

结果

image-20230831144909055

混合工作负载场景

image-20230831144936013

流式计算场景

传统

image-20230831145011620

TiDB

image-20230831145116137

TiDB6.0新特性

Placement Rules in SQL

之前

  • 跨地域部署的集群,无法本地访问
  • 无法根据业务隔离资源
  • 难以按照业务登记配置资源和副本数

image-20230831150730795

之后

  • 跨地域部署的集群,支持本地访问
  • 根据业务隔离资源
  • 按照业务等级配置资源和副本数

image-20230831151034231

使用

步骤1

  • 设计业务拓扑,为不同的TiKV实例设置标签

image-20230831151224690

步骤2

  • 创建PLACEMENT POLICY

image-20230831151333103

步骤3

  • 设定数据对象的PLACEMENT POLICY

image-20230831151452098

应用

  • 精细化数据放置,控制本地访问与跨区域访问
  • 指定副本数,提供重要业务的可用性和数据可靠性
  • 将业务按照等级、资源需求或者数据生命周期进行隔离
  • 业务数据整合,降低运维成本与复杂度

小表缓存

参考TiKV 热点小表缓存

内存悲观锁

悲观锁

image-20230831152642779

内存悲观锁

image-20230831153059791

锁丢失

image-20230831153209587

  • 出现锁丢失后,事务会失败并回滚

使用

  • 在线开启内存悲观锁
    • set config tikv pessimistic-txn.pipelined=‘true’;
    • set config tikv pessimistic-txn.in-memory=‘true’;
  • 修改配置文件

应用

  • 减少事务的延时
  • 降低磁盘和网络带宽
  • 降低TiKV的CPU消耗
  • 锁丢失问题

Top SQL

之前

image-20230831153536170

image-20230831153640507

之后

image-20230831153710043

使用

步骤1

  • 选择需要观察负载的具体TiDB Server或TiKV实例

image-20230831153857160

步骤2

  • 观察Top 5类SQL

image-20230831153943578

步骤3

  • 查看某语句的执行情况:Call/sec(平均每秒请求数)、Scan Indexes/sec(平均每秒扫描索引数)等

image-20230831153954608

作用

  • 可视化地展示CPU开销最多的Top 5类SQL语句
  • 支持制定TiDB Server及TiKV实例进行查询
  • 支持统计所有正在执行的SQL语句
  • 支持每秒请求数、平均延迟、查询计划等详细执行信息

TiDB Enterprise Manager(TiEM)

企业中TiDB集群管理的问题

  • 数量增长
    • 集群数量
    • 节点数量
    • 组件数量
    • 工具数量
  • 复杂度增长
    • 配置参数复杂度
    • 命令行复杂度
    • 管理接口复杂

企业中TiDB集群管理的任务

  • 部署集群
  • 升级集群
  • 参数管理
  • 组件管理
  • 备份恢复与高可用管理
  • 集群监控与告警
  • 集群日志收集
  • 审计与安全

TiEM功能

  • 一键部署集群&多套集群一站式管理
  • 集群原地升级
  • 参数管理
  • 克隆集群&主备集群切换

TiDB Cloud

  • TiDB Cloud是一个功能齐全的数据库即服务或DBaaS,是一个特殊的PaaS

image-20230831155320983

TiDB的好处

  • 分布式SQL数据库-多租户
  • 混合工作负载-在同一个数据库中
    • 事务型:基于行的数据
    • 分析型:基于列的数据
  • 弹性比例
    • 缩小-减少节点
    • 横向扩展-添加节点
  • 基于“RAFT”的高可用性
    • 每个数据段在3个可用区进行复制

多租户

  • 什么是多租户?
    • 在多租户架构中,应用程序的多个实例在共享环境中运行
    • 每个租户在物理上都是集成的,但在逻辑上是分开的
    • 一个软件实例为多个租户提供服务

image-20230831154831329

本地数据库与云DBaaS的比较

image-20230831155430149

提供商Region

image-20230831155653552

TiDB Cloud提供的服务

Developer Tier

image-20230831160206064

限制

image-20230831160238206

Dedicated Tier

image-20230831160325267

比较

image-20230831161022471