{
    "componentChunkName": "component---src-templates-blog-blog-detail-tsx",
    "path": "/blog/tiflash-column-database",
    "result": {"pageContext":{"blog":{"id":"Blogs_48","title":"TiFlash：并非另一个 T + 1 列存数据库丨TiDB工具","tags":["TiFlash"],"category":{"name":"产品技术解读"},"summary":"TiFlash 是配合 TiDB 体系的列存引擎，它和 TiDB 无缝结合，在线 DDL、无缝扩容、自动容错等等方便运维的特点也在 TiFlash 中得到继承，此外，TiFlash 可以实时与行存保持同步。","body":"在 [上篇关于 TiFlash 的文章](https://pingcap.com/blog-cn/tidb-and-tiflash-vs-mysql-mariadb-greenplum-apache-spark/) 发布后，我们收到了很多伙伴们的反馈，大家有各种各样的疑问。包括：TiFlash 是不是 T + 1 列存数据库？为啥实时写入也很快？读压力大怎么办？节点挂了怎么办？业务怎么接入？……今天我们就来详细回复一下大家的问题，希望能对大家理解和实践 TiFlash 有所帮助。\n\n## 并非「另一个 T + 1 列存数据库」\n\n首先，它并不是独立的列存数据库：TiFlash 是配合 TiDB 体系的列存引擎，它和 TiDB 无缝结合，在线 DDL、无缝扩容、自动容错等等方便运维的特点也在 TiFlash 中得到继承。\n\n其次，TiFlash 可以实时与行存保持同步。\n\n### T + 1 问题\n\n**「为何要列和 MySQL 的对比呢？这样是否太无聊？」**\n\n由于 TiFlash 具备实时高频实时更新能力，因此我们在 [上一篇](https://pingcap.com/blog-cn/tidb-and-tiflash-vs-mysql-mariadb-greenplum-apache-spark/) 介绍中单机对单机比较了交易型数据库例如 MySQL，因为这些特点一般是行存引擎具备的优势。TiFlash 与大多数列存不同的是，它支持实时更新，并且与行存数据保持同步。\n\n**「为何说其他列存数据库无法更新？我看到 XX 支持 Update 呀？」**\n\n多数列存引擎并不是绝对不支持更新，而是不支持主键或唯一性约束，因此无法像交易型数据库那样快速定位单条记录并进行一致性更新，这也是你无法向它们实时同步交易库数据的原因。针对这样的设计，常用的更新方式是使用 ETL 去重和融合新老数据，然后批量导入列存，这就使得数据无法实时分析而需等待数小时甚至一天。\n\nTiFlash 是为实时场景设计，因此我们必须支持实时更新。在这个前提下，通过良好的设计和工程实现，也借助 ClickHouse 极速的向量化引擎，TiFlash 仍然拥有不亚于甚至超出其他列存引擎的优异性能。大家可以参考 [上一篇文章中的 Benchmark](https://pingcap.com/blog-cn/tidb-and-tiflash-vs-mysql-mariadb-greenplum-apache-spark/) 。\n\n## 为什么实时写入也很快\n\n**「TiFlash 是列存，大家都说列存的实时写入很慢，TiFlash 呢？」**\n\n经过业界验证的实时更新列存方案是 Delta Main 设计。简单说，就是将需要更新数据与整理好的不可变列存块分开存放，读时归并，定期 Compact，而 TiFlash 也采取了类似设计思路。TiFlash 并非是拍脑袋发明了一种可更新列存结构，而是参考了其他成熟系统设计，如 [Apache Kudu](https://kudu.apache.org/kudu.pdf)，CWI 的 [Positional Delta Tree](http://www.odbms.org/wp-content/uploads/2014/07/PositionalDelat-Trees.pdf) 等的设计思路，TiFlash 的设计也兼具了 B+ 树和 LSM 的优势，在读写两端都有优异的性能（但牺牲了对 TiFlash 场景无用的点查性能）。由于无需考虑点查，因此 TiFlash 可以以进行惰性数据整理加速写入；由于引入了读时排序索引回写，因此哪怕 Compact 不那么频繁仍可以保持扫描高效，进一步减小写放大加速写入。\n\n![](https://img1.www.pingcap.com/prod/1_tiflash_design_afdbe3ed09.png)\n\n**「TiFlash 进行 OLAP 读取的时候会影响 OLTP 性能吗？」**\n\n[上篇文章](https://pingcap.com/blog-cn/tidb-and-tiflash-vs-mysql-mariadb-greenplum-apache-spark/) 中已经展示过 TiFlash 的读取性能：\n\n![](https://img1.www.pingcap.com/prod/2_read_performance_518e397cff.png)\n\n![](https://img1.www.pingcap.com/prod/3_read_performance_chart_9f2660bd02.png)\n*注：为了不影响比例，上图忽略了 MySQL 和 Oracle 数据。*\n\n下面带大家看看更新写入速度，这里做了个简单的写入测试：\n\n* 测试配置 3 节点 6 TiKV（3 副本）+ 2 节点 TiFlash（2 副本）。\n\n* sysbench write-only 测试。\n\n* 以 60954.39 的 QPS 进行混合写入更新和删除。\n\n* 同时 TiFlash 不断进行全表聚合计算。\n\n![](https://img1.www.pingcap.com/prod/4_999_duration_0e98e4688e.png)\n\n测试结果是：\n\n1. sysbench 运行 QPS 非常平稳，不会因为 AP 查询而抖动。从上图可以看到，黄色线段代表 AP 查询（开启和关闭），开启和关闭并不会对查询产生抖动，哪怕 999 分位。\n\n2. TiFlash 可以很好匹配 TiKV 的实时写入（包含增删改而非仅仅插入）同时提供查询。\n\n3. 另外，我们也观测到，以大压力写入同时进行查询，通过对 5000 个 TiFlash Region 副本采样：读取时，进行一致性校对 + 追赶 + 写入的时间平均 27.31 毫秒，95分位在 73 毫秒，99分位是 609 毫秒，对于分析类查询，这个延迟稳定性是可以接受的。\n\n实际上，在都只写 1 副本的情况下，TiFlash 的写入性能大致可以追上 2-3 个同规格 TiKV 节点，这确保了 TiFlash 在更少的资源配比下，也可以匹配 TiKV 的写入压力。\n\n### 为何如此？\n\n由于 TiFlash 引擎针对 AP 场景无需点查的不同设计，它相对 LSM 引擎减小了写放大比率：TiFlash 的写放大大约在 3-7 倍之间。且在写入约繁忙情况下，由于攒批效果反而越接近更小的三倍放大比率。而 LSM 结构下，RocksDB 的写放大在 10 倍左右。这个对比优势大大提高了 TiFlash 磁盘实际能承载的业务吞吐量。\n\n## 方便敏捷的运维\n\n### 灵活扩容\n\n**「如果读压力也很大，你光写得够快有啥用啊？」**\n\n虽然我们展示了 TiFlash 的写入性能，其实哪怕它的写入速度不如 TiKV，我们仍然可以单独对 TiFlash 进行扩容。不管 TiFlash 的写入性能多优秀，仍然有可能因为用户的查询读取压力过大而造成写入速度下降，这时候是否就会产生严重的复制延迟呢？\n\n会。但是 TiFlash 却可以依靠 TiDB 的体系单独扩容，如果业务压力过大，多上线几台 TiFlash 节点就可以自然分担数据和压力，用户完全无需操心扩容过程，这些都是透明且自动的。相对于同节点的行列混合设计，这样的架构无疑更灵活，且仍然保持了一致性。\n\n### 自动恢复\n\n**「节点挂了怎么办？」**\n\n当 TiFlash 节点损坏下线，TiDB 体系可以保证 TiFlash 的数据自动从行存恢复副本，而补副本的过程也会考虑不对 TiKV 产生冲击。在 TiFlash 多副本的情况下，这个过程对用户也是完全透明无感知的：你只需要将补充的服务器启动上线就行。\n\n### 无阻塞 DDL\n\n**「TiFlash 支持 DDL 吗？」**\n\nTiFlash 继承了 TiDB 体系的在线 DDL，尤其是它支持了更改列类型。与传统列存系统需要完全重写列格式不同，TiFlash 支持混合表结构，每个列数据块可以有独立的表结构，这使得 TiFlash 更改列类型是完全实时且无负担的：没有数据需要被立刻重写。这种设计，使得 TiFlash 可以很容易被用于数据集成场合，任何上游数据源的表结构变更可以无阻塞地被同步。\n\n## 快速的业务接入\n\n上述所有这些特性，使得 TiFlash 体系可以非常便捷地承载实时分析业务。考虑一下如果你有一个新业务上线，你需要将在线业务接入分析平台例如 Hadoop，你也许需要做如下事情：\n\n1. 修改业务逻辑，在表结构中添加变更时间标记以便增量抽取。\n\n2. 编写定时任务，从源数据库中抽取增量数据。\n\n3. 将数据写入 Staging 表，通过和 Hive 目标表进行 JOIN 并回写以处理增量更新。\n\n4. 很可能你还需要编写数据校验代码定期检查一致性。\n\n5. 那么也意味着你需要编写不一致时的修复代码。\n\n这个过程可能需要耗费数天，甚至更久，而你还需要维护整个传输链路。\n\n在 TiDB + TiFlash 体系下，你只需要一条命令：\n\n```SQL\nALTER TABLE your_table SET TIFLASH REPLICA 1;\n```\n\n你就可以自动获得一份实时保持一致的列存数据镜像，进行实时分析。\n\n**5秒（取决于你的手速） vs 数天**\n\n即便你已经有完整的 Hadoop 数仓建设，TiFlash 配合 TiSpark，也可以轻松衔接两个平台的同时，为离线数仓提供实时分析能力。\n\n## 欢迎尝鲜\n\nTiFlash 已经在进行第一轮用户测试，并在近期开启第二批用户测试，请关注后续信息，也欢迎联系询问提前体验 maxiaoyu@pingcap.com。来信请注明如下信息：姓名，公司，业务场景，是否已经是 TiDB 用户。","date":"2020-03-20","author":"马晓宇","fillInMethod":"writeDirectly","customUrl":"tiflash-column-database","file":null,"relatedBlogs":[]}}},
    "staticQueryHashes": ["1327623483","1820662718","3081853212","3430003955","3649515864","4265596160","63159454"]}