https://www.jianshu.com/p/d5ee4dca66d8

TiDB概览

先来一段官网的描述

 
 

TiDB server:无状态SQL解析层,支持二级索引,在线ddl,兼容MySQL协议,数据转储
SQL输入->解析语法树(AST)->逻辑计划分析->执行计划优化
->cost-base model->物理计划选择->计算下推tikv->聚合tikv执行结果

PD server: 协调层,存储集群元数据,region调度,事务时间戳TSO。存储每个 TiKV 节点实时的数据分布情况和集群的整体拓扑结构,内置仪表盘dashboard.

TiKV/TiFlash:存储层,tikv行存储引擎,事务类处理走tikv;tiFlash列存储引擎,分析类处理走tiFlash。tikv,基于LSM算法的RocksDB单机Key-Value 存储引擎,TiDB 的 SQL 层做完 SQL 解析后,会将 SQL 的执行计划转换为对 TiKV API 的实际调用。
tikv存储单位为region,关于region的介绍可以参考这里同时里面还有raft的相关介绍,目前最主要记住TIKV以 Region 为单位做 Raft 的复制和成员管理同时只需要同步复制到多数节点,即可安全地认为数据写入成功

 
 

特性:
易拓展:计算能力(TiDB)和存储能力(TiKV)均可水平拓展,但集群中只有一个PD能被选举为leader
高可用:TiDB/TiKV/PD 三大组件均可cluster模式部署
高效存储:基于LSM算法的RocksDB单机存储引擎,lz4、zstd等高效压缩算法,除了 RocksDB之外,TiDB 还支持一些流行的单机存储引擎,比如 GolevelDB、BoltDB 等
安全存储:采用Raft 协议复制数据,多副本防止单机失效
分布式事务:支持ACID事务,不同于XA,客户端调用无需设置数据源为xa,天然分布式事务
易用性:支持MySQL协议,使用MySQL语法,MySQL客户端均可直接连接登陆

因测试环境受限,我们的环境较多软硬件都不符合官方配置要求,啊哈哈哈。。。但这并不影响我们对技术的研究和使用,再穷也要创造条件顶硬上。

一、部署环境

对比项 官方配置 实际配置
操作系统 Red Hat Enterprise Linux7.3 及以上 Red Hat 4.8.5-36
硬盘 部分组件ssd,部分组件sas 机械硬盘raid

其余硬件,实际部署环境CPU 8核,内存16G,千兆网卡。

官网推荐如下

 
 

TiDB 和 PD 可以部署在同一台服务器上。
如对性能和可靠性有更高的要求,应尽可能分开部署。
官网参考
虽然实际测试环境,使用的raid挂载的是机械硬盘,但是读写能力并不弱,dd指令数据如下:

 

本次使用主机11台(10.248.7.154-164)

二、拓扑

 

查看集群状态
tiup cluster display tidb-test

 

当然还有更直观的仪表盘(PD内置,访问PD服务http:ip+port/dashboard).也可以先在部署TiUP的机器执行 tiup cluster display tidb-test --dashboard得到,即

 

使用数据库用户root登陆

 

还可以使用额外部署的grafana:http://10.248.7.163:3000

 

三、测试与优化

场景:大文件,多文件数据入库,入库首先保证速度,最终一致即可(CAP中的AP)文件有备份,可重新入库。入库后简单OLAP操作。
测试准备:入库应用(可配置单次入库记录数),500万行数据文件(写成6个文件)

这里先来说一个异常场景,这个场景刚好可以对比磁盘性能差异引起的tidb性能差异,同时对理解热点问题和对应调优有一定帮助。

在最开始压测的时候,tikv节点的三台主机(raid 22块磁盘),其中有两台主机raid cache电池故障,导致raid cache失效,这两台主机的IO性能严重受影响

 

当然,在测试的时候,事先是并不知道这个问题的,并在此基础上做了一些研究和调优。接下来简要说下过程(以下过程均访问单个TiDB-server):

1、首次压测(单批次5000行记录,5线程)

由于扩展tikv前的图已丢失(现raid电池问题已修复,无法重现),只能贴上4tikv的图了,不过除了加多一个节点,现象差不多,后面再做扩缩容的演示

 

由图可以看出,除了正常的161外,其余的tikv节点,IO均已跑满(163为应用部署主机)。考虑两点,磁盘性能差异、region分布不均匀。
再来看下热点region的图:

 

可以看出,hot region leader的分布非常不均匀。以三副本(peer)为例,根据raft协议,当写入时,首先写入到region leader,写完leader之后再同步拷贝到其余两个节点的region follower 参考官网说明。这里就考虑两个热点部分不均匀的可能:1、单批次提交事务过大,导致同一时间内数据集中在一个region,在未超过一定大小时(默认 96M)并没有分裂region;2、主键有序程度高,导致排序分裂region时,数据在region中比较集中。
入库结果:

 

平均一百万行需要6-7分钟。从文件数据看,先慢后快,这跟初始化时只有单个region有关,只有达到单个region限制后才会分裂。参考这里可先不对此过度优化。

2、第二次压测(单批次2000行记录,10线程)

基于第一次的压测结果,修改单批次提交记录数,并加大线程分散提交的事务。修改后tikv节点的IO使用率并无太多变化。入库速度略有上升:

 
3、第三次压测(单批次2000行记录,10线程,乱序)

在修改了批次大小后,继续修改使主键乱序,同上,IO使用率依旧没有多大变化。不过入库速度有较大提升(平均一百万3分钟):

 

经此两次调整后,region leader热点已分布比较均匀:

 

到目前为止,一直忽略了一个事情,没有观察总的region leader情况:

 

从图看,总的leader分布是很均匀的,且写入字节总量各个tikv节点也大致相同,但是hot leader为什么这么不均匀而且为什么其中一个tikv IO使用率低这么多呢,矛头指向了磁盘性能问题,经排查后发现,磁盘电池故障,raid cache失效。

4、第四次压测(单批次2000行记录,10线程,乱序,sync-log = false)

在磁盘问题修复前,我们找到一处关于sync-log的说明

 

以三副本为例,需要至少写完两个副本之后,才能向客户端返回ack。因此关闭同步日志,异步写follower的副本,相当于写单机的时间。这里牺牲了CAP中的C,只需最终一致即可。我们的应用场景适用,同时我们文件有备份,即便出错可以重新导入。但是对于实时性较强,对一致性要求较高的金融场景,不建议关闭同步日志。
操作需使用Tiup:
执行tiup cluster edit-config tidb-test

 

修改完成后执行:tiup cluster reload tidb-test -R tikv 重启tikv
修改后入库效率如下:

 

一百万行记录入库时间优化到2分钟。

不过在修复磁盘后发现,这个参数在我们的场景影响并不是很大,良好的io性能使得这个参数设置变得不那么重要,因此在修复磁盘后的测试中,我们都是基于开启同步日志的场景

修复磁盘后测试

修复后的tikv 磁盘性能均有如下表现:

 

修复磁盘后,我们测试的条件为:3TiKV3副本,单批次2000行记录,10线程,乱序。恢复同步日志配置的修改。
来看下修复后的TiDB表现:

 

hot region leader 均匀分布,peer(副本)也是均匀分布

 

入库效率如下(平均100万行记录1.5分钟):

 

直觉告诉我们,事情肯定还没有结束,应该还有优化的空间。似乎到目前为止,我们都没有好好看看TiDB-server的情况:

 

到目前为止,我们都是直接访问单个的TiDB-server。因此出现了如图的CPU负载情况,只有157的tidb CPU快到7个核的使用率。由于tidb-server是无状态的,可以通过负载来给另外两个tidb-server分活了。本例使用NGINX,配置如下:

 

修改访问地址,客户端通过连接NGINX访问tidb 10.248.7.154:4000

 
 

通过NGINX负载后,每个tidb-server的cpu都得到了利用,同时平均一百万行记录入库时间优化到1分钟。

按照对官方文档的理解,tidb的计算能力和存储能力都可以扩展,目前我们通过NGINX负载实现了tidb-server计算能力的负载。但是计算不仅仅在tidb-server。tidb-server 解析SQL生成执行计划之后,会有一部分的计算下推到tikv。这也是为何tikv和tidb 这两个组件的实例不能部署在同一台主机。那么扩充tikv节点后,性能会有多大程度提高?另外扩充的节点会不会自动协调原有节点的region呢?

扩展tikv节点
扩展前,肯定要先看看原有的磁盘占用情况:

 
 

扩容过程中,正逐渐转移数据到新的tikv节点。稳定后如下图:

 

不过在入库效率上,提升并不明显,时间上和扩容前相差不多。有以下原因,原本的三节点并行入库性能还有较多可利用空间,相当于只是把部分处理迁移到新节点,单原先节点的处理能力还有很多富余,需要原先的节点IO和CPU有较高使用率时,扩充节点才能有较多的性能提升region调度策略

 

CPU和IO使用率都不大。

同等主机环境的MySQL入库情况如下:

 

在主键无序的情况下,随着数据量的增大,入库性能急剧下滑,这跟索引树叶子节点在主键无序时,频繁分裂调整树结构有关。主键有序时,入库性能中 规中矩,不过即便是有序,在数据量多了以后,入库性能也会下滑。所以MySQL单表有大小要求,超过一定大小之后最好选择分库分表,但是这也会引入另外的问题,业务应用测也要对此做大量的改造。

同等主机环境MySQL与tidb查询性能对比:
当前分区500万行记录查询,查询SQL

select SETTLE_DATE AS "账期日",COUNT(0) AS 成功条数,SUM(JSON_EXTRACT(JSON,'$.Payment')) AS 成功总金额(分)
FROM BL_BATCH_TEST TDP
WHERE TDP.SETTLE_DATE = '20201201' and JSON_EXTRACT(JSON,'$.IsSuccess') = '0' and JSON_EXTRACT(JSON,'$.Result') = '0' group by SETTLE_DATE;
 

TIDB

 

mysql

 
 

(mysql的数据同事帮我跑的,啊哈哈)
对比来看,tidb查询性能较为稳定,即便重启所有组件清楚缓存后(图中第二次查询 ),单个分区500万行记录,查询8s,再次查询时间减半,MySQL第一次查询耗时80+s,第二次查询也能维持较好的性能。通常业务查询(OLAP),最重要的是首次时间,第二次的查询时间参考意义不大,因此稳定的查询时间尤为重要。MySQL和tidb在重启后,首次查询时间都相对要久一点,这跟加载磁盘数据到内存耗费有关,tikv几个节点堆起来的内存跟MySQL单机的内存比,是不太公平的,但这也正是tidb的优势。

总结:
1、TiDB-server是计算密集型组件,同时也会将部分计算下推到TiKV,而TiKV是IO密集型组件,因此TiDB和TiKV不能在同一台主机部署。PD存储元数据会频繁写磁盘,对磁盘IO要求高,因此也不能和TiKV同部署,PD可以和TiDB-server同主机部署。
2、TiKV (集成raft协议)以region为存储单位,超过默认96M后会分裂,通过raft协议做leader选举和副本(即peer)复制,每个region都会有leader 副本,其余的副本为follower,客户端读写只会通过region的leader节点,写入时,写完leader后再复制到follower,超半数以上副本写入完成即认为写入成功。
增减tikv节点,或者修改replication.max-replicas后,PD会通过region的心跳判断当前副本情况,从而调度副本到新节点或者增减副本。
3、通过grafana和PD自带的dashBoard可以实时查看当前系统的问题,比如TIDB节点的CPU使用率、QPS;TIKV节点的CPU、IO使用率;通过PD查看热点分布和region分布于调度情况;通过PD 的dashBoard查看慢sql,集群状态,调用栈火焰图等等。
CPU使用率单核不要超过80%,超过不管是TIDB节点和TIKV都要考虑扩容
tikv节点内存不要超过60%使用率,IO达到80%可视为到达瓶颈
4、region数量单个tikv小于50K, grpc延迟尽可能小于100ms。过多的region会导致调度频繁影响性能,grpc延迟增大。可考虑设置region合并参数

以下配置意为:key数目小于200000,region大小小于20M的合并(默认)
set config pd `schedule.max-merge-region-keys`=200000;
set config pd `schedule.max-merge-region-size`=20;

5、当TIDB节点CPU过高时,如是正常SQL执行需要,可考虑增加TIDB节点,并通过Nginx,HaProxy等负载工具分发到不同节点执行。当Tikv 出现较高水平的cpu使用率或者IO使用率,可考虑增加TiKV节点。TiKV对磁盘要求较高,尽量使用SSD磁盘,或者多磁盘raid
6、出现热点region的时候,有几个地方可以查看,比如grafana监控中的PD可以看相关的hot region分布情况,这是最直观的方式;还可以通过监控中的tikv,查看各节点CPU和IO使用情况,当出现热点问题是,这两个指标在各个节点时很不均匀的,尤其THread cpu的corprocessor 或 scheduler(负责读/写模块的线程)。
7、解决热点region的问题,主要在于分散region数据的分布,减少频繁读写同一个region。通过减少单批次提交记录数(小事务),非自增乱序的主键(官网要求int类型的主键。5.0之后将支持vchar),频繁访问相同数据通过内存访问,从业务层面拆分热点数据等手段减少热点。但在所有的tikv都出现较多热点region时,这时应考虑扩充tikv节点。当tikv节点region分布不均匀,CPU和IO使用率不均匀时,还应考虑硬件性能问题,部分硬件性能会影响整体系统性能。
8、RocksDB默认使用snappy压缩算法,不过TiKV有分层使用压缩算法,默认["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"]当数据量超过 500G 时 RocksDB 的层数才会超过 4, 超过 500G 部分的数据才会启动 ZSTD 压缩算法。lz4解压缩速度及压缩比都优于snappy;ZSTD压缩比更高,解压缩比lz4慢,适合层级高的老数据。
9、RocksDB的LSM树

 

如图:wal相当于MySQL 的redo log。从wal->menorytable(可修改Memtable--》不可修改immutable Memtable)->SST,读放大和写放大问题都会存在,写放大在于sst逐渐往下compact(异步线程);而读放大在于需要逐层查找,且层数越往下,压缩率越高,效率越低。
10、理论上,tidb-server节点和tikv节点都可以无限扩充,但是PD整个集群只能有一个leader,因此扩充能力受限于PD节点的处理能力,此外网络带宽也是限制因素之一。

未完待续......
raft算法与分布式事务percolator、两阶段提交
为何使用kv存储引擎
两个tidb集群间实时同步(异地双中心双活)

参考资料

TiDB官网
官网FAQ
TiDB in action
在线修改配置,非持久化配置
LSM && RocksDB compaction策略
RocksDB解析
region调度策略
TiDB 高并发写入场景最佳实践
TiDB 热点问题处理
海量 Region 集群调优
Percolator 和 TiDB 事务算法
TiDB 集群推荐使用 SSD 的原因

[转帖]TiDB调优小结的更多相关文章

  1. JVM调优小结

    JVM调优浅谈 https://www.cnblogs.com/andy-zhou/p/5327288.html   1.数据类型 java虚拟机中,数据类型可以分为两类:基本类型和引用类型. 基本类 ...

  2. 【Hive六】Hive调优小结

    Hive调优 Hive调优 Fetch抓取 本地模式 表的优化 小表.大表Join 大表Join大表 MapJoin Group By Count(Distinct) 去重统计 行列过滤 动态分区调整 ...

  3. XGBoost参数调优小结

    https://mp.weixin.qq.com/s?__biz=MzU0MDQ1NjAzNg==&mid=2247485630&idx=1&sn=9edf2bfd771cf4 ...

  4. [转帖]jdk8 Metaspace 调优

    jdk8 Metaspace 调优 https://blog.csdn.net/bolg_hero/article/details/78189621 转帖 简介 从JDK8开始,永久代(PermGen ...

  5. [转帖]JVM性能调优详解

    JVM性能调优详解 https://www.cnblogs.com/secbro/p/11833651.html 应该是 jdk8 以前的方法 貌似permsize 已经放弃这一块了. 前面我们学习了 ...

  6. MySQL性能调优与架构设计——第9章 MySQL数据库Schema设计的性能优化

    第9章 MySQL数据库Schema设计的性能优化 前言: 很多人都认为性能是在通过编写代码(程序代码或者是数据库代码)的过程中优化出来的,其实这是一个非常大的误区.真正影响性能最大的部分是在设计中就 ...

  7. scikit-learn随机森林调参小结

    在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结.本文就从实践的角度对RF做一个总结.重点讲述scikit-learn中RF的调参注 ...

  8. scikit-learn 梯度提升树(GBDT)调参小结

    在梯度提升树(GBDT)原理小结中,我们对GBDT的原理做了总结,本文我们就从scikit-learn里GBDT的类库使用方法作一个总结,主要会关注调参中的一些要点. 1. scikit-learn ...

  9. 我如何调优SQL Server查询

    我是个懒人,我只想干尽可能少的活.当我干活的时候我不想太多.是,你没看错,这看起来很糟糕,作为一个DBA这很不合格.但在今天的文章里,我想给你展示下,当你想对特定查询创建索引设计时,你如何把你的工作和 ...

  10. 在SQL Server 2016里使用查询存储进行性能调优

    作为一个DBA,排除SQL Server问题是我们的职责之一,每个月都有很多人给我们带来各种不能解释却要解决的性能问题. 我就多次听到,以前的SQL Server的性能问题都还好且在正常范围内,但现在 ...

随机推荐

  1. 掌握语义内核(Semantic Kernel):如何精进你的提示词工程

    在人工智能的海洋里,大型语言模型(LLM AI)是高速发展的一艘巨轮,而有效地与其沟通和指导其行为的锚,正是提示语(prompts).提示语是我们提供给模型的输入或查询,以期获取特定的响应.当今,提示 ...

  2. servlet怎么实现第一个程序和实现下载文件

    简单介绍一下servlet是什么:1:Servlet是sun公司提供的一门用于开发动态web资源的技术 2:我们若想用发一个动态web资源,需要完成以下2个步骤: 第一步:1.编写一个Java类,实现 ...

  3. Protobuf 的基本使用

    Protobuf 是 Google 用于序列化数据对象的一种机制,使得数据对象能够在应用程序和服务器之间进行交互,尽管现在 Java 已经对应的序列化的实现方式,但是传统的序列化方式存在严重的缺陷,因 ...

  4. ActiveMQ RCE CVE-2023-46604分析

    一.漏洞触发点 org.apache.activemq.openwire.v12包下BaseDataStreamMarshaller类的createThrowable方法. package org.a ...

  5. 文心一言 VS 讯飞星火 VS chatgpt (23)-- 算法导论4.2 5题

    五.V.Pan 发现一种方法,可以用 132 464 次乘法操作完成 68 x 68 的矩阵相乘,发现另一种方法,可以用 143 640 次乘法操作完成 70 x 70 的矩阵相乘,还发现一种方法,可 ...

  6. Feign传递参数

    传递单个参数 1客户端 @RequestMapping("/one") public BaseResp one(@RequestParam("id") Inte ...

  7. 【华为云技术分享】STM32L476移植华为LiteOS系列教程(二)---开发前准备

    在进行移植华为LiteOS开发工作之前,我们是需要提前做一些准备工作,如:开发工具.环境.源码等相关事宜. 一.准备开发工具 STM32CubeMX用于生成工程文件:STM32CubeMX下载地址 I ...

  8. 跟着字节AB工具DataTester,5步开启一个实验

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群   火山引擎A/B测试平台DataTester孵化于字节跳动业务内部,在字节跳动,"万事皆A/B,一切可 ...

  9. drf-Response drf-request.data 序列化类的使用 反序列化新增、修改、删除数据

    目录 APIView基本使用 使用原生Django写接口(View + JsonResponse) 使用drf写接口(APIView + drf Response) drf 两种导入View的方式 d ...

  10. 洛谷P2678:跳石头(贪心 + 二分)

    题目背景 一年一度的"跳石头"比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间 ...