外观
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 存储详细步骤:
- TiKV Leader 处理写入请求,生成 Raft 日志
- Raft 日志复制到 TiFlash Learner
- TiFlash 解析 Raft 日志,提取数据变更
- 将行存格式转换为列存格式
- 将数据写入 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: 202922. 使用 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.port | 9000 | TiFlash 服务端口 |
server.status_port | 20170 | 状态端口,用于监控 |
server.tcp_port | 9009 | TCP 服务端口 |
server.http_port | 8123 | HTTP 服务端口 |
storage.main.dir | "./data" | 数据存储目录 |
storage.main.capacity | 0 | 存储容量限制(字节),0 表示无限制 |
2. 同步配置
| 参数 | 默认值 | 说明 |
|---|---|---|
raft.flash.service_addr | "" | Flash 服务地址 |
raft.flash.proxy_addr | "" | Flash Proxy 服务地址 |
raft.flash.replica_count | 1 | 默认 TiFlash 副本数 |
raft.flash.apply_batch_size | 32 | 批量应用日志大小 |
3. 查询配置
| 参数 | 默认值 | 说明 |
|---|---|---|
mpp.enable | true | 是否启用 MPP 执行 |
mpp.max_threads | 16 | MPP 查询的最大线程数 |
mpp.stream_send_queue_size | 1024 | MPP 流发送队列大小 |
vectorized_execution.enable | true | 是否启用向量执行 |
使用场景
1. 实时数据分析
- 场景:需要对实时数据进行复杂分析查询
- 优势:无需 ETL,直接查询实时数据,延迟低
- 示例:实时销售报表、用户行为分析、运营监控
2. 历史数据查询
- 场景:需要查询大量历史数据
- 优势:列式存储和压缩,减少存储成本,提高查询性能
- 示例:历史订单查询、年度报表生成、趋势分析
3. 复杂聚合查询
- 场景:需要进行多维度复杂聚合查询
- 优势:MPP 并行执行,加速复杂查询
- 示例:多维度 OLAP 查询、数据挖掘、机器学习
4. 即席查询
- 场景:需要进行灵活的即席查询
- 优势:支持 SQL 语法,无需学习新的查询语言
- 示例:数据分析人员的即席查询、业务探索
性能优化
1. 存储优化
调整压缩算法:
tomlstorage.main.compression = "zstd"调整块大小:
tomlstorage.main.block_size = 65536配置存储容量:
tomlstorage.main.capacity = "1Ti"
2. 查询优化
启用 MPP 执行:
tomlmpp.enable = true调整 MPP 线程数:
tomlmpp.max_threads = 32启用向量执行:
tomlvectorized_execution.enable = true
3. 同步优化
调整批量应用大小:
tomlraft.flash.apply_batch_size = 64调整副本数:
tomlraft.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 tiflash3. 扩容 TiFlash
bash
# 编辑拓扑文件,添加新节点
vi topology.yaml
# 扩容集群
tiup cluster scale-out <cluster-name> topology.yaml4. 缩容 TiFlash
bash
# 编辑缩容配置文件
vi scale-in.yaml
# 缩容集群
tiup cluster scale-in <cluster-name> -N <tiflash-node-ip>:90005. 调整 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
- 数据同步存在一定延迟,不适合对实时性要求极高的场景
