专栏首页SEian.G学习记录聊聊TiDB的那些事?

聊聊TiDB的那些事?

TiDB这个词,相信大家或多或少都曾经耳闻过,但是很多人觉得他是分布式数据库,自己的业务是使用mysql,基本使用不上这个技术,可能不会去了解他或不会去深入了解。最近一个月,基于实际业务的应用场景,从测试环境测试基础学习,到生产环境性能压测、高可用测试、故障测试等的学习,到今天TiDB终于完成了线上业务的承接使命,而这一切只是开始,而非终点;

经过这一个月的学习,发现TiDB这些原理其实不仅仅局限于分布式数据库这一块,很多技术都是通用的,所以在这里写一下分享一下学习TiDB的一些心得。当然还有更深层次的东西需要后续慢慢的打磨;

先说说为什么选择TiDB吧,一般来说在咱们的业务中都是使用的mysql,但是单机数据库容量和并发性能都有限,对于一些大容量或者高并发的场景我们会选择mycat去做,使用mycat的确解决了问题但是增加了开发难度,开发需要对每一个表都设置分表key,并且每个查询都得带入这个key的值,这样就增加了查询限制,如果不带key的值就得所有库表都得查询一次才行,效率极低,而且也无法满足AP的业务场景。随着核心业务的逐步从SQL Server迁移到MySQL,怎么解决这个问题呢?经过对开源数据库对比测试,最终选择了TiDB;

经过一个月左右的对TiDB的学习,总体感觉,学习成本其实相对来说还是蛮高的,但是不得不说的是,TiDB的官方文档及社区非常的棒,TiDB文档是我见过做得算是比较顶级的文档了,可以说不叫做文档,其实是一个文章知识库,对新手学习来说,还是比较方便的;

在TiDB学习前,对TiDB总是会有很多的疑问:

TiDB如何保证无限扩展?因为平时使用的大多都是mycat的技术,这种其实无限扩展是比较麻烦的 如何保证id唯一,分布式数据库往往会进行分片,在单机数据库中的自增id就不成立,TiDB是如何保证的呢? TiDB是如何保证事务的呢? TiDB数据库是如何存储的?为什么即适用于TP场景又适用于AP场景?

带着这些问题,先来看看TiDB的架构,下面是官方的给出的架构图:

TiDB其实是典型的计算分离的架构

TiDB Server:计算层,对外暴露协议的连接端口,负责管理客户端的连接,主要做的就是执行SQL解析以及优化,生成分布式执行计划,由于这里是计算层是没有状态的,所以是可以无限扩展。 PD Server:PD是整个集群的大脑,负责存储每个 TiKV 节点实时的数据分布情况和集群的整体拓扑结构,提供 TiDB Dashboard 管控界面,需要保持高可用。 TiKV: k-v存储引擎,在tikv内部,存储数据的基本单位是Region。 Tiflash:这个是用于列式的存储引擎,类似于Clickhouse

我们首先来看TiDB如何做到扩展?

首先我们来看看计算层: tidb-server,刚才说过在计算层中,是无状态的,所以就可以进行无限扩展,如果你的场景并发度很高或者数据库连接很多,可以考虑多扩展tidb-server。

然后我们来看看存储层,作为保存数据的系统,首先要决定的是数据的存储模型,也就是数据以什么样的形式保存下来。TiKV 的选择是 Key-Value 模型,并且提供有序遍历方法。在每个tikv上会划分出多个Region,这个也就是我们的基本存储单位;

任何持久化的存储引擎,数据终归要保存在磁盘上,TiKV 也不例外。但是 TiKV 没有选择直接向磁盘上写数据,而是把数据保存在 RocksDB 中,具体的数据落地由 RocksDB 负责。这个选择的原因是开发一个单机存储引擎工作量很大,特别是要做一个高性能的单机引擎,需要做各种细致的优化,而 RocksDB 是由 Facebook 开源的一个非常优秀的单机 KV 存储引擎,可以满足 TiKV 对单机引擎的各种要求。这里可以简单的认为 RocksDB 是一个单机的持久化 Key-Value Map。

TiKV 利用 Raft 来做数据复制,每个数据变更都会落地为一条 Raft 日志,通过 Raft 的日志复制功能,将数据安全可靠地同步到复制组的每一个节点中。不过在实际写入中,根据 Raft 的协议,只需要同步复制到多数节点,即可安全地认为数据写入成功。

总结一下,通过单机的 RocksDB,TiKV 可以将数据快速地存储在磁盘上;通过 Raft,将数据复制到多台机器上,以防单机失效。数据的写入是通过 Raft 这一层的接口写入,而不是直接写 RocksDB。通过实现 Raft,TiKV 变成了一个分布式的 Key-Value 存储,少数几台机器宕机也能通过原生的 Raft 协议自动把副本补全,可以做到对业务无感知。

所以对于TiDB来说无论是存储层还是计算层,我们都可以无限扩展。

那么TiDB是如何保证id唯一的呢?

在mysql中我们可以对于主键直接设置 AUTO_INCREMENT来达到自增列的效果,mysql是怎么做到自增的呢?

在MySQL5.7及之前的版本:InnoDB引擎的自增值,自增值保存在内存里,并没有持久化。每次重启后,第一次打开表的时候,都会去找自增值的最大值max(id),然后将max(id)+步长作为这个表当前的自增值。 在MySQL8.0版本:将自增值的变更记录在了redo log中,重启的时候依靠redo log恢复重启之前的值。

在TiDB中同样支持 AUTO_INCREMENT,不能保证严格递增,只能保证趋势递增,具体原理是:,对于每一个自增列,都使用一个全局可见的键值对用于记录当前已分配的最大 ID。由于分布式环境下的节点通信存在一定开销,为了避免写请求放大的问题,每个 TiDB 节点在分配 ID 时,都申请一段 ID 作为缓存,用完之后再去取下一段,而不是每次分配都向存储节点申请。

TiDB还支持 AUTO_RANDOM,可以用于解决大批量写数据入 TiDB 时因含有整型自增主键列的表而产生的热点问题。因为region是有序的如果一段时间大量有序的数据产生有可能会在同一个region上,所以我们可以使用AUTO_RANDOM来将我们的主键数据打散。

好了,今天就先聊这些吧,后面会陆续分享一些TiDB相关管理的内容,包括从TiDB生产集群部署到性能压测、高可用、日常运维等常见问题;

本文分享自微信公众号 - DBA的辛酸事儿(dbabitter),作者:SEian.G

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-07-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊Deno的那些事

    ? 这是第 99 篇不掺水的原创,想要了解更多,请戳上方蓝色字体:政采云前端团队 关注我们吧~

    政采云前端团队
  • 聊聊Activity那些事

    Activity身为四大组件之一,在整个App中扮演着向用户呈现界面的角色。在平常的开发中,我们会自定义一个类去继承Activity去实现界面。而Activit...

    猴哥yuri
  • 聊聊ThreadLocal那些事

    这篇文章聊聊 ThreadLocal,我们经常会在一些开源中间件的源码中见到它的身影,比较常见的用途是保存上下文信息,还有就是保证了线程安全。

    pjmike
  • 聊聊登录那些事

    原来分享过一篇文章,Java自定义注解及应用,当时为了能突出重点,直接在url中传了用户的所属角色,并写了一般的做法。加上最近看了一些人的简历,发现神奇的相似,...

    Java识堂
  • 聊聊云原生的那些事

    大家好,今天和大家聊聊云原生,相信这个词大家应该或多或少都听过, 那么什么是云原生计算呢?云原生技术得技术栈有哪些呢?

    机械视角
  • 聊聊AWK命令的那些事

    对于下面的nginx日志access.log,用脚本分析出访问ip的Top 10。 其实这个题不难,但是考察了几个常用的shell 命令,awk、uniq、so...

    大数据技术与应用实战
  • 聊聊API接口那些事

    Android开发:我们当初协商的时候data是个map,你现在给我返回一个list

    大话swift
  • 聊聊Java运算符的那些事

    大家好呀,昨天我们说了Java的数据类型,类型和其它语言都相差不大,为什么这么说呢,我们得记住Python还有个复数类型哦。

    小Bob来啦
  • 聊聊小程序开发那些坑那些事

    我个人是后端开发,或许很多人看到小程序开发比较诧异,这里解释一下,最近有要开发小程序的东西,于是自己学习了一下,将学习经验分享出来,ok,我们进入今天正题,自己...

    公众号guangcity
  • 聊聊 5.7 error log 那些事儿

    MySQL的错误日志(error log)用来记录mysqld启动和关闭过程的信息,启停slave以及死锁日志,bug,core dump 等信息。 在调研 M...

    用户1278550
  • 聊聊测试“左移”那些事

    在目前互联网产品迭代过程中,可能会出现上一个版本的需求被推倒重来,甚至整个已经实现的需求砍掉等情况,这些现象站在敏捷研发角度可能是正常且难以避免的,因为研发团队...

    腾讯移动品质中心TMQ
  • 聊聊 MySql 索引那些事儿

    上一篇文章《一条SQL语句在MySQL中是如何执行的》我们聊到了sql语句内部的执行,包括InnoDB引擎是如何支持事务的,如何做到可以备份恢复的,那么今天我们...

    Java团长
  • 聊聊有关SVG那些事儿

    前几天,老伙计推送微信的一篇文章,文章标题为:【Android微信上的SVG】,正好LZ借此机会学习了解下有关SVG的相关内容。

    HLQ_Struggle
  • 聊聊 MySql 索引那些事儿

    今天我们来聊一聊MySql索引的那些事,在这篇文章中,我会主要聊聊InnoDB下索引的数据结构,索引如何起作用的,如何更好的利用索引提高效率。

    java思维导图
  • 聊聊JDK泛型那些事儿

    在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是...

    孟君
  • 聊聊调试的那些事,超实用!!!

    今天给大家分享的是开发中调试的那些事,在开发中我们最害怕也是最常见的就是出现bug,然后去修改bug,那么怎么去快速定位bug的位置和原因呢?这个时候调试显得尤...

    小丑同学
  • 聊聊Java数据类型的那些事

    前面一篇文章说了Java的变量,我们通过定义变量得到一个名字,然后将某个数据存储在这个变量中,简单来说,这也是变量所承担的任务。

    小Bob来啦
  • 聊聊引用和 ThreadLocal 那些事儿

    某一天,技术交流群里面的某个群友突然提出了一个问题:"ThreadLocal 的 key 是弱引用,那么在 threadLocal.get() 的时候,发生 G...

    kirito-moe
  • 聊聊TCP连接耗时的那些事儿

    在互联网后端日常开发接口的时候中,不管你使用的是C、Java、PHP还是Golang,都避免不了需要调用mysql、redis等组件来获取数据,可能还需要执行一...

    Bug开发工程师

扫码关注云+社区

领取腾讯云代金券