ceph介绍、原理、架构、算法...个人学习记录
前言
之前公司安排出差支援非结构化项目,采用springcloud+(redis+mysql数据冷热处理)+s3+es+ceph+kafka还涉及一些区块链技术等等…,在与大佬的沟通交流下对ceph产生了兴趣,私下学习记录一下;后续工作之余会采用上面相关技术栈手动实现不带公司业务的项目,可能不会分享出来;
ceph集群部署、Amazon S3 API java uitl
这篇记录学习ceph的相关知识
ceph简介
- ceph是⼀种分布式存储系统,可以将多台服务器组成⼀个超⼤集群,把这些机器中的磁盘资源整合到⼀块⼉,形成⼀个⼤的资源池,⽀持PB级别,然后按需分配给客户端应⽤使⽤。
- ⽀持三种存储接口: 对象存储、块存储、⽂件存储。
- 采⽤CRUSH算法,数据分布均衡,并⾏度⾼,不需要维护固定的元数据结构(与结构化存储不同,理解为非结构化)。
- CRUSH需要集群的映射,使⽤CRUSH映射在OSDs中伪随机存储和检索数据,数据在集群中均匀分布,数据具有强⼀致性,确保所有副本写⼊完成后才返回确认,适合读多写少的场景。
- 去中⼼化,没有固定的中⼼节点,集群扩展灵活。
- 去中⼼化的分布式解决⽅案,需要提前做好组件和节点部署规划设计。
- ceph扩容时,由于其数据分布均衡的特性,会导致整个存储系统性能下降。
ceph核心组件
- Monitor(ceph-mon):维护集群Cluster Map的状态,维护集群的Cluster MAP⼆进制表,保证集群数据的⼀致性。Cluster
MAP描述了对象块存储的物理位置,以及⼀个将设备聚合到物理位置的桶列表,map中包含monitor组件信息,manger 组件信息,osd
组件信息,mds 组件信息,crush 算法信息。还负责ceph集群的身份验证功能,client 在连接ceph集群时通过此组件进⾏验证。- OSD(ceph-osd):OSD全称Object Storage Device,⽤于集群中所有数据与对象的存储。ceph 管理物理硬盘时,引⼊了OSD概念,每⼀块盘都会针对的运⾏⼀个OSD进程。换句话说,ceph 集群通过管理 OSD
来管理物理硬盘。负责处理集群数据的复制、恢复、回填、再均衡,并向其他osd守护进程发送⼼跳,然后向Mon提供⼀些监控信息。当Ceph存储集群设定数据有两个副本时(⼀共存两份),则⾄少需要三个OSD守护进程即三个OSD节点,集群才能达到active+clean状态,实现冗余和⾼可⽤。- Manager(ceph-mgr):⽤于 收集ceph集群状态、运⾏指标,⽐如存储利⽤率、当前性能指标和系统负载。对外提供 ceph dashboard(ceph ui)和 resetful api。Manager组件开启⾼可⽤时,⾄少2个实现⾼可⽤性。
- MDS(ceph-mds):Metadata server,元数据服务。为ceph ⽂件系统提供元数据计算、缓存与同步服务(ceph 对象存储和块存储不需要MDS)。同样,元数据也是存储在osd节点中的,mds类似于元数据的 代理缓存服务器,为 posix
⽂件系统⽤户提供性能良好的基础命令(ls,find等)不过只是在需要使⽤CEPHFS时,才需要配置MDS节点。- Object:Ceph最底层的存储单元是Object对象,每个Object包含元数据和原始数据。
- PG:PG全称Placement Grouops,是⼀个逻辑的概念,⼀个PG包含多个OSD。引⼊PG这⼀层其实是为了更好的分配数据和定位数据。
- RADOS:RADOS全称Reliable Autonomic Distributed Object Store(可靠、⾃治、分布式对象存储),是Ceph集群的精华,⽤户实现数据分配、Failover(故障转移)等集群操作。
- Libradio驱动库:Librados是Rados提供库,因为RADOS是协议很难直接访问,因此上层的RBD、RGW和CephFS都是通过librados访问的,⽬前提供PHP、Ruby、Java、Python、C和C++⽀持。
- CRUSH:Ceph使⽤的数据分布算法,类似⼀致性哈希,让数据分配到预期的地⽅。
- RBD:RBD全称RADOS block device,是Ceph对外提供的块设备服务。
- RGW:RGW全称RADOS gateway,是Ceph对外提供的对象存储服务,接⼝与S3和Swift兼容。
- CephFS:CephFS全称Ceph File System,是Ceph对外提供的⽂件系统服务。
核心架构
基础存储系统RADOS
- RADOS(Reliable Autonomic Object Store,可靠、⾃动、分布式对象存储)是ceph存储集群的基础,这⼀层本身就是⼀个完整的对象存储系统。Ceph的⾼可靠、⾼可扩展、⾼性能、⾼⾃动化等等特性本质上也都是由这⼀层所提供的,在ceph中,所有数据都以对象的形式存储,并且⽆论什么数据类型,RADOS对象存储都将负责保存这些对象,确保了数据⼀致性和可靠性。
- RADOS系统主要由两部分组成,分别是OSD(对象存储设备)和Monitor(监控OSD)。
- 能够在动态变化和异质结构的存储设备机群之上提供⼀种稳定、可扩展、⾼性能的单⼀逻辑对象(Object)存储接⼝和能够实现节点的⾃适应和⾃管理的存储系统。
- 在传统分布式存储架构中,存储节点往往仅作为被动查询对象来使⽤,随着存储规模的增加,数据⼀致性的管理会出现很多问题。⽽新型的存储架构倾向于将基本的块分配决策和安全保证等操作交给存储节点来做,然后通过提倡客户端和存储节点直接交互来简化数据布局并减⼩io瓶颈。
基础库LIBRADOS
LIBRADOS基于RADOS之上,它允许应⽤程序通过访问该库来与RADOS系统进⾏交互,⽀持多种编程语⾔,⽐如C、C++、Python等。
上层接⼝RADOSGW、RBD和CEPHFS
- 基于LIBRADOS层开发的三个接⼝:RGW、RBD、CephFS,其作⽤是在librados库的基础上提供抽象层次更⾼、更便于应⽤或客户端使⽤的上层接⼝。
- RADOS GW(简称RGW)提供对象存储服务,是⼀套基于RESTFUL协议的⽹关,⽀持对象存储,兼容S3和Swift。
- RBD提供分布式的块存储设备接⼝,主要⾯向虚拟机提供虚拟磁盘,可以被映射、格式化,像磁盘⼀样挂载到服务器使⽤。
- CephFS是⼀个POSIX兼容的分布式⽂件系统,依赖MDS来跟踪⽂件层次结构,基于librados封装原⽣接⼝,它跟传统的⽂件系统如 Ext4 是⼀个类型的,但区别在于分布式存储提供了并⾏化的能⼒,像NFS等也是属于⽂件系统存储。
- 这⾥提到了两个对象,⼀个是RGW中的对象存储;⼀个是Ceph的后端存储的对象,这两个需要区分: 第⼀个对象⾯向⽤户,是⽤户接⼝能访问到的对象; 第⼆个对象是ceph 服务端操作的对象。
ceph存储接口
- ⽀持三种存储接⼝:对象存储,块存储,⽂件存储,三种⽅式可⼀同使⽤,在底层的数据存储是一致的。⽀持⾃定义接⼝,⽀持多种语⾔驱动。
- ceph是⼀套存储系统但它同时提供:对象存储、块设备存储、⽂件系统存储。
- 对象存储(Object):有原生的API,而且也兼容OpenStack Swift API和Amazon S3 API。
- 块设备存储(Block):支持精简配置、快照、克隆。
- ⽂件系统存储(File):Posix接口,支持快照。
三种存储
块存储
- 主要是将裸磁盘空间映射给主机使用的;(磁盘阵列,硬盘)。
- 多块硬盘组合起来,提高容量;多块磁盘组合出来的逻辑盘,提升读写效率。但是,主机之间无法共享数据。
- 通过Raid与LVM等手段,对数据提供了保护,但是采用SAN架构组网时,光纤交换机,造价成本高。
- rbd:(rados block devices) 是由ceph集群提供出来的块设备。rbd是通过⽹络连接到了ceph集群中的⼀块存储区域,往rbd设备⽂件写⼊数据,最终会被存储到ceph集群的这块区域中。延升:sda和hda都是通过数据线连接到了真实的硬盘。
- 你可以理解为:往rbd设备⽂件写⼊数据,最终会被存储到ceph集群的这块区域中。
文件存储
- 克服了块存储文件无法共享的问题。
- 在服务器上架设FTP与NFS服务,就是文件存储。
- 造价低,随便一台机器就可以了,但是读写速率低。
- 方便文件共享,但是传输速率慢。
对象存储
- 多台服务器内置大容量硬盘,安装上对象存储管理软件,对外提供读写访问功能,有原生的API,而且也兼容OpenStack Swift API和Amazon S3 API。
- 具备块存储的读写高速和文件存储的共享等特性。
- 使⽤⽅式是通过http协议上传下载删除对象(⽂件即对象)。
- ⽂件系统存储具有复杂的数据组织结构,能够提供给⽤户更加丰富的数据操作接⼝,⽽对象存储精简了数据组织结构,提供给⽤户有限的数据操作接⼝,以换取更好的存储性能。对象接⼝提供了REST API,⾮常适⽤于作为web应⽤的存储。
块设备接口与文件系统接口区别
Ceph的块设备具有优异的读写性能,但不能多处挂载同时读写,⽬前主要⽤在OpenStack上作为虚拟磁盘;⽽Ceph的⽂件系统接⼝读写性能较块设备接⼝差,但具有优异的共享性。
为什么Ceph的块设备接⼝不具有共享性,⽽Ceph的⽂件系统接⼝具有呢?
- 对于Ceph的块设备接⼝,⽂件系统的结构状态是维护在各⽤户机内存中的。假设Ceph块设备同时挂载到了⽤户机1和⽤户机2,当在⽤户机1上的⽂件系统中写⼊数据后,更新了⽤户机1的内存中⽂件系统状态,最终数据存储到了Ceph集群中,但是此时⽤户机2内存中的⽂件系统并不能得知底层Ceph集群数据已经变化⽽维持数据结构不变,因此⽤户⽆法从⽤户机2上读取⽤户机1上新写⼊的数据。
- 对于Ceph的⽂件系统接⼝,⽂件系统的结构状态是维护在远端Ceph集群中的。Ceph⽂件系统同时挂载到了⽤户机1和⽤户机2,当往⽤户机1的挂载点写⼊数据后,远端Ceph集群中的⽂件系统状态结构随之更新,当从⽤户机2的挂载点访问数据时会去远端Ceph集群取数据,由于远端Ceph集群已更新,所有⽤户机2能够获取最新的数据。
ceph底层存储过程
ceph IO算法
- File用户需要读写的文件。File->Object映射:ino (File的元数据,File的唯一id)。
- Object是RADOS需要的对象。Ceph指定一个静态hash函数计算oid的值,将oid映射成一个近似均匀分布的伪随机值,然后和mask按位相与,得到pgid。Object->PG映射:
hash(oid) & mask-> pgid 。- PG(Placement Group),用途是对object的存储进行组织和位置映射, (类似于redis cluster里面的slot的概念)
一个PG里面会有很多object。采用CRUSH算法,将pgid代入其中,然后得到一组OSD。PG->OSD映射:CRUSH(pgid)->(osd1,osd2,osd3)。
IO流程
- client 创建cluster handler。
- client 读取配置文件。
- client 连接上monitor,获取集群map信息。
- client 读写io 根据crshmap 算法请求对应的主osd数据节点。
- 主osd数据节点同时写入另外两个副本节点数据。
- 等待主节点以及另外两个副本节点写完数据状态。
- 主节点及副本节点写入状态都成功后,返回给client,io写入完成。
新加入的OSD1取代了原有的 OSD4成为 Primary OSD
这时新加入的OSD1取代了原有的 OSD4成为 Primary OSD, 由于 OSD1 上未创建 PG , 不存在数据,那么 PG 上的 I/O 无法进行,怎样工作的呢?
- client连接monitor获取集群map信息。
- 同时新主osd1由于没有pg数据会主动上报monitor告知让osd2临时接替为主。
- 临时主osd2会把数据全量同步给新主osd1。
- client IO读写直接连接临时主osd2进行读写。
- osd2收到读写io,同时写入另外两副本节点。
- 等待osd2以及另外两副本写入成功。
- osd2三份数据都写入成功返回给client, 此时client io读写完毕。
- 如果osd1数据同步完毕,临时主osd2会交出主角色。
- osd1成为主节点,osd2变成副本。
ceph RBD IO
- 采用的是librbd的形式,使用librbd创建一个块设备,向这个块设备中写入数据。
- 在客户端本地同过调用librados接口,然后经过pool,rbd,object、pg进行层层映射,在PG这一层中,可以知道数据保存在哪3个OSD上,这3个OSD分为主从的关系。
- 客户端与primay OSD建立SOCKET 通信,将要写入的数据传给primary OSD,由primary OSD再将数据发送给其他replica OSD数据节点。
- 客户端创建一个pool,需要为这个pool指定pg的数量。
- 创建pool/image rbd设备进行挂载。
- 用户写入的数据进行切块,每个块的大小默认为4M,并且每个块都有一个名字,名字就是object+序号。
- 将每个object通过pg进行副本位置的分配。
- pg根据cursh算法会寻找3个osd,把这个object分别保存在这三个osd上。
- osd上实际是把底层的disk进行了格式化操作,一般部署工具会将它格式化为xfs文件系统。
- object的存储就变成了存储一个文rbd0.object1.file。
Pool和PG分布
- pool是ceph存储数据时的逻辑分区,它起到namespace的作用。
- 每个pool包含一定数量(可配置)的PG。
- PG里的对象被映射到不同的Object上。
- pool是分布到整个集群的。
- pool可以做故障隔离域,根据不同的用户场景不一进行隔离。
OSD数据扩容
每个OSD上分布很多PG, 并且每个PG会自动散落在不同的OSD上。如果扩容那么相应的PG会进行迁移到新的OSD上,保证PG数量的均衡。
心跳机制
ceph 心跳检测
- OSD节点会监听public、cluster、front和back四个端口。
- public端口:监听来自Monitor和Client的连接。
- cluster端口:监听来自OSD Peer的连接。
- front端口:供客户端连接集群使用的网卡, 这里临时给集群内部之间进行心跳。
- back端口:供客集群内部使用的网卡。集群内部之间进行心跳。
- hbclient:发送ping心跳的messenger。
OSD之间相互心跳检测
- 同一个PG内OSD互相心跳,他们互相发送PING/PONG信息。
- 每隔6s检测一次(实际会在这个基础上加一个随机时间来避免峰值)。
- 20s没有检测到心跳回复,加入failure队列。
OSD与Mon心跳检测
OSD报告给Monitor:
- OSD有事件发生时(比如故障、PG变更)。
- 自身启动5秒内。
- OSD周期性的上报给Monito:
3.1 OSD检查failure_queue中的OSD失败信息。
3.2 向Monitor发送失效报告,并将失败信息加入failure_pending队列,然后将其从failure_queue移除。
3.3 收到来自failure_queue或者failure_pending中的OSD的心跳时,将其从两个队列中移除,并告知Monitor取消之前的失效报告。
3.4 当发生与Monitor网络重连时,会将failure_pending中的错误报告加回到failure_queue中,并再次发送给Monitor。- Monitor统计下线OSD:
4.1 Monitor收集来自OSD的失效报告。
4.2 当错误报告指向的OSD失效超过一定阈值,且有足够多的OSD报告其失效时,将该OSD下线。
Ceph通过OSD汇报失效节点和Monitor统计来自OSD的心跳两种方式判定OSD节点失效。
ceph通信框架
- Accepter监听peer的请求, 调用 SimpleMessenger::add_accept_pipe() 创建新的 Pipe 到 SimpleMessenger::pipes 来处理该请求。
- Pipe用于消息的读取和发送。该类主要有两个组件,Pipe::Reader,Pipe::Writer用来处理消息读取和发送。
- Messenger作为消息的发布者, 各个 Dispatcher 子类作为消息的订阅者, Messenger 收到消息之后, 通过 Pipe 读取消息,然后转给 Dispatcher 处理。
- Dispatcher是订阅者的基类,具体的订阅后端继承该类,初始化的时候通过 Messenger::add_dispatcher_tail/head 注册到 Messenger::dispatchers.
收到消息后,通知该类处理。- DispatchQueue该类用来缓存收到的消息, 然后唤醒 DispatchQueue::dispatch_thread 线程找到后端的 Dispatch 处理消息。
CRUSH算法
- CRUSH算法:(Controlled Scalable Decentralized Placement of Replicated Data),可控的、可扩展的、分布式的副本数据放置算法。
- pg到OSD的映射的过程算法叫做CRUSH 算法。(一个Object需要保存三个副本,也就是需要保存在三个osd上)。
- CRUSH算法是一个伪随机的过程,他可以从所有的OSD中,随机性选择一个OSD集合,但是同一个PG每次随机选择的结果是不变的,也就是映射的OSD集合是固定的。
CRUSH算法原理
CRUSH算法因子:层级化的Cluster Map、Placement Rules。
层级化的Cluster Map
- 树形结构,OSDMap更多记录的是OSDMap的属性(epoch/fsid/pool信息以及osd的ip等等)。
- 叶子节点是device(也就是osd),其他的节点称为bucket节点,这些bucket都是虚构的节点,可以根据物理结构进行抽象,当然树形结构只有一个最终的根节点称之为root节点,中间虚拟的bucket节点可以是数据中心抽象、机房抽象、机架抽象、主机抽象等。
Placement Rules(数据分布策略)
Bucket随机算法
- 一般的buckets:适合所有子节点权重相同,而且很少添加删除item。
- list buckets:适用于集群扩展类型。增加item,产生最优的数据移动,查找item,时间复杂度O(n)。 tree buckets:查找负责度是O (log n), 添加删除叶子节点时,其他节点node_id不变。
- straw buckets:允许所有项通过类似抽签的方式来与其他项公平“竞争”。定位副本时,bucket中的每一项都对应一个随机长度的straw,且拥有最长长度的straw会获得胜利(被选中),添加或者重新计算,子树之间的数据移动提供最优的解决方案。
ceph 官方QOS原理
(目前官方QOS模块属于半成品)
补充
- mClock是一种基于时间标签的I/O调度算法,最先被Vmware提出来的用于集中式管理的存储系统。(目前官方QOS模块属于半成品)。
相关文章:

ceph介绍、原理、架构、算法...个人学习记录
前言 之前公司安排出差支援非结构化项目,采用springcloud(redismysql数据冷热处理)s3escephkafka还涉及一些区块链技术等等…,在与大佬的沟通交流下对ceph产生了兴趣,私下学习记录一下;后续工作之余会采用上面相关技术栈手动实现不…...

Spring MVC源码解析——HandlerMapping(处理器映射器)
Sping MVC 源码解析——HandlerMapping处理器映射器1. 什么是HandlerMapping2. HandlerMapping2.1 HandlerMapping初始化2.2 getHandler解析3. getHandlerInternal()子类实现3.1 AbstractUrlHandlerMapping与AbstractHandlerMethodMapping的区别3.2 AbstractUrlHandlerMapping3…...

【Word/word2007】将标题第1章改成第一章
问题:设置多级列表没有其他格式选的解决办法和带来的插入图注解的问题,将标题第1章改成第一章的问题其他方案。 按照百度搜索的方法设置第一章,可以是没有相应的样式可以选。 那就换到编号选项 设置新的编号值 先选是 然就是变得很丑 这时打开…...

NLP预训练模型
Models Corpus RoBERTa: A Robustly Optimized BERT Pretraining Approach 与BERT主要区别在于: large mini-batches 保持总训练tokens数一致,使用更大的学习率、更大的batch size,adam β20.98\beta_20.98β20.98;dynamic ma…...

Typora上传文档图片链接失效的问题+PicGo布置图床在Github
文章目录typora图片链接失效原因PicGO开源图床布置先配置Github2.1先创建新仓库、用于存放图片2.2生成一个token,用picGo访问github3.下载picGo,并进行配置3.1 配置v4.1typora图片链接失效原因 因为你是保存在本地的,因此图片是不能访问,可以…...

win10安装oracle
文件放到最后。我的电脑是win11的,因为老师让写下安装笔记,在11上安装的时候没有截屏,所以在虚拟机上重新安装下吧。室友说要把文件夹放到c盘才能打开。我试了下,具体的是要把Oracle11g文件夹放到c盘根目录下。如果解压后不是这个…...

AQS为什么用双向链表?
首先,在AQS中,等待队列是通过Node类来表示的,每个Node节点包含了等待线程的信息以及等待状态。下面是Node类的部分源码:static final class Node {// 等待状态volatile int waitStatus;// 前驱节点volatile Node prev;// 后继节点…...
AtCoder Beginner Contest 292——A-E题讲解
蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提! Hello, 大家好哇!本初中生蒟蒻讲解一下AtCoder Beginner Contest 292这场比赛的A-E题! A题 原题 Problem Statement You are given a string SSS consisting of lo…...

(蓝桥真题)最长不下降子序列(权值线段树)
样例输入: 5 1 1 4 2 8 5 样例输出: 4 分析:看到这种对其中连续k个数进行修改的我们就应该想到答案是由三部分组成,因为求的是最长不下降子序列,那么我们可以找到一个最合适的断点i,使得答案是由区间[1…...
数据类型及参数传递
1.数据类型 java中的基本数据类型: 数值型: 整数型:byte short long int 浮点型:float double 布尔型: boolean字符串: char java中的引用数据类型: 数组(array) 类(class…...

永春堂1300系统开发|解析永春堂1300模式商城的五大奖项
电商平台竞争越来越激烈,各种营销方式也是层出不穷,其中永春堂1300营销模式,以其无泡沫和自驱动性强等特点风靡一时。在这套模式中,虽然单型价格差异较大,但各种奖励的设计,巧妙的兼顾了平台和所有会员的利…...

最近一年我都干了什么——反思!!
过去一年不管是学习方式还是心态上都和以往有了许多不同的地方,比较昏昏沉沉。最近慢慢找到状态了,就想赶紧记录下来。 学习 在学习新技术的过程中开始飘了,总感觉有了一些开发经验后就觉得什么都不用记,知道思路就行遇到了现场百…...
Docker学习(十七)save 和 export 命令的区别
Docker 中有两个命令可以将镜像导出为本地文件系统中的 tar 文件:docker save 和 docker export。尽管它们的作用类似,但它们之间有一个重要的区别。 1.使用方式的不同: docker save 的使用示例: docker save -o test.tar image…...

【数据结构初阶】详解“树”
目录 前言 1.树概念及结构 (1)树的概念 (2)树的名词介绍 (3)树的表示 编辑 2.二叉树概念及结构 (1)概念 (2)特殊的二叉树 (3࿰…...

20230304 CF855 div3 vp
Dashboard - Codeforces Round 855 (Div. 3) - Codeforces呃呃,评价是,毫无进步呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训…...

UML 时序图
时序图(Sequence Diagram)是显示对象之间交互的图,是按时间顺序排列的。 时序图中显示的是参与交互的对象及其对象之间消息交互的顺序。 时序图包括的建模元素主要有:对象(Actor)、生命线(Lif…...

详解进程 及 探查进程
进程的概念PCB是什么task_struct的作用如何执行进程进程的探查什么是bashps命令的使用(查看进程)创建进程探究父子进程进程的概念 简而言之,进程就是正在在执行的程序 之前说过,程序执行的第一步Windows是双击程序Linux是 ./ &a…...
汇编相关问题
汇编语言期末复习题DX:单项选择题 DU:多项选择题 TK:填空题 MC:名词解释 v JD:简答题 CXFX:程序分析题 CXTK:程序填空题 BC:编程题第1章:基础知识1、在汇编语言程序的开发…...
华为OD机试Golang解题 - 火星文计算 2 | 包含思路
华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典文章目录 华为Od必看系列使用说明本期题目…...
成功解决configure: error: the HTTP rewrite module requires the PCRE library
文章目录 前言问题复现问题解决思考环节总结前言 大家好,我是沐风晓月,本专栏是记录日常实验中的所有疑难杂症,教程的安装,程序的bug,甚至各类报错,如果你也遇到了困惑和问题,欢迎与我一起交流学习。 另外不要解决完问题就结束了,思考环节也要好好看看哦。 问题复现…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...