当前位置: 首页 > news >正文

Crimson:高性能,高扩展的新一代 Ceph OSD

背景

随着物理硬件的不断发展,存储软件所使用的硬件的情况也一直在不断变化。

一方面,内存和 IO 技术一直在快速发展,硬件的性能在极速增加。在最初设计 Ceph 的时候,通常情况下,Ceph 都是被部署到机械硬盘上,能够提供数百 IOPS 的读写和数十 G 的磁盘容量。但是,目前最新的 NVMe 设备可以提供数百万的 IOPS 读写,并支持 TB 级的磁盘容量。DRAM 的容量在大约20年的时间内增加了128倍。对于网络 IO 来说,网卡设备现在能够提供超过 400Gbps 的速度,而几年前只有 10Gbps。

另一方面,在大约十年的时间内,CPU 频率和 CPU 内核的单线程性能一直处于稳定的状态,增长不明显。相比之下逻辑核心的数量随着晶体管规模的增加而迅速增长。

Ceph 的性能要跟上硬件发展的速度一直很有挑战的,因为 Ceph 的架构是十年前的——它对单核 CPU 性能的依赖使它无法充分利用不断增长的 IO。特别是,当 Ceph 对象存储守护程序(OSD)依赖线程池来处理不同的 IO 时,跨 CPU 核心通信会产生了大量的延迟开销。减少或消除这些开销成本是 Crimson 项目的核心目标。

Crimson 项目使用 shared-nothing 设计和 run-to-completion 模型来重写 Ceph OSD,以满足苛刻的硬件与软件系统的扩展要求,同时也与现有的客户端和组件兼容。

为了理解 Crimson OSD 如何针对 CPU 扩展进行重新设计的,我们比较了 传统 OSD 和 Crimson OSD 之间的架构差异,来解释架构怎么以及为何这样设计。然后我们讨论了 Crimson 为什么建立在 Seastar 框架之上,以及每个核心组件是如何实现扩展的。

最后,我们分享了实现这一目标的最新情况,同时还提供了一个我们最终希望达到的性能结果。

Crimson 与传统 OSD 架构

Ceph OSD 是 Ceph 集群的一部分,主要负责通过网络来提供对象的访问、维护数据冗余和高可用性以及将对象持久化到本地存储设备。作为传统 OSD 的重写版本,Crimson OSD 从客户端和 OSD 的角度来看是与现有的 RADOS 协议兼容的,它提供相同的接口和功能。Messenger、OSD 服务和 ObjectStore 等 Ceph OSD 模块化的功能没有太大改变,但跨组件交互和内部资源管理的形式进行了大幅重构,以使用 shared-nothing 设计和自下而上的用户空间任务调度。

传统 OSD 的架构中,每个组件中都有线程池,针对多 CPU 核心场景下,使用共享队列处理任务效率很低。在一个简单的例子中,一个 PG 操作需要先由一个messenger worker 线程处理,将原始数据流组装或解码成一条消息,然后放入消息队列中进行调度。之后由一个PG worker thread 来获取消息,经过必要的处理后,将请求以事务的形式交给 ObjectStore。

事务提交后,PG 会完成操作,再次通过发送队列和 messenger worker 线程发送回复。尽管可以通过向池中添加更多线程来将工作负载扩展到多个 CPU,但这些线程默认共享资源,因此需要锁,这会引入争用问题。

传统架构的一个主要挑战是锁竞争开销随着任务数和 CPU 核数的增加而迅速扩大,在某些场景下每个锁点都可能成为扩展瓶颈。此外,这些锁和队列即使在没有争用的情况下也会产生延迟开销。多年来,社区在分析和优化更细粒度的资源管理和快速路径实现以跳过队列方面做了大量工作。未来,这类优化的成果会越来越少,可扩展性似乎会在当前的设计架构下达到了某个瓶颈。也还有其他挑战。随着在工作线程之间分配任务,延迟问题将随着线程池和任务队列而恶化。锁可以强制上下文切换,这会使事情变得更糟。

Crimson 项目希望通过 shared-nothing 设计和 run-to-completion 模型来解决 CPU 可扩展性问题。该设计的重点是强制每个内核或 CPU 运行一个固定线程并在用户空间中分配非阻塞任务。因为请求以及它们的资源可以被分配到各个核心,所以它们可以在同一个核心中被处理,直到处理完成。理想情况下,我们不再需要所有的锁和上下文切换,因为每个正在运行的非阻塞任务都使用到 CPU,一直到它完成任务。没有其他线程可以在同一时间抢占任务。如果不需要与数据路径中的其他分片通信,理想情况下,性能将随着内核数量线性扩展,直到 IO 设备达到其极限。这种设计非常适合 Ceph OSD,因为在 OSD 层面,所有 IO 都已经被 PG 分片了。

虽然跨区通信不能完全消除,但那通常是用于 OSD 全局状态的维护,而不是用于数据路径中。这里的一个主要挑战是,最重要的改变是对 OSD 操作的基本要求——相当一部分现有的锁或线程代码无法重用,需要重新设计,同时保持向后的兼容性。

重新设计需要对代码的整体理解,以及相关的注意事项。使用 shared-nothing 架构实现底层的one-thread-per-core和用户空间调度是另一个挑战。

Crimson 试图在 Seastar 的基础上重新设计 OSD,Seastar 是一个异步编程框架,具有满足上述目标的所有理想特性。

Seastar Framework

Seastar 是 Crimson 项目的理想选择,因为它不仅在 C++ 中实现了 one-thread-per-core 的 shared-nothing 架构,而且还提供了一套全面的功能和模型,这些功能和模型已被证明在其它应用程序中对性能和扩展有效。资源默认情况下不在分片之间共享,Seastar 实现了自己的内存分配器以进行无锁分配。该分配器还利用了 NUMA 拓扑结构的优势,将最近的内存分配给分片。对于一些不可避免的跨核资源共享和通信,Seastar 强制要求明确地处理它们。如果一个分片拥有另一个核心的资源,它必须通过外部指针指向这些资源;如果一个分片需要与其他分片通信,它必须提交并转发任务给他们。这就迫使程序限制其跨核的需求,并有助于减少对 CPU 扩展性问题的分析范围。Seastar 还为跨核通信实现了高性能的非阻塞通信。

传统的带有异步事件和回调的程序在实现、理解和调试方面是非常困难的。用户空间的非阻塞任务调度需要实现普遍的异步性。Seastar 将 futures、promises 和 continuations (f/p/c) 作为构建块来组织逻辑。futures 和 promises 通过将逻辑上连接的异步结构组合在一起,而不是将它们分散用于普通的回调中,这使代码更更容易实现以及更好的可读性。Seastar 还为循环、计时器以及基于未来控制生命周期甚至 CPU 份额提供了更高级别的工具。为了进一步简化应用程序,Seastar 将网络和磁盘访问封装到 shared-nothing 和基于 f/p/c 设计的模式中。采用不同 I/O 堆栈(如 epoll、linux-aio、io-uring、DPDK 等)的复杂性和细微控制对应用程序代码是透明的。

Run-to-completion performance

Crimson 团队已经为 RBD 客户端的读写工作负载实现了 OSD 的大部分关键特性。当前完成的任务包括重新实现 messenger V2 (msgr2), heartbeat, PG peering, backfill, recovery, object-classes, watch-notify, etc等,并不断努力的增加一些 CI 测试组件。Crimson 已经达到了一个里程碑,我们可以在具有足够稳定的单个分片中验证run-to-completion设计。

综合考虑现实条件,在相同的随机 4KB RBD 工作负载下,在没有复制的情况下,通过将传统和 Crimson OSD 与 BlueStore 后端进行比较来验证 single-shard run-to-completion。两个 OSD 都分配了 2 个 CPU 资源。Crimson OSD 很特别,因为 Seastar 需要一个独占 CPU 核心来运行 single-shard OSD 逻辑。这意味着 BlueStore 线程必须固定到另一个核心,引入 AlienStore 来弥合 Seastar 线程和 BlueStore 线程之间的边界,并在两个边界之间提交 IO 任务。相比之下,传统 OSD 没有限制使用分配的 2 个 CPU。

性能结果显示,使用 BlueStore 时,Crimson OSD 的随机读取性能大约提高了 25%,随机写入情况下的 IOPS 大约比传统 OSD 高 24%。进一步的分析显示,在随机写的情况下,CPU 的利用率很低,因为大约 20% 的 CPU 被消耗在频繁的查询中,这表明 Crimson OSD 应该不是是当前的瓶颈。

Crimson OSD 提交和完成 IO 任务,以及在 Seastar 和 BlueStore 线程之间进行同步,也有额外的开销。因此,我们针对 MemStore 后台重复了同一组实验,两个 OSD 都分配了 1 个 CPU。如下图所示,Crimson OSD 在随机读取中提供了大约 70% 的 IOPS,在随机写入中比 传统 OSD 高 25%,这与之前实验中的结论一致,即 Crimson OSD 可以做得更好。

尽管上述场景仅涵盖实验性 single-shard 案例,但结果表明使用 Seastar 框架具有性能优势——消除锁、通过用户空间任务调度删除上下文切换、分配更靠近 CPU 的内存。此外,重要的是要重申,run-to-completion 模型的目标是更好地扩展 CPU 并消除软件使用高性能硬件而引起的性能瓶颈。

Multi-shard Implementation

实现多分片的路径很明确。由于每个PG中的 IO 已经在逻辑上被分片,所以对IO路径没有太大改变。主要的挑战是确定无法避免的跨核通信,并设计新的解决方案,以尽量减少其对IO路径的影响,这需要根据具体情况进行分析。一般来说,当从 Messenger 接收到一个 IO 操作时,它会根据 PG-core 映射被定向到 OSD 分片,并在同一分片/CPU的上下文中运行,直到完成。请注意,在当前阶段,为了简单起见,设计上选择不修改RADOS协议。

Messenger

Messenger 在确保解决方案可扩展方面发挥着重要作用。有一些限制需要认真考虑。一个限制来自 RADOS 协议,它只为每个客户端或 OSD 定义一个连接。连接必须存在于特定核心上才能根据其状态高效且无锁地解码和编码消息。与 OSD 对等体的共享连接意味着在当前阶段跨核消息传递到多个 PG 分片是不可避免的,除非可以调整协议以允许到每个分片的独占连接。

Seastar 框架的另一个限制是它不允许在 Seastar 套接字被 accept()ed 或 connect()ed 之后移动到另一个核心。这对无损连接 (msgr2) 来说是一个挑战,因为它会影响 Messenger 和 OSD 服务之间的交互,在这种情况下,由于网络故障重新连接,连接可能会预先跳转到另一个核心。

扩展 Messenger 的大部分工作是在将 IO 操作分派到 PG 分片之前将消息传递工作负载(编码、解码、压缩、加密、缓冲区管理等)优化扩展到多个内核,并最小化跨内核消息沿 IO 路径传递,理想情况下,在上述约束下,对于每个消息发送和接收操作,它最多保持 1 跳。

OSD

OSD 负责维护 PG 分片之间共享的全局状态和活动,包括心跳、身份验证、客户端管理、osdmap、PG 维护、访问 Messenger 和 ObjectStore 等。

多核 Crimson OSD 的一个简单原则是将所有与共享状态相关的处理保持在专用内核上。如果一个 IO 操作要访问共享资源,要么按顺序访问专用核,要么访问保持同步的共享信息的独占副本。

实现这一目标有两个主要步骤。第一步是让 IO 操作根据 PG 分片策略运行在多个 OSD 分片中,包括 PG 状态在内的所有全局信息都维护在第一个分片中。此步骤在 OSD 中启用分片,但需要在第一个分片中做出有关 IO 调度的所有决策。即使这一步 Messenger 可以在多核中运行,消息仍然需要传递到第一个分片进行准备(例如 PG peering)并在提交到该分片之前确定正确的 PG 分片。这会导致额外的开销和不平衡的 CPU 使用(第一个 OSD 分片使用率高,其他分片很低,等等)。因此,下一步是将 PG-core 映射扩展到所有 OSD 分片。

ObjectStore

Crimson 支持三种 ObjectStore 后端:AlienStore、CyanStore 和 SeaStore。AlienStore 提供与 BlueStore 的向后兼容性。CyanStore 是用于测试的虚拟后端,由易失性内存实现。SeaStore 是一种新的对象存储,专为 Crimson OSD 设计,采用 shared-nothing 设计。根据后端的具体目标,实现多分片支持的路径是不同的。

1AlienStore

AlienStore 是 Seastar 线程中的一个瘦代理,用于与使用 POSIX 线程的 BlueStore 进行通信。对于多个 OSD 分片没有特别的工作要做,因为 IO 任务通信同步了。BlueStore 中没有为 Crimson 定制其他内容,因为不可能真正将 BlueStore 扩展到 shared-nothing 设计,因为它依赖于第 三 方 RocksDB 项目,而 RocksDB 仍然是线程的。但是,在 Crimson 能够拿出一个足够优化和足够稳定的原生存储后端解决方案(SeaStore)之前,合理的开销来换取复杂的存储后端解决方案是可以接受的。

2CyanStore

Crimson OSD 中的 CyanStore 与传统 OSD 中的 MemStore 相对应。对多分片支持的唯一改变是为每个分片创建独立的 CyanStore 实例。一个目标是确保虚拟 IO 操作能够在同一个内核中完成,以帮助识别 OSD 级别的可扩展性问题(如果有的话)。另一个目标是在 OSD 层面上与传统 OSD 做直接的性能比较,而不受 ObjectStore 的复杂因数影响。

3SeaStore

SeaStore 是 Crimson OSD 原生的 ObjectStore 解决方案,采用 Seastar 框架开发,采用相同的设计原则。

虽然很有挑战性,但是 Crimson 必须建立一个新的本地存储引擎,这有多种原因。存储后端是主要的 CPU 资源消耗者,如果 Crimson OSD 的存储后端不改变,那么它就不能真正地随核心扩展。我们的实验也证明了 Crimson OSD 不是随机写入场景中的瓶颈。

其次,BlueStore 中具有事务支持的 CPU 密集型元数据管理基本上由 RocksDB 提供,如果不重新实现,它无法在原生的 Seastar 线程中运行。与其为 BlueStore 重新实现通用的键值事务存储,不如在更高的层次上重新思考和定制相应的架构——ObjectStore。问题在原生的解决方案中比在 第三方项目中更容易解决,因为第三方项目必须保证使用与通用的场景。

第三个考虑是为异构存储设备和硬件加速器提供原生支持,让用户可以根据自己的需求平衡成本和性能。如果 Crimson 能够更好地控制整个存储堆栈,那么 Crimson 将更灵活地简化部署硬件组合的解决方案。

SeaStore 在单分片读写方面已经可以正常使用,尽管在稳定性和性能改进方面仍有待努力。目前的努力仍然集中在架构上,而不是极端情况下的优化。它针对多分片 OSD 的设计很明确。与 CyanStore 一样,第一步是为每个 OSD 分片创建独立的 SeaStore 实例,每个实例都在存储设备的静态分区上运行。第二步是实现一个共享磁盘空间平衡器来动态调整分区,它应该可以在后台异步运行,因为 PG 已经以伪随机方式分配了用户 IO。SeaStore 实例可能不需要等于 OSD 分片的数量,根据性能分析,调整这个比例是后期工作的第三步。

摘要和测试配置

在这篇文章中,我们介绍了为什么以及如何对 Ceph OSD 进行重构以跟上硬件的发展。另外我们也给出了我们所做的详细设计、 一个简单的性能测试结果。也提供了 Crimson OSD 真正实现多核可扩展的所要考虑的大部分因素。

测试结果可能会根据不同的 commit 版本、软件和硬件配置而有所变化。为了确保我们的测试是可重复的,可复现的,并可在以后场景中作为参考,我们列出了所有可能产生影响的设置和注意事项。

我们为 Crimson 和 传统 OSD 部署了本地 Ceph 集群,并使用 CBT 执行了 FIO 测试。Crimson 在使用 tcmalloc 时仍然存在问题,因此为了公平起见,我们将两个 OSD 配置为使用 libc*。我们使用 BlueStore。RBD 缓存被禁用。BlueStore 线程数设置为 4 以获得更好的结果。部署 Crimson 时,需要指定*ceph-osd_cmd ( crimson-osd )。CPU 绑定通过 CBT 配置文件中的 crimson_cpusets 指定,BlueStore 线程通过 crimson_alien_thread_cpu_cores 和 crimson_alien_op_num_threads配置。要部署传统 OSD,numactl 用于控制 CPU 绑定。根据 CBT 存储库,部署过程的其余部分没有变化。

测试场景:

  • Client: 4 FIO clients
  • IO mode: random write and then random read
  • Block size: 4KB
  • Time: 300s X 5 times to get the average results
  • IO-depth: 32 X 4 clients
  • Create 1 pool using 1 replica
  • 1 RBD image X 4 clients
  • The size of each image is 256GB

测试环境:

  • Ceph 版本 (SHA1):7803eb186d02bb852b95efd1a1f61f32618761d9
  • Ubuntu 20.04
  • GCC-12
  • 1TB NVMe SSD 作为 BlueStore 块设备
  • 50GB 内存用于 MemStore 和 CyanStore

相关文章:

Crimson:高性能,高扩展的新一代 Ceph OSD

背景 随着物理硬件的不断发展,存储软件所使用的硬件的情况也一直在不断变化。 一方面,内存和 IO 技术一直在快速发展,硬件的性能在极速增加。在最初设计 Ceph 的时候,通常情况下,Ceph 都是被部署到机械硬盘上&#x…...

【websocket】websocket-client 与 websockets

websocket-client websocket-client 是 websocket 客户端,提供了对ws低级API的访问。通过导入 websocket 库使用,websocket 库是基于事件驱动的设计模式,通过定义回调函数来处理接收到的消息、错误和连接关闭等事件。 优势: 兼容…...

Qt快速学习(一)--对象,信号和槽

目录 1.Qt概述 1.1 什么是Qt 2.2 手动创建 2.3 pro文件 2.4 一个最简单的Qt应用程序 3 第一个Qt小程序 3.1 按钮的创建 3.2 对象模型(对象树) 3.3 Qt窗口坐标体系 4 信号和槽机制 4.1 系统自带的信号和槽 4.2 自定义信号和槽 4.3信号槽的拓展 4…...

Qt6之如何为QDialog添加最大化和最小化按钮

在QDialog构造函数中添加以下几行代码: // 设置窗体最大化和最小化Qt::WindowFlags windowFlag Qt::Dialog;windowFlag | Qt::WindowMinimizeButtonHint;windowFlag | Qt::WindowMaximizeButtonHint;windowFlag …...

攻防世界-warmup

原题解题思路 只有一张图片,就查看源代码,有一个source.php。 查看source.php,白名单中还有一个hint.php。 hint.php告诉我们flag的位置ffffllllaaaagggg 但是直接跳转是没用的,构造payload。 http://61.147.171.105:55725/sourc…...

02__models

LangChain提供两种封装的模型接口 1.大规模语言模型(LLM):输入文本字符串,返回文本字符串 2.聊天模型:基于一个语言模型,输入聊天消息列表,返回聊天消息 Langchain的支持OpenAI、ChatGLM、Hu…...

MyBatis入门配置及CURD实现

目录 一、MyBatis简介 1. 什么是 MyBatis ? 2. MyBatis的特性 3. 什么是持久层框架? 二、MyBatis环境配置 2.1 创建maven工程 2.2 导入相关pom依赖 2.3 导入jdbc配置文件 2.4 Mybatis相关插件安装 3.5 Mybatis-cfg.xml 核心配置 2.6 引入Log4j2日志文件…...

《游戏编程模式》学习笔记(五)原型模式 Prototype Pattern

原型的定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 举个例子 假设我现在要做一款游戏,这个游戏里有许多不同种类的怪物,鬼魂,恶魔和巫师。这些怪物通过“生产者”进入这片区域,每种敌人…...

ansible案列之LNMP分布式剧本

LNMP分布式剧本 一:环境设置二:编写Nginx剧本准备nginx下载源准备配置文件并开放PHP的访问路径准备php测试页面编写nginx剧本 三:编写Mysql剧本编写密码获取脚本准备Mysql的yum源编写mysql剧本 四:准备PHP剧本准备两个配置文件编写…...

React2023电商项目实战 - 1.项目搭建

古人学问无遗力,少壮工夫老始成。 纸上得来终觉浅,绝知此事要躬行。 —— 陆游《《冬夜读书示子聿》》 系列文章目录 项目搭建App登录及网关App文章自媒体平台(博主后台)内容审核(自动) 文章目录 系列文章目录一、项目介绍1.页面…...

数据库连接池(c3p0和德鲁伊)

目录 连接池介绍 c3p0连接池 传统方法引入jar包 配置文件 德鲁伊连接池 德鲁伊工具类 传统jdbc数据库使用DriverManger来获取,每次向数据库建立连接需要将Connection加载到内存中,频繁的操作会造成占用很多系统资源,造成服务器崩溃&…...

ARM--day6(实现字符、字符串收发的代码和现象,分析RCC、GPIO、UART章节)

uart4.h #ifndef __UART4_H__ #define __UART4_H__#include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_uart.h"//RCC/GPIO/UART4章节初始化 void hal_uart4_init();//发送一个字符函数 void hal_put_char(const c…...

2023牛客暑期多校训练营9 B.Semi-Puzzle: Brain Storm

文章目录 题目大意题解求解回溯 参考代码 题目大意 给定两个数 a , m a,m a,m ,求满足 a u ≡ u ( m o d m ) a^u \equiv u (mod\ \ m) au≡u(mod m) 的一个解。 ( 1 ≤ a , m ≤ 1 0 9 , 0 ≤ u ≤ 1 0 18 ) (1\leq a,m \leq10^9 ,0\leq u\leq 10^{18}) (1≤a…...

mysql中的窗口函数

MySQL中的窗口函数(Window Functions)是一种用于在查询结果集内执行计算的功能。窗口函数可以在查询中进行分析和聚合操作,而无需将查询结果分组。它们可以用于计算排名、行号、累积值等各种分析操作。窗口函数通常与OVER子句一起使用&#x…...

【双指针】经典数组双指针题LeetCode

文章目录 27. 移除元素 简单283. 移动零 简单🔥167. 两数之和 II - 输入有序数组 中等11. 盛最多水的容器 中等🔥15. 三数之和 中等(N数之和)中等🔥42. 接雨水 困难 🔥26. 删除有序数组中的重复项 简单5. 最…...

极智嘉x吉利汽车 x京东物流,引领汽车行业智慧物流新变革!

近日,中国领先的汽车制造商吉利汽车携手中国领先的技术驱动的供应链解决方案及物流服务商京东物流、全球仓储机器人引领者极智嘉(Geek),在西安吉利汽车制造基地RDC仓库率先落地SkyPick上存下拣解决方案,实现了全物流链精益化、智能化、一体化…...

RK3588平台开发系列讲解(AI 篇)RKNN C API 详细说明

文章目录 一、API 硬件平台支持说明二、API 函数介绍2.1、rknn_init2.2、rknn_destroy2.3、rknn_query2.4、rknn_inputs_set2.5、rknn_run2.6、rknn_outputs_get2.7、rknn_outputs_release沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要讲解 RKNN C API 详细…...

【基础】Android Handler

一、博客参考 Handler机制详解【重点】:https://www.jianshu.com/p/b4d745c7ff7a Handler Thread工作线程操作UI范例【重点】:https://www.cnblogs.com/net168/p/4075126.html 二、内存泄漏的解决:静态内部类弱引用 关于 Handler&#xf…...

c语言实现MD5算法

MD5加密 文章目录 MD5加密MD5介绍应用场景代码分析 (基于qt5.14.2)测试记录 MD5介绍 1。 一种单向加密算法,即对明文加密,而不能通过密文得到明文。对原数据的任何改动,哪怕是1字节,得到的MD5值都有很大的区…...

Apache Doris 2.0.0 特性分析

1、存算分离 所谓存算分离是指查询外表时,使用一种专门做计算的BE节点,但对于存储在BE上的内部表,目前还不能做到存储分离。 doris可以查询外部表,包括: Hive、Iceberg、Hudi、Elasticsearch、JDBC、Paimon 早期版本中…...

如何做H5性能测试?

提起H5性能测试,可能许多同学有所耳闻,但是不知道该如何对H5做性能测试,或者不知道H5应该关注哪些性能指标。今天我们就来看下,希望阅读本文后,能够有所了解。 常用指标 1、H5性能相关参数介绍 白屏时间:…...

【Docker】Docker Desktop配置资源:cpu、内存等(windows环境下)

Docker Desktop配置资源:cpu、内存等(windows环境下) 一、WSL2 以及 hyper-v区别,二者安装docker desktop1.WSL2和hyper-v区别2.安装Docker Desktop 二、docker desktop限额配置,资源配置方法 Docker 是指容器化技术&a…...

8.2.tensorRT高级(3)封装系列-内存管理的封装,内存的复用

目录 前言1. 内存管理封装2. 补充知识总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。 本次课程学习 tensorRT 高级-内存管理的封装&…...

Keepalived入门指南:实现故障转移和负载均衡

文章目录 一、简介1. Keepalived概述2. 高可用性和负载均衡的重要性 二、故障转移1. 什么是故障转移2. Keepalived的故障转移原理a) VRRP协议b) 虚拟路由器ID和优先级 3. 配置Keepalived实现故障转移a) 主备服务器的设置b) 监控网络接口c) 虚拟IP的配置d) 备份服务器接管流程 三…...

cuOSD(CUDA On-Screen Display Library)库的学习

目录 前言1. cuOSD1.1 Description1.2 Getting started1.3 For Python Interface1.4 Demo1.5 Performance Table 2. cuOSD案例2.1 环境配置2.2 simple案例2.3 segment案例2.4 segment2案例2.5 polyline案例2.6 comp案例2.7 perf案例 3. cuOSD浅析3.1 simple_draw函数 4. 补充知…...

c++函数指针基本用法

将函数像变量一样传递,实际上拿到的是函数的地址,由于函数类型的多样,可以使用auto关键字,可以使用 void(*function2)() ,不过它太繁琐,因此使用typedef 起个名字 typedef void(*HelloWorldFunction)(); 叫…...

Java创建对象的几种方式

在Java中,对象是程序中的一种基本元素,它通过类定义和创建。本篇教程旨在介绍Java中创建对象的几种方式,包括使用new关键字、反射、clone、反序列化等方式。 使用new关键字创建对象 在Java中,最常用的创建对象方式是使用new关键…...

Docker实战专栏简介

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...

解放数据库,实时数据同步利器:Alibaba Canal

文章首发地址 Canal是一个开源的数据库增量订阅&消费组件,主要用于实时数据同步和数据订阅的场景,特别适用于构建分布式系统、数据仓库、缓存更新等应用。它支持MySQL、阿里云RDS等主流数据库,能够实时捕获数据库的增删改操作&#xff…...

机器学习基础之《分类算法(3)—模型选择与调优》

作用是如何选择出最好的K值 一、什么是交叉验证(cross validation) 1、定义 交叉验证:将拿到的训练数据,分为训练和验证集。以下图为例:将数据分成5份,其中一份作为验证集。然后经过5次(组)的测试&#x…...

孝感做网站/搜索引擎的四个组成部分及作用

发现一个问题,我phpmyadmin竟然可以随便用一个帐号和空密码登录。现在设置下phpmyadmin不允许使用空密码登录。解决办法:(1)修改phpmyadmin文件config.inc.php(根目录)或config.default.php(根目录)或libraries\config.default.ph…...

怎么自己做导购网站/seo快速排名首页

短语 suspense film 悬疑片 thriller 恐怖片 romantic film 爱情片 action movie 动作片 comedy 喜剧 tragedy 悲剧 In my working overtime 在我加班期间 drink milk 喝牛奶 grade one in high / middle school 初一或者高一 in a good mood 拥有好心情 dormitory / dorm 宿舍…...

东莞专业做淘宝网站/广州疫情最新数据

刘恺威说:“我74年的,杨幂86年的,我大三时她才小学一年级。”李双江不服:“老子39年的,梦鸽66年的,老子大三时,她没出生呢!”张艺谋哈哈大笑:“我50年的,新妻…...

凡科建站官网登录入口网页版/百度seo排名优化系统

根据《武汉大学学生出国(境)交流学习专项奖学金管理暂行办法》(武大外字[2017]35号)和《武汉大学弘毅学堂学生出国(境)交流学习资助实施办法(2019修订版)》文件精神的有关要求&#…...

龙岗建设企业网站/什么是网络营销?

问: 你做这个研究有一些年头了,我侧重于关心这些付出会有哪些回报? 答:预期回报当然是有的。那就是建立一个智能软件社区,每一个贡献者(包括我)通过别人的使用获得回报。至于回报的多少,最简单…...

观澜专业做网站公司/百度竞价推广点击软件

match 最简单的一个match例子: 查询和"我的宝马多少马力"这个查询语句匹配的文档。 {"query": {"match": {"content" : {"query" : "我的宝马多少马力"}}} }上面的查询匹配就会进行分词&#xff0c…...