PD的时钟服务——TSO

2023-10-06 23:30
文章标签 时钟 服务 pd tso

本文主要是介绍PD的时钟服务——TSO,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者:tsthght

原文来源: https://tidb.net/blog/51d5f201

时钟对数据库系统尤为重要,目前分布式数据库已经是主流方向,但是在分布式环境中获取一致性的时钟非常困难。

由于存在时钟偏移(clock skew),分布式中各个节点的时钟无法完美同步。人们尝试了各种方法来使得分布式系统各个节点保证时钟同步。比较知名的有Lamport提出的逻辑时钟,混合逻辑时钟 和 TrueTime。

接下来介绍下TiDB中的时钟服务。首先回顾下TiDB集群整体架构:

其中,Placement Driver (简称 PD) 是整个集群的管理模块,其主要工作有三个:一是存储集群的元信息(某个 Key 存储在哪个 TiKV 节点);二是对 TiKV 集群进行调度和负载均衡(如数据的迁移、Raft group leader 的迁移等);三是提供时间服务。

TiDB的时间服务是由PD提供的,使用的是中心授时服务。

PD集群是由多个(通常3个)PD实例构成的,其中的Leader实例对外提供服务。PD内置的etcd服务,用来实现PD的高可用和元数据存储。当PD的Leader实例出现故障,通过选举产生新的Leader,从而保证了授时等服务的高可用。其中etcd的Leader节点通常与PD的Leader节点是同一个PD实例,因此选举新Leader的时候,会先选举etcd的Leader再选举PD的Leader,其流程大致如下:

pd-leader

PD的TSO使用的是中心式的混合逻辑时钟。其使用64位表示一个时间,其中低18位代表逻辑时钟部分,剩余部分代表物理时钟部分,其结构如下图所示。由于其逻辑部分为18位,因此理论上每秒可以分配时间戳为 218 * 1000 = 262144000个,即每秒可以产生2.6亿个时间戳。

pd-time

接下来,我们将详细介绍PD中的TSO的算法实现。我们将TSO分成三部分进行讲解:校时,授时,推进。

校时

当新的Leader节点被选出时,其并不知道当前系统的时间已经推进到了哪里,因此首选需要对Leader的时间进行校对。

首先新Leader节点会读取上一个Leader保存到etcd中的时间,这个保存到etcd的时间是上一个Leader申请的物理时间的最大值tlast。通过读取该时间,便可以知道上一个Leader分配的时间戳是小于Tlast的。

获得Tlast后,会将本地物理时间Tnow与Tlast进行比较,如果Tnow - Tlast < 1ms,那么当前的物理时间 Tnext = Tlast + 1,否则 Tnext= Tnow。至此,校时完成。

授时

校时完成后,便可以对外提供TSO服务了。为了保证当前Leader 节点宕机之后,新Leader能够校时成功,需要在每次授时之后,都要对tlast进行持久化,保存到etcd中。如果每次授时之后,都会持久化,性能会大大降低。因此PD目前采取的策略是预申请一个可分配的时间窗口Tx,默认Tx = 3s。

因此在授时开始之前,PD的Leader首先将Tlast = Tnext + Tx存储到etcd中,存储成功之后,PD的Leader便可以在内存中直接分配 [Tnext , Tnext + Tx)之内的所有时间戳。预分配解决了频繁操作etcd带来的性能问题,但是如果Leader crash,就会浪费一些时间戳。

当客户端请求PD的TSO服务时,返回给客户端的是64位表示的混合逻辑时间戳。其中的物理时钟部分便是校时之后的tlast,而逻辑时钟部分便随着请求原子递增。如果逻辑时钟部分超过了最大逻辑时钟的值(1 << 18),则会睡眠50ms来等待时间被推进,物理时间被推进后,如果有时间戳可以被分配,则会继续分配时间戳。

由于TSO请求是跨网络的,所以减少网络开销,PD的TSO服务支持批量请求时间戳。客户端可以一次申请N个时间戳,减少网络开销。

推进

授时阶段,只能通过逻辑时钟部分自增来分配时间戳,当逻辑时钟部分到达上限后,则无法继续分配,则需要对物理时间进行推进。

PD会每50ms检测当前的时钟,进行时钟推进。首先计算jetLag = Tnow - Tlast,如果jetLag > 1ms,则说明混合逻辑时钟的物理时钟部分落后于物理时钟,则需要更新混合逻辑时钟的物理时钟部分:Tnext = Tnow。与此同时,为了防止授时阶段由于逻辑时钟达到阈值导致的等待,在推进阶段,当发现当前的逻辑时钟 已经大于逻辑时钟的最大值的一半时,也会增加混合逻辑时钟的物理时钟部分。一旦混合逻辑时钟的物理时钟部分增长,则逻辑时钟部分会被重置为0。

当Tlast - Tnext <= 1ms时,说明上次申请的时间窗口已经用完了,需要申请下一个时间窗口。此时,同样将Tlast = Tnext + Tx存储到etcd中,然后继续在新的时间窗口内进行时间分配。

PD采用了中心式的时钟解决方案,本质上还是混合逻辑时钟。但是由于其是单点授时,所以是全序的。中心式的解决方案实现简单,但是跨区域的性能损耗大,因此实际部署时,会将PD集群部署在同一个区域,避免跨区域的性能损耗;PD通过引入etcd解决了单点问题,一旦Leader节点故障,会立刻选举新的Leader继续提供服务;而由于TSO服务只通过PD的Leader提供,所以可能会出现性能瓶颈,但是理论上PD每秒可以产生2.6亿个时间戳,并且经过了很多优化,从目前使用情况看,TSO并没有出现性能瓶颈。

这篇关于PD的时钟服务——TSO的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/154585

相关文章

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

基于SpringBoot的宠物服务系统+uniapp小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统+原生微信小程序+LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统+LW参考示例 3.基于SpringBoot+Vue的企业人事管理系统+LW参考示例 4.基于SSM的高校实验室管理系统+LW参考示例 5.基于SpringBoot的二手数码回收系统+原生微信小程序+LW参考示例 6.基于SSM的民宿预订管理系统+LW参考示例 7.基于

Golang支持平滑升级的HTTP服务

前段时间用Golang在做一个HTTP的接口,因编译型语言的特性,修改了代码需要重新编译可执行文件,关闭正在运行的老程序,并启动新程序。对于访问量较大的面向用户的产品,关闭、重启的过程中势必会出现无法访问的情况,从而影响用户体验。 使用Golang的系统包开发HTTP服务,是无法支持平滑升级(优雅重启)的,本文将探讨如何解决该问题。 一、平滑升级(优雅重启)的一般思路 一般情况下,要实现平滑

Golang服务平滑重启

与重载配置相同的是我们也需要通过信号来通知server重启,但关键在于平滑重启,如果只是简单的重启,只需要kill掉,然后再拉起即可。平滑重启意味着server升级的时候可以不用停止业务。 我们先来看下Github上有没有相应的库解决这个问题,然后找到了如下三个库: facebookgo/grace - Graceful restart & zero downtime deploy for G

Java后端微服务架构下的API限流策略:Guava RateLimiter

Java后端微服务架构下的API限流策略:Guava RateLimiter 大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! 在微服务架构中,API限流是保护服务不受过度使用和拒绝服务攻击的重要手段。Guava RateLimiter是Google开源的Java库中的一个组件,提供了简单易用的限流功能。 API限流概述 API限流通过控制请求的速率来防止