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
  • 数据同步存在一定延迟,不适合对实时性要求极高的场景