MatrixOne Logtail 设计解析

Logtail 是 CN(Computation Node)与 TN(Transaction Node)之间的一种日志同步协议,是 CN 和 TN 协同工作的基础。本文将介绍 logtail 协议的基本定位,协议内容和产生过程,也会提及一些遇到的挑战和问题,希望能从宏观层面介绍 logtail,以及它在 MatrixOne 架构中的位置和作用。

早前的 TAE 分析文章(TAE-MatrixOne云原生事务与分析引擎)提到 TN 目前拥有三个职责:

  1. 处理提交的事务;
  2. 为 CN 提供 Logtail 服务;
  3. 转存最新的事务数据至对象存储中,并且推动日志窗口。

其中 1、3 完成时,都会产生状态变化,比如数据成功写入内存,或者成功写入对象存储,而 Logtail 是一种日志同步协议,面向 CN 以低成本的方式同步 TN 的部分状态。CN 通过获取 Logtail,在本地重建出必要的,可读的数据。作为 MatrixOne 存算分离架构的关键协议,Logtail 有以下特点:

  • 串联协同 CN 和 TN,本质是一个日志复制状态机,让 CN 同步 TN 部分状态。
  • Logtail 支持以 pull 和 push 两种模式获取:
  • push 有更强的实时性,不断地从 TN 同步增量日志到 CN;
  • pull 支持指定任意时间区间,同步表的快照,也可以按需同步后续产生的增量日志信息。
  • Logtail 支持按照表级别进行订阅、收集,在多 CN 支持方面更加灵活,更好地实现 CN 负载的均衡。

Part 1 Logtail 协议内容

Logtail 协议的目前主体内容用简单的语言来说,分为两个部分,内存数据和元数据,核心区别在于是否已经转存到对象存储中。

一次事务 commit 产生的更新,在转存至对象存储前,其日志在 logtail 中会以内存数据的形式呈现。任何数据上的修改都可以归结到插入和删除两种形式:对于插入,logtail 信息包含该数据行的 row-id,commit-timestamp 以及表定义中的列;对于删除,logtail 信息则包含 row-id,commit-timestamp 以及主键列。这样的内存数据传递到 CN 后,会在内存中以 Btree 的形式组织,对上层提供查询。

显然内存数据不能一直保留在内存中增加内存压力,通过时间或者容量的限制,内存数据会被 flush 到对象存储上形成一个 object。object 包含一个或者多个 block。block 是表数据的最小存储单位,一个 block 包含的行数不超过固定上限,目前默认是 8192 行。当 flush 完成时,logtail 把 block 元数据传递给 CN,CN 根据事务时间戳,过滤出可见的 block list,读取出 block 中的内容,再综合内存数据,得到某个时刻数据的完整视图。

上面仅仅是最基础的过程,随着一些性能优化的引入,会呈现更多的细节,比如:

1. Checkpoint

当 TN 运行一段时间,在某个时刻做 checkpoint,这个时刻前的全部数据都已经转存到对象存储,因此把这些元数据统一收集并精简,得到一个"压缩包",当一个新启动的 CN 链接到 TN,获取第一次 logtail,如果订阅时间戳大于 checkpoint 的时间戳,就可以把 checkpoint 的元数据(一个字符串)通过 logtail 传递,直接在 CN 读取 checkpoint 时刻之前产生的 block 信息,避免了在网络上从零传递 block 元数据,增加 TN 的 IO 压力。

2. 清理内存

当 TN 产生的 block 元数据给到 CN 时,会按照 block-id 去清理之前送达的内存数据。但是在 TN 侧 flush 事务进行过程中,可能同时发生了数据的更新,比如被 flush 的 block 上新产生了删除。如果此时的策略是回滚重试,那么已经写好的数据就完全无效,在更新密集的负载下,会产生大量的回滚,浪费 TN 资源。为了避免这种情况,TN 会继续 commit,导致这部分 flush 事务开始后产生的内存数据就不能从 CN 中删除,于是在 logtail 的 block 元信息中会传递一个时间戳,在这个时间戳之前,属于这个 block 的内存数据才可以从内存中清理。这些未清除的更新,会在下一次 flush 中的异步地刷盘,并且推送的到 CN 进行删除。

3. 更快读取 

已经转存到对象存储上的 block,可能继续产生删除,读取这些 block 时需要综合内存里的删除数据。为了更快地明确哪些 block 需要结合内存数据,CN 额外维护一个 block 的 Btree 索引,在应用 logtail 的时候就需要更小心地修改这个索引:处理内存数据时增加索引条目,处理 block 元数据时减少索引条目。只能在这个索引中的 block,才有去检查内存数据,在 block 数量比较多的情况下收益比较大。

4. More 

关于 logtail 协议还有更多的改进空间:

  • 后续会向 Logtail 中添加更多的控制信息,让 CN 中的过期数据得到更及时的清理,控制内存使用。
  • 尽管经过 TN 后台 merge,多个 block 可能在一个 object 中,但是目前 CN 中仍然按照 block list 组织数据,之后会让元数据在 object 层面传递,减少 block list 的规模。

Part 2 Logtail 的产生

如前所述,可以通过 pull 和 push 两种方式进行 logtail 获取。这两种模式的特点不同,接下来分别介绍。

1. Pull

如前所述,pull 实际上是同步表的快照,以及后续产生的增量日志信息。

为了达成这个目的,TN 维护了一个按照事务 prepare 时间排序的 txn handle 列表,logtail table,给定任意时刻,通过二分查找得到范围内的 txn handle,再由 txn handle 得到该事务在哪些 block 上做过更新,通过遍历这些 block,就能得到完整的日志。为了加快查找速度,对 txn handle 做了分页,一个页的 bornTs 就是当前页中的 txn handle 的最小 prepare 时间,第一层二分的对象就是这些页。

基于 logtail table,从接收到 pull 请求,主要工作路径如下:

  1. 根据已有的 checkpoints,调整请求的时间范围,更早的可以通过 checkpoint 给出。
  2. 取 logtail table 的一份快照,基于访问者模式用 RespBuilder 去迭代这份快照中相关的 txn handle,收集已提交的日志信息。
  3. 将收集到的日志信息,按照 logtail 协议格式转换,作为响应返回给 CN。

type RespBuilder interface {  
OnDatabase(database *DBEntry) error  
OnPostDatabase(database *DBEntry) error  
OnTable(table *TableEntry) error  
OnPostTable(table *TableEntry) error  
OnPostSegment(segment *SegmentEntry) error  
OnSegment(segment *SegmentEntry) error  
OnBlock(block *BlockEntry) error  
BuildResp() (api.SyncLogTailResp, error)  
Close()
} 

这个过程依然有非常多的优化可以做,这里举几个例子:

  • 如果请求的时间范围不是最新,在请求范围右侧范围内发生了数据刷盘,那么请求范围内的数据更改应该怎么给呢?我们认为再从对象存储中读出这个区间的更改是不必要的,直接把 block 元数据给到 CN,在 CN 利用时间戳过滤去指定范围的数据是更节省的做法。
  • 如果一个时间范围内的内存更改是在太多,通过内存发送也是不实际的,所以会在收集时检查响应大小,如果过大,可以强制刷盘,重新收集。
  • Logtail table 也需要根据 checkpoint 做定时清理,避免内存膨胀。另外也对更早的 txn handle 可以做一些数据上的聚合,避免每次都从 txn handle 层面迭代

2. Push 

Push 的主要目的是更实时地 TN 同步增量日志到 CN。整体流程分为订阅、收集、推送三个阶段。

订阅:一个新 CN 启动后的必要流程,就是作为客户端,和服务端 TN 建立一个 RPC stream,并且订阅 catalog 相关表,当 database、table、column 这些基本信息同步完成后,CN 才能对外提供服务。当 TN 收到订阅一个表的请求时,其实先走一遍 pull 流程,会把 截止到上次 push 时间戳前 的所有 logtail 都包含在订阅响应中。目前对一个 CN,logtail 的订阅、取消订阅、数据发送,都发生在一条 RPC stream 链接上,如果它有任何异常,CN 会进入重连流程,直到恢复。一旦订阅成功,后续的 logtail 就是推送增量日志。

收集:在 TN,一个事务完成 WAL 写入后,触发回调执行,在当前事务中收集 logtail。主要流程是遍历 workspace 中的 TxnEntry(一种事务更新的基本容器,直接参与到 commit pipeline 中),依据其类型,取对应的日志信息转换为 logtail 协议的数据格式。这个收集过程通过 pipeline,和 WAL 的 fysnc 并发执行,减少阻塞。

推送:推送阶段主要做一次过滤,如果发现某个 CN 没有订阅该表,就跳过该 CN,避免推送。

按事务收集有一个比较明显的问题,如果一个表长时间没有更新怎么办?CN 怎么知道是没有更新,还是没有收到呢?这里就加入了心跳机制,默认是 2 ms,TN 的 commit 队列中会放入一个 heartbeat 的空事务,不做任何实质性工作,只消耗时间戳,从而触发一次心跳 logtail 发送,告知 CN 此前的所有表数据已经发送过更新,推动 CN 侧的时间戳水位更新。

Part 3 总结

至此只是从总体上介绍了 logtail,篇幅有限,挂一漏万,并不能展示 logtail 的全部细节。而恰好 logtail 是对细节要求非常高的模块,充分考验了协议在两个系统中的适用性。如果对细节的把控不足,则会导致数据的漏读、重复读,再加上时间戳的这个变量,经常引发偶现的错误。今后我们会继续迭代 logtail,提升其稳定性,规范流程,力求更加透明可理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/108242.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何选择最适合你的LLM优化方法:全面微调、PEFT、提示工程和RAG对比分析

一、前言 自从ChatGPT问世以来,全球各地的企业都迫切希望利用大型语言模型(LLMs)来提升他们的产品和运营。虽然LLMs具有巨大的潜力,但存在一个问题:即使是最强大的预训练LLM也可能无法直接满足你的特定需求。其原因如…

微信小程序获取手机号(2023年10月 python版)[无需订阅]

技术栈: 1. 微信开发者工具中的调试基础库版本:3.1.2。 2. 后台:django。 步骤: 1. 首先在后台django项目的定时任务中增加一个下载access_token函数,并把得到的access_token保存在数据库中(其实随便哪里…

INTELlij IDEA编辑VUE项目

菜单中选择setting–>Plugins 或者快捷键 ctrlalts 搜索vue,但有些情况会搜索不出来,先说搜索到的情况 如下图所示: 如果没有vue.js则说明过去已经安装了。 搜索到了后点击Install安装即可, 但即使搜索成功了,也不…

功夫猫小游戏

欢迎来到程序小院 功夫猫 玩法&#xff1a; 对准对方猫点击鼠标左键进行扑街&#xff0c;碰到敌方猫扑街X1&#xff0c;不要让对方猫碰到自己&#xff0c;统计扑街次数&#xff0c;快去玩功夫猫吧^^。开始游戏https://www.ormcc.com/play/gameStart/189 html <canvas id&q…

非技术背景项目经理如何发展?

非技术背景的项目经理在现代企业中扮演着重要的角色&#xff0c;他们负责协调和管理项目的各个方面&#xff0c;确保项目按时、按预算和按质量要求完成。对于没有技术背景的项目经理来说&#xff0c;他们需要通过一些特定的方法和策略来发展自己的职业生涯。 首先&#xff0c;…

Mac下通过nvm管理node

背景 本地有两个项目&#xff0c;老项目需要用到node 14&#xff0c;新项目需要用node 16&#xff0c;所以只能通过nvm来管理node了 卸载原始的node 我的node是通过官网的.pkg文件安装的&#xff0c;可以通过以下命令进行删除 sudo rm -rf /usr/local/{bin/{node,npm},lib/…

Python数据挖掘入门进阶与实用案例:自动售货机销售数据分析与应用

文章目录 写在前面01 案例背景02 分析目标03 分析过程04 数据预处理1. 清洗数据2.属性选择3.属性规约 05 销售数据可视化分析1.销售额和自动售货机数量的关系2.订单数量和自动售货机数量的关系3.畅销和滞销商品4.自动售货机的销售情况5.订单支付方式占比6.各消费时段的订单用户…

day06-前后端项目上传到gitee、后端多方式登录接口、发送短信功能、发送短信封装、短信验证码接口、短信登录接口

1 前后端项目上传到gitee 2 后端多方式登录接口 2.1 序列化类 2.2 视图类 2.3 路由 3 发送短信功能 4 发送短信封装 4.0 目录结构 4.1 settings.py 4.2 sms.py 5 短信验证码接口 6 短信登录接口 6.1 视图类 6.2 序列化类 1 前后端项目上传到gitee # 我们看到好多开源项目…

编辑器功能:用一个快捷键来【锁定】或【解开】Inspector面板

一、需求 我有一个脚本&#xff0c;上面暴露了许多参数&#xff0c;我要在场景中拖物体给它进行配置。 如果不锁定Inspector面板的话&#xff0c;每次点击物体后&#xff0c;Inspector的内容就是刚点击的物体的内容&#xff0c;而不是挂载脚本的参数面板。 二、 解决 &…

Vue项目使用svg之svg-sprite-loader详细使用

项目中为了体验好、性能优、资源丰富等原因经常会用svg这种矢量图&#xff0c;但是svg不能直接像image标签一样直接使用&#xff0c;这就需要前端的同学自己处理了。 svg有以下优点&#xff1a; svg放大不失真,png&#xff0c;jpg会出现失真现象svg的体积非常小&#xff0c;对…

探索数字安全的卓越之选 - Digicert证书

在数字时代&#xff0c;数据安全和隐私保护变得尤为重要。无论是个人网站、电子商务平台还是大型企业&#xff0c;保护用户数据和建立信任都是至关重要的任务。在这个领域&#xff0c;Digicert是一个备受推崇的品牌&#xff0c;提供了卓越的数字证书解决方案&#xff0c;以确保…

跨境商城源码部署(多商户入驻,一键铺货,快速部署)

现如今&#xff0c;互联网的快速发展为商业带来了前所未有的机遇&#xff0c;跨境电商作为其中的热门领域&#xff0c;吸引了众多企业和创业者的关注。而通过部署跨境商城源码&#xff0c;您将获得多商户入驻、一键铺货等功能&#xff0c;轻松拥有一家生意蓬勃发展的跨境商城。…

Gson反序列化原理

前言 序列化和反序列化是日常工作中经常使用的工具&#xff0c;一般用于对象的持久化保存或者对象的网络传输&#xff0c;一般有两种情况&#xff0c;一种是对象本身实现了Serializable接口&#xff0c;这种情况下可以利用jdk自带的功能或者Kryo等这种封装好的序列化反序列化工…

CSS悬停卡片翻转明信片效果源码附注释

运行效果演示: HTML页面代码: <!DOCTYPE html> <html lang="en" > <head>

同为科技(TOWE)关于风力发电雷电防护的解决方案

风能作为一种可再生清洁能源&#xff0c;是国家新能源发展战略的重要组成部分。我国风能开发潜力高达2.510GW以上&#xff0c;近年来风力发电机组逐年增加&#xff0c;截止到2022年&#xff0c;全国风电装机容量约3.5亿千瓦&#xff0c;同比增长16.6%。然而&#xff0c;由于风力…

ros_rtsp订阅Image类型topic转换为rtsp视频流

文章目录 一、安装环境二、在catkin工作空间中构建三、设置流四、推出视频流五、验证视频流1、安装vlc拉流2、安装gstreamer拉流3、安装FFmpeg拉流 一、安装环境 ROS gstreamer development libs&#xff0c;包括base、good、bad和rtspserver: sudo apt-get install libgstre…

智能垃圾桶丨悦享便捷生活

垃圾桶是人们日常生活所必不可少的必需品&#xff0c;它让生活中所产生的垃圾有了一个正确的存放地方。随着生产技术的迅速发展&#xff0c;垃圾桶也得以更新换代。由最初的简单式的圆筒式垃圾桶&#xff0c;到现在出现的感应式垃圾桶、智能语音控制垃圾桶&#xff0c;垃圾桶也…

2023年中国自动驾驶卡车市场发展趋势分析:自动驾驶渗透率快速增长[图]

自动驾驶卡车的技术原理是通过电脑算法控制车辆行驶&#xff0c;辅助驾驶员完成任务。其实现方式主要是基于传感器和计算处理技术。自动驾驶卡车可以随时感知周围环境&#xff0c;灵活避障&#xff0c;自适应调整行驶路径&#xff0c;相比之下传统卡车需要驾驶员进行手动操作&a…

Switch模拟器-Ryujinx(龙神模拟器)安装教程

Ryujinx是由gdkchan带领团队运用C#语言创建并发布在GitHub平台的Switch开源模拟器. 系 统 要 求 内存8 GB RAM及以上 显卡支持Vulkan、OpenGL版本4.5及以上 64位系统 Windows 10 RS4&#xff08;Redstone 4&#xff0c;版本 1803&#xff09;或更高版本 软 件 教 程 第一…