TIDB-Lightning是什么
简单来说TIDB Lightning是一个能把源数据快速全量导入到TIDB集群的工具。在这段描述中有三个重点单词:快速、全量、TIDB集群,快速指的是TIDB Lightning的速度较快,在建议配置可以达到300G的速度,当然实际的速度是取决于硬件的性能情况。全量指的是TIDB Lightning用来进行全量数据的导入,比如在初始化TIDB集群的时候需要用到,TIDB Lightning不能用于增量数据的同步,如果需要使用增量数据可以使用dm进行。
为什么要有TIDB Lightning
在做全量同步的时候可以使用的方式有很多,比如可以用DM中集成的DM工具也可以做全量的数据迁移,那么为什么还需要专门的一个TIDB Lightning工具做全量导入的。
在使用SQL做全量迁移的过程中(比如使用mydumper)因为都是通过insert语句方式进行的导入,所以在导入过程中TIDB需要做大量的工作。比如:
需要保证ACID特性带来的开销;
region分裂过程中的开销。因为在一开始的时候对表的insert基本都在一个region中完成,那么这个region很容易就就成为热点region,写入会密集的集中在某一个TIKV上面,这种情况下需要持续一段时间直到PD完成leader的调度工作,在一个大表写入完成之后,新表的写入也会发生上面提到的事情,这样也就造成了性能的额外开销。
另外就是在分层压缩下导致的写放大。
在使用SQL做全量导入的时候不免会发生上述的三个问题,那么怎么去解决这些问题呢?TIDB是一个高度分层的结构,既然走TIDB_Server层需要遇到acid的问题,而且我们主要也是在做数据的导入工作,没有业务的活动,那么就可以通过绕过TIDB_SERVER层的方式解决事务的开销。对于region热点的问题就更容易解决了,可以通过预先分配region的方式解决。第三个问题也可以通过预先的排序降低TIKV压缩时的复杂度来解决。TIDB Lightning就是为此而生的。
整体架构
在TIDB-Lightning结构中,导入的过程主要有如下流程:
Lightning对mydumper导出目录进行解析,筛选出DDL这些建表的语句。然后将执行语句发送给TIDB_SERVER执行。
Lightning对表的insert语句进行解析和编码,通过kv编译器转换为KV,然后发给importer组件。
importer组件进行排序分裂、上传数据到tikv等一系列的操作,最后进行导入。
Lightning
Lightning目前只能实现对mydumper导出,主要步骤有:
1、扫描。Lightning组件会首先对备份的文件进行一次扫描,获取表结构定义数据和表数据(insert into),对于表结构的定义语句会直接发送给TIDB_Server进行处理。
2、建表。TIDB Server收到表结构定义语句,进行建表等操作。
3、解析表数据。在TIDB的整体结构中,TIDB_Server负责对SQL进行解析,在Lightning中会调用TIDB对sql文件进行解析,这里的TIDBServer是本地的TIDB,寄存于Lightning的内存中。Lightning 会直接使用 TiDB 实例来把 SQL 转换为 KV 对,这个就是图中的KV解析器,同时Lightning还会把文件分割为默认256M的区块,以便并行执行操作。
4、将解析编码后的数据发送给importer
Lightning的并发策略主要有如下三个参数:
index-concurreny=2
table-concurreny=2
region-concurreny=40
importer
importer主要的工作:
1、排序。毫无疑问,从Lightning发送过来的kv肯定是一种无序的状态,importer首先要做的事情就是需要对kv进行排序。importer直接使用rocksdb对数据进行排序,在排序前会预先分配一定的空间,这些预先分配的空间可以叫engine file,每一个engine file都可以看成是一个rocksdb。排序的时候只需要把KV导入到这些engine file,rocksdb就可以帮助我们完成排序合并等一系列的操作。
2、预分配region。importer会根据要导入的数据范围(这个时候已经收到数据自然知道对于的范围了)预先分配region,如果通知PD在导入前就完成pd的调度工作。这样就避免了在导入过程中产生热点region的问题。
3、上传数据。如果importer排序(其实是rocksdb干的)后的文件均是一些sst文件,这些数据需要上传到对应的tikv上去。
4、将数据导入到raft-group中
后续工作
1、数据校验
2、统计分析、自增列id处理
对于自增列来说,因为数据不是通过tidb是通过tivk直接导入的,那么自增列就存在一定的问题,如果不处理则可能导致唯一键冲突的问题。
部署需求
TIKV的空间:
数据源大小*索引倍率(2)*副本数(3)*压缩比(0.7)
数据源大小一般是不包含索引的,而编码后会有索引。
raft默认有3个副本,所以需要*3
TIKV会进行数据的压缩,建议按照0.7进行计算
TIKV的网络需求:
建议使用万兆网卡,另外需要注意如果所有的带宽都被importer占用,那么会导致TIKV同PD的交互出现问题,PD可能会认为节点已经被下线,在使用千兆网卡的时候容易出现,建议使用upload-speed-limit进行网络限制。
Lightning硬件需求:
32+Cpu
足够储存整个数据源的 SSD 硬盘,读取速度越快越好
使用万兆网卡,带宽需 300 MB/s 以上
运行过程默认会打满 CPU,建议单独部署。如果必须同其他组件一同部署,需要配置region-concurrency 限制 tidb-lightning 的 CPU 使用
tikv-importer硬件要求:
32+ 逻辑核 CPU
40 GB+ 内存
1 TB+ SSD 硬盘,IOPS 越高越好(要求 ≥8000)
硬盘必须大于最大的 N 个表的大小总和,其中 N = max(index-concurrency, table-concurrency)。
使用万兆网卡,带宽需 300 MB/s 以上
运行过程中 CPU、I/O 和网络带宽都可能打满,建议单独部署。
关于importer内存的使用计算:
(max-open-engines(8) × write-buffer-size × 2) + (num-import-jobs × region-split-size × 2)
max-open-engines:
write-buffer-size:数据刷到硬盘前能存于硬盘的上限
num-import-jobs:导入认为的并发数
region-split-size:把要导入的数据切分为这个大小的 Region,之所以要*2是因为有两个列族(数据和索引)
机器不够(混合部署)怎么办
1、在Lightning上把region-concurrency设为分配给Lightning的cpu数量,建议为全体CPU的75%。
2、在importer上面,降低table-concurrency+index-concurrency的数量降低对磁盘的使用,这两个参数分别是对表的并发处理数和索引的并发处理数量假设他们的值都为1,那么importer的空间只需要一张最大表大小就好了。
3、在importer上面降低num-import-jobs减少对cpu和内存的使用
4、设置upload-speed-limit限制带宽,带宽不够可能会导致pd获取不到tikv的状态。