在 0 和 1 的计算机世界里,开发者和程序员们为了晋升零碎运行速度、最大化开释服务器性能,也要面对各种各样的挑战,一直提出计划,开展实际,以冲破瓶颈、解决难题。
个推“大数据降本提效”专题,正是通过总结分享本身在大数据实战过程中的踩坑教训、调优技巧等,为从业人员发展大数据实际提供参考。本文是“大数据降本提效”专题的第三篇,将为大家分享个推通过调优,实现 TiDB 千倍性能晋升的实战经验。
个推与 TiDB 的结缘
作为一家数据智能企业,个推为数十万 APP 提供了音讯推送等开发者服务,同时为泛滥行业客户提供业余的数字化解决方案。在疾速倒退业务的同时,公司的数据体量也在高速增长。随着工夫的推移,数据量越来越大,MySQL 曾经无奈满足公司对数据进行疾速查问和剖析的需要,一种反对程度弹性扩大,可能有效应对高并发、海量数据场景,同时高度兼容 MySQL 的新型数据库成为个推的选型需要。
通过深刻调研,咱们发现“网红”数据库 TiDB 不仅具备以上个性,还是金融级高可用、具备数据强一致性、反对实时 HTAP 的云原生分布式数据库。因而,咱们决定将 MySQL 切换到 TiDB,冀望实现在数据存储量一直增长的状况下,依然确保数据的疾速查问,满足内外部客户高效剖析数据的需要,比方为开发者用户提供及时的推送下发量、达到率等相干数据报表,帮忙他们科学决策。
实现选型后,咱们就开始进行数据迁徙。本次迁徙 MySQL 数据库实例的数据量无数 T 左右,咱们采纳 TiDB 自带的生态工具 Data Migration (DM) 进行全量和增量数据的迁徙。
全量数据迁徙:从数据源迁徙对应表的表构造到 TiDB,而后读取存量数据,写入到 TiDB 集群。
增量数据复制:全量数据迁徙实现后,从数据源读取对应的表变更,而后写入到 TiDB 集群。
个推将 MySQL 数据迁徙到 TiDB
当数据同步稳固之后,将利用逐渐迁徙到 TiDB Cluster。把最初一个利用迁徙实现之后,进行 DM Cluster。这样就实现了从 MySQL 到 TiDB 的数据迁徙。
注:DM 的具体配置应用详见官网文档。
陷入 TiDB 应用的“反模式”
然而,当利用全副迁徙到 TiDB 之后,却呈现了数据库反馈慢、卡顿,利用不可用等一系列的问题。
如下图:
登陆数据库时遇到卡顿
通过排查,咱们发现有大量的慢 SQL 都是应用 load 导入数据的脚本。
慢 SQL 的导入耗时几十分钟
和业务方沟通后,咱们发现有些导入语句就蕴含几万条记录,导入工夫须要耗时几十分钟。
比照之前应用 MySQL,一次导入只需几分钟甚至几十秒钟就实现了,而迁到 TiDB 却须要双倍甚至几倍的工夫才实现,几台机器组成的 TiDB 集群反而还不如一台 MySQL 机器。
这必定不是关上 TiDB 的正确姿态,咱们须要找到起因,对其进行优化。
单个服务器负载过高
通过查看监控,发现服务器负载压力都是在其中一台机器上(如上图,红色线框里标注的这台服务器承当次要压力),这阐明咱们目前并没有充分利用到所有的资源,未能施展出 TiDB 作为分布式数据库的性能劣势。
关上 TiDB 的正确应用姿态
首先优化配置参数
具体如何优化呢?咱们首先从配置参数方面着手。家喻户晓,很多配置参数都是应用零碎的默认参数,这并不能帮忙咱们正当地利用服务器的性能。通过深刻查阅官网文档及多轮实测,咱们对 TiDB 配置参数进行了适当调整,从而充分利用服务器资源,使服务器性能达到现实状态。
下表是个推对 TiDB 配置参数进行调整的阐明,供参考:
重点解决热点问题
调整配置参数只是根底的一步,咱们还是要从根本上解决服务器负载压力都集中在一台机器上的问题。可是如何解决呢?这就须要咱们先深刻理解 TiDB 的架构,以及 TiDB 中表保留数据的外在原理。
在 TiDB 的整个架构中,分布式数据存储引擎 TiKV Server 负责存储数据。在存储数据时,TiKV 采纳范畴切分(range)的形式对数据进行切分,切分的最小单位是 region。每个 region 有大小限度(默认下限为 96M),会有多个正本,每一组正本,成为一个 raft group。每个 raft group 中由 leader 负责执行这个块数据的读 & 写。leader 会主动地被 PD 组件(Placement Driver,简称“PD”,是整个集群的治理模块)平均调度在不同的物理节点上,用以均分读写压力,实现负载平衡。
TiDB 架构图(图片来源于 TiDB 官网)
TiDB 会为每个表调配一个 TableID,为每一个索引调配一个 IndexID,为每一行调配一个 RowID(默认状况下,如果表应用整数型的 Primary Key,那么会用 Primary Key 的值当做 RowID)。同一个表的数据会存储在以表 ID 结尾为前缀的一个 range 中,数据会依照 RowID 的值顺序排列。在插入(insert)表的过程中,如果 RowID 的值是递增的,则插入的行只能在末端追加。
当 Region 达到肯定的大小之后会进行决裂,决裂之后还是只能在以后 range 范畴的末端追加,并永远仅能在同一个 Region 上进行 insert 操作,由此造成热点(即单点的过高负载),陷入 TiDB 应用的“反模式”。
常见的 increment 类型自增主键就是按程序递增的,默认状况下,在主键为整数型时,会将主键值作为 RowID,此时 RowID 也为程序递增,在大量 insert 时就会造成表的写入热点。同时,TiDB 中 RowID 默认也依照自增的形式程序递增,主键不为整数类型时,同样会遇到写入热点的问题。
在应用 MySQL 数据库时,为了不便,咱们都习惯应用自增 ID 来作为表的主键。因而,将数据从 MySQL 迁徙到 TiDB 之后,原来的表构造都放弃不变,依然是以自增 ID 作为表的主键。这样就造成了批量导入数据时呈现 TiDB 写入热点的问题,导致 Region 决裂一直进行,耗费大量资源。
对此,在进行 TiDB 优化时,咱们从表构造动手,对以自增 ID 作为主键的表进行重建,删除自增 ID,应用 TiDB 隐式的_tidb_rowid 列作为主键,将
create table t (a int primary key auto_increment, b int);
改为:
create table t (a int, b int)SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=2
通过设置 SHARD_ROW_ID_BITS,将 RowID 打散写入多个不同的 Region,从而缓解写入热点问题。
此处须要留神,SHARD_ROW_ID_BITS 值决定分片数量:
SHARD_ROW_ID_BITS = 0 示意 1 个分片
SHARD_ROW_ID_BITS = 4 示意 16 个分片
SHARD_ROW_ID_BITS = 6 示意 64 个分片
SHARD_ROW_ID_BITS 值设置的过大会造成 RPC 申请数放大,减少 CPU 和网络开销,这里咱们将 SHARD_ROW_ID_BITS 设置为 4。
PRE_SPLIT_REGIONS 指的是建表胜利后的预平均切分,咱们通过设置 PRE_SPLIT_REGIONS=2,实现建表胜利后预平均切分 2^(PRE_SPLIT_REGIONS) 个 Region。
经验总结
· 当前新建表禁止应用自增主键,思考应用业务主键
· 加上参数 SHARD_ROW_ID_BITS = 4 PRE_SPLIT_REGIONS=2
此外,因为 TiDB 的优化器和 MySQL 有肯定差别,呈现了雷同的 SQL 语句在 MySQL 里能够失常执行,而在 TiDB 里执行慢的状况。咱们针对特定的慢 SQL 进行了深入分析,并针对性地进行了索引优化,获得了不错的功效。
优化成绩
通过慢 SQL 查问平台能够看到,通过优化,大部分的导入在秒级工夫内就实现了,相比原来的数十分钟,实现了数千倍的性能晋升。
慢 SQL 优化后果
同时,性能监控图表也显示,在负载高的时刻,是几台机器同时高,而不再是独自一台升高,这阐明咱们的优化伎俩是无效的,TiDB 作为分布式数据库的劣势得以真正体现。
优化后,实现服务器负载平衡
总结
作为一种新型分布式关系型数据库,TiDB 可能为 OLTP(Online Transactional Processing)和 OLAP(Online Analytical Processing)场景提供一站式的解决方案。个推不仅应用 TiDB 进行海量数据高效查问,同时也开展了基于 TiDB 进行实时数据分析、洞察的摸索。
后续更多“大数据降本提效”的干货分享,请大家继续锁定个推技术实际公众号~