我们又重写了一个关键服务

news2024/11/24 22:43:52

#01

QueryCoord 组件介绍

QueryCoord 是 Milvus 中查询集群的中心调度节点,在用户将一个 Collection Load 到内存中时,QueryCoord 负责将该 Collection 的 Segment 调度到 QueryNode 集群中,以支持后续的查询。

QueryCoord 最核心的操作有4种:

  • Load:将资源加载到 QueryNode 中

  • Release:将资源从 QueryNode 释放

  • Handoff:使用新的 Segment C 替换旧的 Segment A,B

  • Balance:在 QueryNodes 之间移动 Segment

此外,在 Milvus v2.1.0 我们加入了内存多副本的功能,通过增加 Segment 在内存中的副本数量来提升性能,提高可用性。

#02

为什么必须重构

在 Milvus v2.1.x 中,我们遇到了很多与 QueryCoord 相关的问题,其中不少问题无法在现有的设计上彻底解决,也有不少问题由于此前的设计耦合,在修复时很容易引入其它问题。 此前,有两类问题是最为常见,也最为棘手的:

  1. QueryCoord 在某个操作之后长时间无响应

  2. QueryCoord 有时无法通过重启恢复服务

我们在 Milvus v2.1.x 的开发过程中花费了大量的时间去解决无响应相关的问题。这个问题并不只是代码的问题,从根本来说是 QueryCoord 试图提供的接口语义过于强大,以至于根本无法简单实现我们期望的语义。

根本原因

此前的 QueryCoord,试图为每一个接口都提供最终完成的语义,只要请求到达 QueryCoord,即使后续出现错误,QueryCoord 也会试图最终将这些请求完成。

此外,QueryCoord 会记录每个 Segment 所处的节点位置,并将这一信息持久化。当发生 Balance 之类的操作时,根据 RPC 是否成功来决定是否要修改记录的位置信息。

我们很快意识到这一做法是无法做到准确的,因为 RPC 会有 false failure,QueryCoord 主动跟踪资源位置,并以 RPC 结果作为资源位置变化的依据,是必定会发生资源泄漏的。

为了达成这种最终完成的语义,QueryCoord 选择实现了一个完全串行的 scheduler,将每一种请求视作一类 task,可以认为这个 task scheduler 就是一个 WAL applier,而请求就是 WAL 中的 record,QueryCoord 会将所有 task 持久化,并在重启时重放这些 task。

这一套机制像由若干小齿轮连接起来的精密器件,容错率是很低的:

  • 由于完全串行执行,当某一个请求无法执行,或执行慢时,后续的所有请求都会被阻塞

  • 由于持久化了所有的 task,一个无法完成的请求会持续阻塞整个系统,即使重启也无法恢复

  • 一个有副作用的请求失败时(如 Load),无法保证接口的原子性

以 Load 请求为例,如果在 Load 了部分 Segment 后,请求无法继续执行。

在这一套机制下就无法做出正确的处理。如果多次重试,则会让后续请求的阻塞更长时间;如果直接丢弃请求,则可能无法释放已经 Load 成功的 Segment。

#03

重构思路

QueryCoord 的本质是一个资源调度中心,我们需要把 Segment 和 Channel 调度到 QueryNode 集群中来支持查询。

同时也要很好的支持内存多副本,在副本数量与预设值不同时能进行相应的上下线操作。新的 QueryCoord 设计参考了 Placement Driver[1] 等业内成熟系统,我们有一些基本的出发点:

  • QueryCoord 必须感知真实的资源分布情况

  • 资源上下线操作是否完成不能以 RPC 是否成功作为判断条件

  • 启动时依赖的持久化信息需要尽量少

  • 需要一个组件不断根据分布对资源进行上下线调整

从这些点出发,重构后的 QueryCoord 作出了下面的调整:

心跳机制

依赖 RPC 的成功与否去判断资源的上下线是否成功是不可行的,RPC 存在 false failure,因此可能会导致资源泄露。

集群中资源的分布情况,最真实的来源就是节点本身报告自己持有哪些资源,因此必须加入一套心跳机制,在 QueryCoord 与 QueryNode 之间同步资源分布情况。

在加入心跳机制后,QueryCoord 不再去持久化资源的分布信息,而是在启动时询问所有的 QueryNode 来恢复出分布信息,这样可以避免脏数据对重启带来影响。

同时,依赖心跳汇报的资源分布信息来判断资源的上下线是否完成,是最准确的,在 Balance 这个操作中,我们需要对一个 Segment 进行先上后下,以保证 Balance 过程中不会影响服务的可用性,通过心跳机制,我们可以准确地判断上线操作是否真的已经完成,来决定是否进行下线操作。

抛弃最终完成语义

从系统自身的角度来看,最终完成语义是很难保证的,这一性质要求持久化所有请求,并在重启后进行重放。一些请求并不能保证总是可执行的,例如一个加载 Segment 的请求,可能在重启后这个 Segment 已经被 Compact,从而无法加载。

从用户的角度来看,当服务不可用时,用户通常期望可以通过重启去清理掉一些脏数据,让服务能够重新工作。抛弃最终完成的语义之后,QueryCoord 只对接口提供原子性保证,不再持久化请求,避免恢复时被一些无法完成的请求阻塞。

在做出上面的修改后,我们也不再需要一个全局串行的 scheduler,而是将请求的并发粒度降低到了 Collection 级别,并且需要进入 scheduler 的请求只有 Load/Release 两类。可以极大提高 QueryCoord 的响应速度。

资源分布检查

在一个分布式的环境中,任何网络请求都有失败的可能。一个对一批资源进行处理的请求甚至可能是部分成功的,我们希望系统具有更高的容错率,在任何情况下都有能够将资源副本数量调整到预设值的能力。

因此在新的 QueryCoord 中,我们加入了若干的资源检查器(Checker):

  • Balance Checker:检查集群的负载情况,并作出适当的资源调整,平衡集群负载

  • Channel Checker:检查集群中各个 Channel 的分布情况,保证 Channel 的副本数量不多不少

  • Segment Checker:检查集群中各个 Segment 的分布情况,保证 Segment 的副本数量不多不少

在 Release 的情况下,检查器能够保证即使在 Release 实现存在 Bug 的情况下,也可以把泄露的资源释放掉。

#04

资源调度系统的设计感悟

得益于 Milvus 的架构设计,在这次重构中我们几乎重写了整个 QueryCoord,但依然能够无缝的替换掉原来的 QueryCoord。在新的 QueryCoord 上线后,Milvus 系统:

  • Query 集群更加健壮,稳定

  • 彻底解决 Load/Release 等请求无响应的问题

  • 保证了 Query 相关服务在重启后能够恢复

  • QueryCoord 更加容易维护,排查问题更加容易

而我个人也从这次重构中收获良多,在资源调度系统的设计上,与代码实现上获得了许多感悟:

  • 分布信息作为调度的输入,必须是真实的,也就是各节点上报的信息汇总

  • 简单,清晰的语义比看上去强大的复杂语义更强大, 简单粗暴往往意味着高容错

  • 原子性是一个非常有力的性质,系统在各类操作有了原子性保证后会更容易维护,在并发的情况下,为了保证原子性有时需要很小心

在 QueryCoord 的后续演进中,我们会继续强化 QueryCoord 的可用性与 Query 集群的性能。

参考资料

[1]

Placement Driver: https://docs.pingcap.com/tidb/stable/tidb-architecture#placement-driver-pd-server

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

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

相关文章

将egg项目部署至服务器

文章目录1.下载linux版本的node-v162.将node安装包从自己电脑上上传到自己的服务器3.在服务器中解压压缩包4.配置环境变量5.使文件生效6.将egg项目传到服务器指定目录下7.下载依赖8.npm start 运行不会占用终端 并且一直在运行 可以使用npm stop停用9.最后使用云服务器ip:端口号…

Linux22 --- 网络为什么要分层、使用tcp协议实现两个进程间通信的功能、IP地址转换函数

一、网络为什么要分层 1 1、分层的优点 1)各层之间是独立的。某一层并不需要知道它的下一层是如何实现的,而仅仅需要知道该层通过层间的接口(即界面)所提供的服务。由于每一层只实现一种相对独立的功能,因而可将一个…

Linux-Hadoop集群配置

文章目录一、配置Hadoop集群1、在master虚拟机上配置hadoop(1)编辑Hadoop环境配置文件 - hadoop-env.sh(2)编辑Hadoop核心配置文件 - core-site.xml(3)编辑HDFS配置文件 - hdfs-site.xml(4&…

1542_AURIX_TC275_CPU子系统_内核

全部学习汇总: GreyZhang/g_TC275: happy hacking for TC275! (github.com) 我因为看了这个章节的开篇有些疑惑去看了内核手册,现在学习的进程终于又重新回归,回到了TC275这个MCU的学习上。 这里的几条笔记记录是隔了很久写的,前面…

【Java面试】HashMap死循环问题

问题 最近几道面试题被问了是否了解并发情况下JDK7中HashMap发生死循环,导致CPU占用100%的问题。 由于HashMap并非是线程安全的,所以在高并发的情况下必然会出现问题,这是一个普遍的问题。 如果是在单线程下使用HashMap,自然是没…

[MAUI] 开篇-初识MAUI

前言 在2020年5月, 微软宣布了MAUI跨平台框架, MAUI 是Xamarin.Forms演变而来, 这也就意味着, 如果你原来具备Xamarin.Forms开发经验, 你可以流畅的过渡到MAUI开发当中。 原本于2021年底发布的MAUI正式版被推迟到了2022年5月底发布。现在, 你目前可以通过安装VS2022 预览版进行…

Elasticsearch倒排索引

什么是正排索引? 如下图,有一张商品表(tb_goods): 对于mysql数据库来说,肯定会给“id”创建主键索引,然后根据“id”来查询对应的商品信息,而这种情况就被称为“正排索引” 现在有…

eMagin:当月产百万片时,4K MicroOLED成本将不是问题

在今年2022 SID显示周期间,Micro OLED微显示模组厂商eMagin曾展示一款专为超短焦VR头显开发的4K Micro OLED微显示屏,有趣的是,该显示屏连接的主板上印有STEAMBOAT字样,让人不禁怀疑它与Valve之间是否存在某种联系。甚至有猜测认为…

【Linux】8.0 多线程

文章目录1.0 Linux线程概念1.1 Linux线程基本概念1.2 Linux线程优劣介绍2.0 Linux线程控制2.1 pthread_create(创建线程)2.2 pthread_join(线程等待)2.3 pthread_exit(线程终止)2.4 pthread_detach(线程分离)3.0 线程id和LWP的关系4.0 Linux线程互斥4.1 线程互斥相关概念4.2 线…

JUC系列(五) 读写锁与阻塞队列

📣 📣 📣 📢📢📢 ☀️☀️你好啊!小伙伴,我是小冷。是一个兴趣驱动自学练习两年半的的Java工程师。 📒 一位十分喜欢将知识分享出来的Java博主⭐️⭐️⭐️,擅…

Qt第二十六章:Nuitka打包教程

Nuitka环境安装 ①下载gcc文件。提取码:8888百度网盘 请输入提取码 ②解压nuitka1.0.6版本,我们解压64位的。 ③设置环境变量 ④检测一下 gcc.exe --version 安装nuitka pip install nuitka pip install ordered-set 防止环境变量不生效,…

【Redis】Redis介绍

文章目录1.NoSQL数据库1.1NoSQL适用场景1.2常用的NoSQL1.3Redis介绍1.4Redis的使用场景1.5Redis默认按照目录1.6Redis的启动1.7Redis是单线程多路IO复用技术1.NoSQL数据库 NoSQL(NoSQL Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库。 NoS…

学生HTML个人网页作业作品 (服装商城HTML+CSS)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材,DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 在线商城购物 | 水果商城 | 商城系统建设 | 多平台移动商城 | H5微商城购物商城项目 | HTML期末大学生网页设计作业,Web大学生网页 HTML&a…

RK3588平台开发系列讲解(Pinctrl篇)Pinctrl设备树介绍

平台内核版本安卓版本RK3588Linux 5.10Android12🚀返回专栏总目录 文章目录 一、 DTS介绍二、新建pinctrl三、引用pinctrl沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍pinctrl设备树的使用方法。 一、 DTS介绍 RK芯片的设备树⼀般把pinctrl节点放在soc…

元宇宙数字藏品,打造数字经济产业,实现全新业态升级

《中华人民共和国国民经济和社会发展第十四个五年规划和2035年远景目标纲要》提出以数字化转型整体驱动生产方式、生活方式和治理方式变革,催生新产业新业态新模式,壮大经济发展新引擎,将“虚拟现实和增强现实”列入了数字经济重点产业。 而自…

GAN生成漫画脸

最近对对抗生成网络GAN比较感兴趣,相关知识点文章还在编辑中,以下这个是一个练手的小项目~ (在原模型上做了,为了减少计算量让其好训练一些。) 一、导入工具包 import tensorflow as tf from tensorflow.keras import layersimport numpy a…

tinymce富文本编辑器做评论区

今天分享一下tinymce富文本编辑器做评论区的全过程。 文章目录一、介绍1.最终效果2.功能介绍3.主要项目包版本介绍:二、每个功能的实现1.自定义toolbar的功能区①对应的样式以及意义②对应的代码实现【忽略了一切非实现该功能的代码】2.展示、收起评论区①对应的样式…

ctf工具之:mitmproxy实践测试

1、安装居然使用的pip pip install mitmproxy 导入证书,密码为空 2、启用mitmweb pause 直接可以查看方式 搜索里输入login 对于http协议 直接看到了密码原文 3、后台日志方式 录入和回放 mitmdump -w baidu.txt pause 录制结束 mitmdump -nC baidu.txt paus…

如何设计可扩展架构

架构设计复杂度模型 业务复杂度和质量复杂度是正交的 业务复杂度 业务固有的复杂度,主要体现为难以理解、难以扩展,例如服务数量多、业务流程长、业务之间关系复杂 质量复杂度 高性能、高可用、成本、安全等质量属性的要求 架构复杂度应对之道 复杂…

MySQL备份与恢复

目录 一.数据备份的重要性 二.数据库备份的分类 2.1 物理备份 2.2 逻辑备份 2.3 完全备份(只适合第一次) 三.常见的备份方法 四.MySQL完全备份 4.1 MySQL完全备份优缺点 4.2 数据库完全备份分类 4.2.1 物理冷备份与恢复 五.完全备份 5.1 MySQ…