Skip to content

TiFlash 组件

角色定位

TiFlash 是 TiDB 分布式数据库的列式存储引擎,为 TiDB 提供实时 HTAP(混合事务分析处理)能力。它通过与 TiKV 实时同步数据,支持对实时数据进行高效的分析查询,无需 ETL 过程。

核心功能

  • 列式存储:采用列式存储格式,适合分析查询,减少 I/O 开销
  • 实时同步:与 TiKV 实时同步数据,保持数据一致性
  • MPP 执行:支持分布式并行查询执行,提高复杂查询性能
  • 向量计算:支持向量计算加速,提升分析查询效率
  • ACID 兼容:支持 ACID 事务,保证数据一致性
  • 透明融合:与 TiDB 无缝集成,无需修改应用代码

架构特点

  • 分离存储:与 TiKV 共享相同的数据,但采用不同的存储格式
  • 实时同步:基于 Raft Learner 协议,从 TiKV 实时同步数据
  • MPP 架构:支持多节点并行查询执行
  • 云原生设计:支持容器化部署和 Kubernetes 管理
  • 高可用性:数据多副本存储,自动故障转移
  • 弹性扩展:支持通过增加节点线性扩展分析性能

架构设计

内部模块

TiFlash 内部包含多个核心模块,协同工作提供列式存储和分析查询服务:

1. 网络层

  • 功能:处理节点间通信和客户端请求
  • 协议支持:gRPC 协议,高效的跨语言通信
  • 连接管理:管理与 TiKV 节点、TiDB 节点和其他 TiFlash 节点的连接
  • MPP 通信:支持 MPP 查询的节点间数据交换

2. 存储引擎层

  • 功能:负责数据的列式存储和管理
  • 列式存储格式:采用高效的列式存储格式,支持压缩
  • Delta Tree:存储引擎核心,支持实时更新和查询
  • 数据压缩:支持多种压缩算法,降低存储成本
  • 索引支持:支持多种索引类型,加速查询

3. 同步层

  • 功能:从 TiKV 实时同步数据
  • Raft Learner:作为 TiKV Raft 组的 Learner,接收日志复制
  • 数据转换:将行存格式转换为列存格式
  • 增量更新:支持实时增量同步
  • 一致性保证:保证与 TiKV 数据的最终一致性

4. 查询执行层

  • 功能:执行分析查询
  • MPP 执行:支持多节点并行查询执行
  • 向量计算:支持向量计算加速
  • 查询优化:生成高效的查询执行计划
  • 算子支持:支持各种分析查询算子,如聚合、连接、排序等

5. 监控模块

  • 功能:监控 TiFlash 节点的状态和性能
  • 指标收集:收集各种性能指标
  • 健康检查:定期检查节点健康状态
  • 告警机制:当检测到异常时触发告警

数据同步机制

1. Raft Learner 同步

TiFlash 作为 TiKV Raft 组的 Learner,接收 Raft 日志复制:

  • 实时同步:从 TiKV Leader 接收 Raft 日志
  • 异步应用:异步将日志应用到本地存储
  • 一致性保证:保证与 TiKV 数据的最终一致性
  • 低影响:对 TiKV 性能影响小,不影响事务处理

2. 同步流程

TiKV Leader → Raft 日志复制 → TiFlash Learner → 日志解析 → 列式转换 → Delta Tree 存储

详细步骤

  1. TiKV Leader 处理写入请求,生成 Raft 日志
  2. Raft 日志复制到 TiFlash Learner
  3. TiFlash 解析 Raft 日志,提取数据变更
  4. 将行存格式转换为列存格式
  5. 将数据写入 Delta Tree 存储引擎

部署与配置

部署方式

1. 使用 TiUP 部署

部署命令

bash
# 编辑拓扑文件,添加 TiFlash 配置
vi topology.yaml

# 部署集群
tiup cluster deploy <cluster-name> <tidb-version> topology.yaml --user root -p

# 启动集群
tiup cluster start <cluster-name>

拓扑文件示例

yaml
global:
  user: "tidb"
  ssh_port: 22
  deploy_dir: "/tidb-deploy"
  data_dir: "/tidb-data"

server_configs:
  tiflash:
    log.level: "info"
    storage.main.dir: "/tidb-data/tiflash-9000"

tiflash_servers:
  - host: 10.0.0.9
    port: 9000
    status_port: 20170
    tcp_port: 9009
    http_port: 8123
    flash_service_port: 3930
    flash_proxy_port: 20292

2. 使用 TiDB Operator 部署

YAML 配置示例

yaml
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
  name: basic
spec:
  version: v7.5.0
  tiflash:
    replicas: 2
    template:
      spec:
        containers:
        - name: tiflash
          resources:
            requests:
              cpu: 4
              memory: 16Gi
            limits:
              cpu: 8
              memory: 32Gi
          storageClassName: local-storage
          volumeMounts:
          - name: tiflash-data
            mountPath: /var/lib/tiflash
    storage:
      volumeClaimTemplates:
      - metadata:
          name: tiflash-data
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 1Ti
          storageClassName: local-storage

核心配置参数

1. 基本配置

参数默认值说明
server.port9000TiFlash 服务端口
server.status_port20170状态端口,用于监控
server.tcp_port9009TCP 服务端口
server.http_port8123HTTP 服务端口
storage.main.dir"./data"数据存储目录
storage.main.capacity0存储容量限制(字节),0 表示无限制

2. 同步配置

参数默认值说明
raft.flash.service_addr""Flash 服务地址
raft.flash.proxy_addr""Flash Proxy 服务地址
raft.flash.replica_count1默认 TiFlash 副本数
raft.flash.apply_batch_size32批量应用日志大小

3. 查询配置

参数默认值说明
mpp.enabletrue是否启用 MPP 执行
mpp.max_threads16MPP 查询的最大线程数
mpp.stream_send_queue_size1024MPP 流发送队列大小
vectorized_execution.enabletrue是否启用向量执行

使用场景

1. 实时数据分析

  • 场景:需要对实时数据进行复杂分析查询
  • 优势:无需 ETL,直接查询实时数据,延迟低
  • 示例:实时销售报表、用户行为分析、运营监控

2. 历史数据查询

  • 场景:需要查询大量历史数据
  • 优势:列式存储和压缩,减少存储成本,提高查询性能
  • 示例:历史订单查询、年度报表生成、趋势分析

3. 复杂聚合查询

  • 场景:需要进行多维度复杂聚合查询
  • 优势:MPP 并行执行,加速复杂查询
  • 示例:多维度 OLAP 查询、数据挖掘、机器学习

4. 即席查询

  • 场景:需要进行灵活的即席查询
  • 优势:支持 SQL 语法,无需学习新的查询语言
  • 示例:数据分析人员的即席查询、业务探索

性能优化

1. 存储优化

  • 调整压缩算法

    toml
    storage.main.compression = "zstd"
  • 调整块大小

    toml
    storage.main.block_size = 65536
  • 配置存储容量

    toml
    storage.main.capacity = "1Ti"

2. 查询优化

  • 启用 MPP 执行

    toml
    mpp.enable = true
  • 调整 MPP 线程数

    toml
    mpp.max_threads = 32
  • 启用向量执行

    toml
    vectorized_execution.enable = true

3. 同步优化

  • 调整批量应用大小

    toml
    raft.flash.apply_batch_size = 64
  • 调整副本数

    toml
    raft.flash.replica_count = 2

监控与运维

监控指标

TiFlash 提供了丰富的监控指标,可通过 Prometheus 收集和 Grafana 可视化:

1. 存储指标

  • tiflash_storage_data_size_bytes:存储数据总大小
  • tiflash_storage_delta_bytes:Delta 层数据大小
  • tiflash_storage_data_compression_ratio:数据压缩率
  • tiflash_storage_read_bytes_total:读取字节总数
  • tiflash_storage_write_bytes_total:写入字节总数

2. 同步指标

  • tiflash_raft_logs_received_total:接收的 Raft 日志总数
  • tiflash_raft_logs_applied_total:应用的 Raft 日志总数
  • tiflash_raft_logs_pending:待处理的 Raft 日志数
  • tiflash_raft_sync_lag_seconds:同步延迟(秒)

3. 查询指标

  • tiflash_queries_total:查询总数
  • tiflash_query_duration_seconds_bucket:查询延迟分布
  • tiflash_mpp_queries_total:MPP 查询总数
  • tiflash_vectorized_execution_total:向量执行查询总数

4. 系统指标

  • tiflash_server_memory_usage_bytes:内存使用量
  • tiflash_server_cpu_usage_seconds_total:CPU 使用时间
  • tiflash_server_threads_active:活跃线程数

常见运维操作

1. 查看 TiFlash 状态

bash
# 使用 tiup 查看状态
tiup cluster display <cluster-name> | grep tiflash

# 查看进程状态
ps -ef | grep tiflash

# 使用 TiDB 查看 TiFlash 状态
mysql -h <tidb-ip> -P 4000 -u root -e "SELECT * FROM information_schema.tiflash_replica;"

2. 重启 TiFlash

bash
# 重启单个 TiFlash 节点
tiup cluster restart <cluster-name> -R tiflash[0]

# 重启所有 TiFlash 节点
tiup cluster restart <cluster-name> -R tiflash

3. 扩容 TiFlash

bash
# 编辑拓扑文件,添加新节点
vi topology.yaml

# 扩容集群
tiup cluster scale-out <cluster-name> topology.yaml

4. 缩容 TiFlash

bash
# 编辑缩容配置文件
vi scale-in.yaml

# 缩容集群
tiup cluster scale-in <cluster-name> -N <tiflash-node-ip>:9000

5. 调整 TiFlash 副本

sql
-- 为表添加 TiFlash 副本
ALTER TABLE <table_name> SET TIFLASH REPLICA 1;

-- 修改表的 TiFlash 副本数
ALTER TABLE <table_name> SET TIFLASH REPLICA 2;

-- 删除表的 TiFlash 副本
ALTER TABLE <table_name> SET TIFLASH REPLICA 0;

-- 查看表的 TiFlash 副本状态
SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = '<database_name>' AND TABLE_NAME = '<table_name>';

常见问题与排查

1. TiFlash 同步延迟高

现象:TiFlash 与 TiKV 数据同步延迟高

排查步骤

  • 检查网络连接:确认 TiFlash 与 TiKV 之间的网络延迟是否正常
  • 检查系统负载:确认 TiFlash 节点 CPU、内存、磁盘 I/O 是否过高
  • 检查同步配置:确认批量应用大小等参数是否合适
  • 查看监控指标:检查 tiflash_raft_sync_lag_seconds 指标

解决方案

  • 优化网络环境,降低节点间延迟
  • 增加 TiFlash 节点资源,降低系统负载
  • 调整同步配置,增加批量应用大小:
    toml
    raft.flash.apply_batch_size = 64
  • 增加 TiFlash 节点数量,分担同步压力

2. 分析查询性能差

现象:使用 TiFlash 执行分析查询时性能不佳

排查步骤

  • 检查查询语句:确认查询是否可以优化
  • 检查 MPP 配置:确认 MPP 是否已启用
  • 检查向量执行:确认向量执行是否已启用
  • 查看执行计划:使用 EXPLAIN ANALYZE 查看查询执行计划
  • 检查 TiFlash 资源:确认 TiFlash 节点资源是否充足

解决方案

  • 优化查询语句,添加合适的索引
  • 启用 MPP 执行:
    toml
    mpp.enable = true
  • 启用向量执行:
    toml
    vectorized_execution.enable = true
  • 增加 TiFlash 节点数量,提高并行处理能力
  • 调整 MPP 线程数:
    toml
    mpp.max_threads = 32

3. TiFlash 节点无法启动

现象:TiFlash 节点无法正常启动

排查步骤

  • 检查日志:查看 TiFlash 日志中的错误信息
  • 检查数据目录:确认数据目录权限和空间是否正常
  • 检查配置文件:确认配置文件是否正确
  • 检查网络连接:确认节点间网络是否正常

解决方案

  • 根据日志错误信息进行针对性修复
  • 检查并修复数据目录权限问题
  • 调整配置文件,确保配置正确
  • 修复网络连接问题

4. TiFlash 副本状态异常

现象:TiFlash 副本状态异常,无法正常同步数据

排查步骤

  • 查看副本状态:使用 SQL 语句查看 TiFlash 副本状态
  • 检查 TiFlash 节点状态:确认 TiFlash 节点是否正常运行
  • 检查 TiKV 节点状态:确认 TiKV 节点是否正常运行
  • 检查网络连接:确认 TiFlash 与 TiKV 之间的网络是否正常

解决方案

  • 重启异常的 TiFlash 节点
  • 重建 TiFlash 副本:
    sql
    ALTER TABLE <table_name> SET TIFLASH REPLICA 0;
    ALTER TABLE <table_name> SET TIFLASH REPLICA 1;
  • 修复网络连接问题

最佳实践

1. 部署建议

  • 生产环境:建议部署至少 2 个 TiFlash 节点,实现高可用性
  • 资源配置:每个 TiFlash 节点建议配置 16C 32GB 内存起,根据查询负载调整
  • 存储选择:使用 SSD 存储,提高查询性能
  • 网络配置:确保与 TiKV 节点之间的网络延迟低,带宽充足
  • 跨 AZ 部署:将 TiFlash 节点部署在不同可用区,提高容灾能力

2. 配置建议

  • 启用 MPP 执行:对于复杂分析查询,建议启用 MPP 执行
  • 启用向量执行:启用向量执行可以提高查询性能
  • 调整压缩算法:根据数据特点选择合适的压缩算法,如 ZSTD
  • 配置存储容量:根据数据量大小配置合适的存储容量

3. 使用建议

  • 合理选择表:只为需要分析查询的表添加 TiFlash 副本
  • 优化查询语句:避免全表扫描,尽量使用索引
  • 控制查询复杂度:将复杂查询拆分为多个简单查询
  • 监控同步延迟:定期监控 TiFlash 同步延迟,确保数据及时性

4. 监控建议

  • 核心指标:监控同步延迟、查询性能、资源使用率等指标
  • 告警配置:设置合理的告警阈值,及时发现问题
  • 定期巡检:定期检查 TiFlash 状态,发现并解决潜在问题

常见问题(FAQ)

Q1: TiFlash 与 TiKV 有什么区别?

A1: TiFlash 和 TiKV 是 TiDB 的两种存储引擎,主要区别:

  • 存储格式:TiFlash 采用列式存储,TiKV 采用行式存储
  • 适用场景:TiFlash 适合分析查询,TiKV 适合事务处理
  • 同步机制:TiFlash 从 TiKV 实时同步数据
  • 查询执行:TiFlash 支持 MPP 执行,TiKV 支持分布式执行

Q2: TiFlash 如何保证数据一致性?

A2: TiFlash 基于 Raft Learner 协议从 TiKV 同步数据,保证与 TiKV 数据的最终一致性。当 TiDB 执行查询时,会根据事务时间戳选择合适的数据版本,确保查询结果的一致性。

Q3: 如何决定哪些表需要添加 TiFlash 副本?

A3: 建议只为需要进行复杂分析查询的表添加 TiFlash 副本,考虑因素:

  • 表的大小:大表更适合添加 TiFlash 副本
  • 查询频率:频繁进行分析查询的表适合添加
  • 查询复杂度:复杂聚合查询适合使用 TiFlash
  • 数据更新频率:TiFlash 适合更新频率适中的表

Q4: TiFlash 支持哪些压缩算法?

A4: TiFlash 支持多种压缩算法,包括:

  • LZ4:高压缩速度,适合高写入场景
  • ZSTD:平衡的压缩速度和压缩率,适合大多数场景
  • LZMA:高压缩率,较低的压缩速度
  • None:不压缩

Q5: 如何查看 TiFlash 的版本?

A5: 可以通过以下方式查看 TiFlash 版本:

  • 使用 tiup
    bash
    tiup cluster display <cluster-name> | grep Version
  • 查看日志:TiFlash 启动日志中包含版本信息
  • 使用 SQL
    sql
    SELECT TIFLASH_VERSION();

Q6: TiFlash 支持多大的数据规模?

A6: TiFlash 支持 PB 级数据规模:

  • 单个 TiFlash 节点的存储容量取决于磁盘大小
  • 支持通过增加节点线性扩展存储容量和查询性能
  • 已在生产环境中验证支持 PB 级数据

Q7: 如何优化 TiFlash 的查询性能?

A7: 优化 TiFlash 查询性能的方法:

  • 启用 MPP 执行和向量执行
  • 为表添加合适的索引
  • 优化查询语句,避免全表扫描
  • 增加 TiFlash 节点数量,提高并行处理能力
  • 调整 MPP 线程数和其他配置参数

Q8: TiFlash 支持哪些查询类型?

A8: TiFlash 支持多种查询类型:

  • 选择查询(SELECT)
  • 聚合查询(GROUP BY)
  • 连接查询(JOIN)
  • 排序查询(ORDER BY)
  • 子查询
  • 窗口函数
  • 常见表表达式(CTE)

Q9: TiFlash 如何处理数据更新?

A9: TiFlash 通过以下方式处理数据更新:

  • 从 TiKV 实时接收数据更新日志
  • 将更新应用到本地 Delta Tree 存储
  • 支持增量更新,避免全表重写
  • 定期合并数据,优化存储结构

Q10: TiFlash 适合所有分析场景吗?

A10: TiFlash 适合大多数分析场景,但也有一些限制:

  • 不适合极低延迟的查询场景
  • 不适合需要极高并发的分析场景
  • 对于简单查询,性能可能不如 TiKV
  • 数据同步存在一定延迟,不适合对实时性要求极高的场景