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

【ceph】分布式存储ceph

1 块存储,文件存储,对象存储

1.1 简介

image.pngimage.pngimage.png

  • 文件存储:分层次存储,文件存储在文件夹中;访问文件时系统需要知道文件所在的路径。

举例:企业部门之间运用网络存储器(NAS)进行文件共享。

  • 块存储:将数据拆分成块,并单独存储各个块,块是一段标准长度(块大小)的字节或比特。

举例:可用于绝大部分通用业务场景下的数据存储。

  • 对象存储:扁平结构,数据会被分解为称为“对象”的离散单元,并保持在单个存储空间中;通过API接口供客户端使用。

举例:AWS S3, 阿里云OSS

image.png

  • 直连式存储(Direct-Attached Storage,简称DAS)
  • 网络化存储(Fabric-Attached Storage,简称FAS);
  • 网络化存储根据传输协议又分为:网络接入存储(Network-Attached Storage,简称NAS)和存储区域网络(Storage Area Network,简称SAN)。

在DAS和SAN中,存储资源就像一块一块的硬盘,直接挂载在主机上,我们称之为块存储
而在NAS中,呈现出来的是一个基于文件系统的目录架构,有目录、子目录、孙目录、文件,我们称之为文件存储
文件存储的最大特点,就是所有存储资源都是多级路径方式进行访问的。
例如:C:\Program Files (x86)\Tencent\WeChat\WeChat.exe

  • 块存储,操作对象是磁盘。存储协议是SCSI、iSCSI、FC。以 SCSI 为例,主要接口命令有 Read/Write/Read Capacity/Inquiry 等等。
  • 文件存储,操作对象是文件和文件夹。存储协议是NFS、SAMBA(SMB)、POSIX等
  • **对象存储,主要操作对象是对象(Object)。存储协议是S3、Swift等。**以 S3 为例,主要接口命令有 PUT/GET/DELETE 等。接口命令非常简洁,没有那种目录树的概念

image.png

1.2 对象存储

对象存储中的数据组成
对象存储呈现出来的是一个“桶”(bucket),你可以往“桶”里面放“对象(Object)”。这个对象包括三个部分:Key、Data、Metadata

image.png

Key
可以理解文件名,是该对象的全局唯一标识符(UID)。
Key是用于检索对象,服务器和用户不需要知道数据的物理地址,也能通过它找到对象。这种方法极大地简化了数据存储。
下面这行,就是一个对象的地址范例:
image.png
看上去就是一个URL网址。如果该对象被设置为“公开”,所有互联网用户都可以通过这个地址访问它。
Data
也就是用户数据本体。这个不用解释了。
Metadata
Metadata叫做元数据,它是对象存储一个非常独特的概念。
元数据有点类似数据的标签,标签的条目类型和数量是没有限制的,可以是对象的各种描述信息。

举个例子,如果对象是一张人物照片,那么元数据可以是姓名、性别、国籍、年龄、拍摄地点、拍摄时间等。
image.png
元数据可以有很多
在传统的文件存储里,这类信息属于文件本身,和文件一起封装存储。而对象存储中,元数据是独立出来的,并不在数据内部封装。

元数据的好处非常明显,可以大大加快对象的排序,还有分类和查找。

对象存储的架构

对象存储的架构是怎样的呢?如下图所示,分为3个主要部分:
image.png
对象存储的简单架构示意图
OSD对象存储设备

  • 这是对象存储的核心,具有自己的CPU、内存、网络和磁盘系统。它的主要功能当然是存储数据。同时,它还会利用自己的算力,优化数据分布,并且支持数据预读取,提升磁盘性能。

MDS元数据服务器

  • 它控制Client和OSD的交互,还会管理着限额控制、目录和文件的创建与删除,以及访问控制权限。

Client客户端

  • 提供文件系统接口,方便外部访问。

根据上面的架构可以看出,对象存储系统可以是一个提供海量存储服务的分布式架构。

对象存储的优点

对象存储的优点很多,简单归纳如下:
容量无限大

  • 对象存储的容量是EB级以上。EB有多大?大家的硬盘普遍是TB级别。1EB约等于1TB的一百万倍,请自行脑补…
  • 对象存储的所有业务、存储节点采用分布式集群方式工作,各功能节点、集群都可以独立扩容。从理论上来说,某个对象存储系统或单个桶(bucket),并没有总数据容量和对象数量的限制。
  • 换句话说,只要你有足够的money,服务商就可以不停地往架构里增加资源,这个存储空间就是无限的。
  • 你可以根据自身需求购买相应大小的对象存储空间。如果需要调整大小,也是支持弹性伸缩的,你不要进行数据迁移和人工干预。

数据安全可靠

  • 对象存储采用了分布式架构,对数据进行多设备冗余存储(至少三个以上节点),实现异地容灾和资源隔离。
  • 根据云服务商的承诺,数据可靠性至少可以达到99.999999999%(不用数了,一共11个9)(强一致性)。这意味着,1000亿个文件里,每月最多只会有1个文件发生数据丢失。这比一个人被陨石击中的概率还要小143000倍。
  • 数据访问方面,所有的桶和对象都有ACL等访问控制策略,所有的连接都支持SSL加密,OBS系统会对访问用户进行身份鉴权。因为数据是分片存储在不同硬盘上的,所以即使有坏人偷了硬盘,也无法还原出完整的对象数据


对象存储的应用场景
目前国内有大量的云服务提供商,他们把对象存储当作云存储在卖。
他们通常会把存储业务分为3个等级,即标准型、低频型、归档型。对应的应用场景如下:

  • 标准类型:移动应用 | 大型网站 | 图片分享 | 热点音视频
  • 低频访问类型:移动设备 | 应用与企业数据备份 | 监控数据 | 网盘应用
  • 归档类型:各种长期保存的档案数据 | 医疗影像 | 影视素材


1.3 总结

下图简要的总结了三者之间的差异:

块存储文件存储对象存储
概念用高速协议连接专业主机服务器的一种存储方式使用文件系统,具有目录树结构将数据和元数据当作一个对象
速度低延迟(10ms),热点突出不同技术各有不同100ms~1s,冷数据
可分布性异地不现实可分布式,但有瓶颈分布并发能力高
文件大小大小都可以,热点突出适合大文件适合各种大小
接口driver,kernel modulePOSIXRestful API
典型技术SANGFS,FTP,NASSwift, Amazon S3
适合场景银行数据中心网络媒体文件存储

2 什么是ceph

众所周知,ceph是一种分布式存储系统,是有着“ceph之父”之称的Sage Weil读博期间的研究课题,项目诞生于2004年,在2006年基于开源协议开源了Ceph的源代码,在经过了数年的发展之后,已经成为了开源社区受关注较高的项目之一。
Ceph可以将多台服务器组成一个超大集群,把这些机器中的磁盘资源整合到一块儿,形成一个大的资源池(支持PB级别),然后按需分配给客户端应用使用。
ceph官网: https://ceph.com/
ceph官方文档(英文):https://docs.ceph.com/
ceph官方文档(中文):http://docs.ceph.org.cn/

根据官方网站上的信息,Cpeh的生态系统参加下图:
image.png
不难看出,图中列出的厂商或组织带有明显的云计算气息。

2.1 Ceph特点

  1. 支持三种 **对象存储,块存储,文件存储 **接口,称之为统一存储
  2. 采用CRUSH算法,数据分布均衡,并行度高,不需要维护固定的元数据结构
  3. 数据具有强一致性,确保所有副本写入完成后才返回确认,适合读多写少的场景
  4. 去中心化,没有固定的中心节点,集群扩展灵活

CRUSH需要集群的映射,并使用CRUSH映射在OSDs中伪随机存储和检索数据,数据在集群中均匀分布。

2.2 ceph缺点

  1. 去中心化的分布式解决方案,需要提前做好组件和节点部署规划设计
  2. ceph扩容时,由于其数据分布均衡的特性,会导致整个存储系统性能下降

2.3 Ceph相较于其他存储方案的优势

  1. CRUSH算法
    a. CURSH是ceph的两大创新之一(另一大就是去中心化),ceph摒弃了传统的集中式存储元数据寻址的方案,转而使用CRUSH算法计算的方式完成数据的寻址操作;
    b. crush算法有强大的扩展性(即高扩展性),理论上支持上千个存储节点规模。
  2. 高可用
    a. 数据副本数可以灵活调整;
    b. 可以通过crush算法指定副本的物理存放位置以分割故障域,支持数据强一致性;
    c. 支持多种故障场景自动尝试进行修复;
    d. 支持多份强一致性副本,副本能够垮主机、机架、机房、数据中心存放,安全可靠;
    e. 存储节点可以自管理、自动修复。无单点故障,容错性强
  3. 高性能
    a. 因为是多个副本,因此在读写操作时能够做到高度并行化,理论上,节点越多,整个cpeh集群的IOPS和吞吐量就越高;
    b. ceph客户端读写数据可直接与存储设备-OSD交互,在块存储和对象存储中无需元数据-MDS服务
  4. 特性丰富
    a. 支持三种存储接口:对象存储,块存储,文件存储,三种方式可一同使用
    b. 支持自定义接口,支持多种语言驱动

3 Ceph的三种存储接口(块设备、文件系统、对象存储)

Ceph可以一套存储系统同时提供块设备存储、文件系统存储和对象存储三种存储功能。没有存储基础的用户则比较难理解Ceph的块存储、文件系统存储和对象存储接口。该章节先让大家大体理解这三者在ceph的区别我们再去研究ceph的架构和原理。

3.1 Ceph的块设备存储接口

首先,什么是块设备?

块设备是i/o设备中的一类,是将信息存储在固定大小的块中,每个块都有自己的地址,还可以在设备的任意位置读取一定长度的数据。看不懂?那就暂且认为块设备就是硬盘或虚拟硬盘吧。

查看下Linux环境中的设备:


root@nb:~$ ls /dev/
/dev/sda/ dev/sda1 /dev/sda2 /dev/sdb /dev/sdb1 /dev/hda 
/dev/rbd1 /dev/rbd2 …

上面的/dev/sda、/dev/sdb和/dev/hda都是块设备文件,这些文件是怎么出现的呢?
当给计算机连接块设备(硬盘)后,系统检测的有新的块设备,该类型块设备的驱动程序就在/dev/下创建个对应的块设备设备文件,用户就可以通过设备文件使用该块设备了。

它们怎么有的叫 sda?有的叫 sdb?有的叫 hda?
以sd开头的块设备文件对应的是SATA接口的硬盘,而以hd开头的块设备文件对应的是IDE接口的硬盘。那SATA接口的硬盘跟IDE接口的硬盘有啥区别?你只需要知道,IDE接口硬盘已经很少见到了,逐渐被淘汰中,而SATA接口的硬盘是目前的主流。而sda和sdb的区别呢?当系统检测到多个SATA硬盘时,会根据检测到的顺序对硬盘设备进行字母顺序的命名。

怎么还有的叫 rbd1 和 rbd2 呢? rbd(rados block devices)
被你发现了,rbd就是我们压轴主角了。rbd就是由Ceph集群提供出来的块设备。可以这样理解,sda和hda都是通过数据线连接到了真实的硬盘,而rbd是通过网络连接到了Ceph集群中的一块存储区域,往rbd设备文件写入数据,最终会被存储到Ceph集群的这块区域中。

那么块设备怎么用呢?这里举个例子:
打个比方,一个块设备是一个粮仓,数据就是粮食。农民伯伯可以存粮食(写数据)了,需要存100斤玉米,粮仓(块设备)这么大放哪里呢,就挨着放(顺序写)吧。又需要存1000斤花生,还是挨着放吧。又需要存……

后来,农民伯伯来提粮食(读数据)了,他当时存了1000斤小麦,哎呀妈呀,粮仓这么大,小麦在哪里啊?仓库管理员找啊找,然后哭晕在了厕所……

新管理员到任后,想了个法子来解决这个问题,用油漆把仓库划分成了方格状,并且编了号,在仓库门口的方格那挂了个黑板,当农民伯伯来存粮食时,管理员在黑板记录,张三存了1000斤小麦在xx方格处。后来,农民伯伯张三来取粮食时,仓库管理员根据小黑板的记录很快提取了粮食。

故事到此为止了,没有方格和黑板的仓库(块设备)称为裸设备。由上例可见,裸设备对于用户使用是很不友好的,直接导致了旧仓库管理员的狗带。例子中划分方格和挂黑板的过程其实是在块设备上构建文件系统的过程,文件系统可以帮助块设备对存储空间进行条理的组织和管理,于是新管理员通过文件系统(格子和黑板)迅速找到了用户(农民伯伯张三)存储的数据(1000斤小麦)。针对多种多样的使用场景,衍生出了很多的文件系统。有的文件系统能够提供更好的读性能,有的文件系统能提供更好的写性能。我们平时常用的文件系统如xfs、ext4是读写性能等各方面比较均衡的通用文件系统。

能否直接使用不含有文件系统块设备呢?

可以的,xfs和ext4等通用的文件系统旨在满足大多数用户的存储需求,所以在数据存储的各方面的性能比较均衡。然而,很多应用往往并不需要这种均衡,而需要突出某一方面的性能,如小文件的存储性能。此时,xfs、ext4等通用文件系统如果不能满足应用的需求,应用往往会在裸设备上实现自己的数据组织和管理方式。简单的说,就是应用为了强化某种存储特性而实现自己定制的数据组织和管理方式,而不使用通用的文件系统

总结一下,块设备可理解成一块硬盘,用户可以直接使用不含文件系统的块设备,也可以将其格式化成特定的文件系统,由文件系统来组织管理存储空间,从而为用户提供丰富而友好的数据操作支持。

3.2 Ceph的文件系统存储接口

什么是Ceph的文件系统接口?

还记得上面说的块设备上的文件系统吗,用户可以在块设备上创建xfs文件系统,也可以创建ext4等其他文件系统。如图3.1,Ceph集群实现了自己的文件系统来组织管理集群的存储空间,用户可以直接将Ceph集群的文件系统挂载到用户机上使用。

image.png

图3.1 Ceph的块设备接口和文件系统接口对比
image.pngimage.png
块存储和文件存储

Ceph有了块设备接口,在块设备上完全可以构建一个文件系统,那么Ceph为什么还需要文件系统接口呢?

主要是因为应用场景的不同,Ceph的块设备具有优异的读写性能,但不能多处挂载同时读写,目前主要用在OpenStack上作为虚拟磁盘,而Ceph的文件系统接口读写性能较块设备接口差,但具有优异的共享性

为什么Ceph的块设备接口不具有共享性,而Ceph的文件系统接口具有呢

对于Ceph的块设备接口,如图3.2,文件系统的结构状态是维护在各用户机内存中的,假设Ceph块设备同时挂载到了用户机1和用户机2,当在用户机1上的文件系统中写入数据后,更新了用户机1的内存中文件系统状态,最终数据存储到了Ceph集群中,但是此时用户机2内存中的文件系统并不能得知底层Ceph集群数据已经变化而维持数据结构不变,因此用户无法从用户机2上读取用户机1上新写入的数据。
因此不建议多个机器挂载ceph同一块设备
image.png
图3.2 Ceph块设备接口共享性

对于Ceph的文件系统接口,如图3.3,文件系统的结构状态是维护在远端Ceph集群中的,Ceph文件系统同时挂载到了用户机1和用户机2,当往用户机1的挂载点写入数据后,远端Ceph集群中的文件系统状态结构随之更新,当从用户机2的挂载点访问数据时会去远端Ceph集群取数据,由于远端Ceph集群已更新,所有用户机2能够获取最新的数据。

image.png
图3.3 Ceph文件系统接口共享性

Ceph的文件系统接口使用方式?

将Ceph的文件系统挂载到用户机目录


/* 保证/etc/ceph目录下有Ceph集群的配置文件ceph.conf和ceph.client.admin.keyring */mkdir -p /mnt/ceph_fuse ceph-fuse /mnt/ceph_fuse

大功告成,在/mnt/ceph_fuse下读写数据,都是读写远程Ceph集群

总结一下,Ceph的文件系统接口弥补了Ceph的块设备接口在共享性方面的不足,Ceph的文件系统接口符合POSIX标准,用户可以像使用本地存储目录一样使用Ceph的文件系统的挂载目录。还是不懂?这样理解吧,无需修改你的程序,就可以将程序的底层存储换成空间无限并可多处共享读写的Ceph集群文件系统。

3.3 Ceph的对象存储接口

首先,通过图4来看下对象存储接口是怎么用的?

简单了说,使用方式就是通过http协议上传下载删除对象(文件即对象)。
image.png
图4 对象存储接口的使用方式
image.png

老问题来了,有了块设备接口存储和文件系统接口存储,为什么还整个对象存储呢?
往简单了说,Ceph的块设备存储具有优异的存储性能但不具有共享性,而Ceph的文件系统具有共享性然而性能较块设备存储差,为什么不权衡一下存储性能和共享性,整个具有共享性而存储性能好于文件系统存储的存储呢,对象存储就这样出现了。

对象存储为什么性能会比文件系统好?
原因是多方面的,主要原因是:

  • 对象存储组织数据的方式相对简单,只有bucket和对象两个层次(对象存储在bucket中),对对象的操作也相对简单。
  • 而文件系统存储具有复杂的数据组织方式,目录和文件层次可具有无限深度,对目录和文件的操作也复杂的多,因此文件系统存储在维护文件系统的结构数据时会更加繁杂,从而导致文件系统的存储性能偏低。

Ceph的对象存储接口怎么用呢?
Ceph的对象接口符合亚马逊S3接口标准和OpenStack的Swift接口标准,可以自行学习这两种接口。

总结一下,文件系统存储具有复杂的数据组织结构,能够提供给用户更加丰富的数据操作接口,而对象存储精简了数据组织结构,提供给用户有限的数据操作接口,以换取更好的存储性能。对象接口提供了REST API,非常适用于作为web应用的存储。

对象存储适用于多读少写场景。提供写入、读取、删除三个接口。

3.4 总结

概括一下,块设备速度快,对存储的数据没有进行组织管理,但在大多数场景下,用户数据读写不方便(以块设备位置offset + 数据的length来记录数据位置,读写数据)。而在块设备上构建了文件系统后,文件系统帮助块设备组织管理数据,数据存储对用户更加友好(以文件名来读写数据)。Ceph文件系统接口解决了“Ceph块设备+本地文件系统”不支持多客户端共享读写的问题,但由于文件系统结构的复杂性导致了存储性能较Ceph块设备差。对象存储接口是一种折中,保证一定的存储性能,同时支持多客户端共享读写。

4 ceph的架构

4.1 ceph核心架构组件

支持三种接口:

  • Object:有原生的API,而且也兼容Swift和S3的API。
  • Block:支持精简配置、快照、克隆。
  • File:Posix接口,支持快照。

image.png
image.png
官方原架构图请看https://docs.ceph.com/en/latest

由上图所示,自下往上,逻辑上可以分为四个层次:

  1. 基础存储系统RADOS(Reliable Autonomic Object Store,可靠、自动、分布式对象存储)

RADOS是ceph存储集群的基础,这一层本身就是一个完整的对象存储系统。Ceph的高可靠、高可扩展、高性能、高自动化等等特性本质上也都是由这一层所提供的,在ceph中,所有数据都以对象的形式存储,并且无论什么数据类型,RADOS对象存储都将负责保存这些对象,确保了数据一致性和可靠性。RADOS系统主要由两部分组成,分别是OSD(对象存储设备)和Monitor(监控OSD)

  1. 基础库LIBRADOS

LIBRADOS基于RADOS之上,它允许应用程序通过访问该库来与RADOS系统进行交互,支持多种编程语言,比如C、C++、Python等。

  1. 上层接口RADOSGW、RBD和CEPHFS

基于LIBRADOS层开发的三个接口,其作用是在librados库的基础上提供抽象层次更高、更便于应用或客户端使用的上层接口。

  • RADOS GW(简称RGW)提供对象存储服务,是一套基于RESTFUL协议的网关,支持对象存储,兼容S3和Swift
  • RBD提供分布式的块存储设备接口,主要面向虚拟机提供虚拟磁盘,可以被映射、格式化,像磁盘一样挂载到服务器使用。
  • CephFS是一个POSIX兼容的分布式文件系统,依赖MDS来跟踪文件层次结构,基于librados封装原生接口,它跟传统的文件系统如 Ext4 是一个类型的,但区别在于分布式存储提供了并行化的能力,像NFS等也是属于文件系统存储。

PS:两个对象的区分,需要说明下,这里提到两个对象的概念。一个是RGW中的对象存储;一个是Ceph 的后端存储的对象,这两个需要区分:

  • 第一个对象面向用户,是用户接口能访问到的对象;
  • 第二个对象是ceph 服务端操作的对象


eg:使用RGW接口,存放一个1G的文件,在用户接口看到的就是存放了一个对象;而后通过RGW 分片成多个对象后最终存储到磁盘上;

RGW为RADOS Gateway的缩写,ceph通过RGW为互联网云服务提供商提供对象存储服务。RGW在librados之上向应用提供访问ceph集群的RestAPI,支持Amazon S3和openstack swift两种接口。对RGW最直接的理解就是一个协议转换层,把从上层应用符合S3或Swift协议的请求转换成rados的请求,将数据保存在rados集群中。

4.2 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
    CRUSH是Ceph使用的数据分布算法,类似一致性哈希,让数据分配到预期的地方。

  • RBD
    RBD全称RADOS** block device**,是Ceph对外提供的块设备服务。

  • RGW
    RGW全称RADOS gateway,是Ceph对外提供的对象存储服务,接口与S3和Swift兼容。

  • CephFS
    CephFS全称Ceph File System,是Ceph对外提供的文件系统服务。

4.2.1 RADOS的系统逻辑结构

RADOS (Reliable, Autonomic Distributed Object Store) 是Ceph的核心之一,作为Ceph分布式文件系统的一个子项目,特别为Ceph的需求设计,能够在动态变化和异质结构的存储设备机群之上提供一种稳定、可扩展、高性能的单一逻辑对象(Object)存储接口和能够实现节点的自适应和自管理的存储系统。 在传统分布式存储架构中,存储节点往往仅作为被动查询对象来使用,随着存储规模的增加,数据一致性的管理会出现很多问题。而新型的存储架构倾向于将基本的块分配决策和安全保证等操作交给存储节点来做,然后通过提倡客户端和存储节点直接交互来简化数据布局并减小io瓶颈。

image.png628983 Ceph分布式存储学习指南-有书签.pdf

设计图来源于ceph官方RADOS文档:https://ceph.com/wp-content/uploads/2016/08/weil-rados-pdsw07.pdf
服务端 RADOS 集群主要由两种节点组成:

  • 一种是为数众多的、负责完成数据存储和维护功能的OSD(Object Storage Device);
  • 另一种则是若干个负责完成系统状态检测和维护的monitor,monitor是一些独立的进程,以及少量的本地存储,monitor之间通过一致性算法保证数据的一致性。

4.2.1 Cluster Map使用

  • 集群通过monitor集群操作cluster map来实现集群成员的管理。cluster map 描述了哪些OSD被包含进存储集群以及所有数据在存储集群中的分布。cluster map不仅存储在monitor节点,它被复制到集群中的每一个存储节点,以及和集群交互的client。当因为一些原因,比如设备崩溃、数据迁移等,cluster map的内容需要改变时,cluster map的版本号被增加,map的版本号可以使通信的双方确认自己的map是否是最新的,版本旧的一方会先将map更新成对方的map,然后才会进行后续操作。
  • 而RADOS也通过 cluster map来实现这些存储半自动化的功能,cluster map会被复制到集群中的所有部分(存储节点、控制节点,甚至是客户端),并且通过怠惰地传播小增量更新而更新。Cluster map中存储了整个集群的数据的分布以及成员。通过在每个存储节点存储完整的Cluster map,存储设备可以表现的半自动化,通过peer-to-peer的方式(比如定义协议)来进行数据备份、更新,错误检测、数据迁移等等操作。这无疑减轻了占少数的monitor cluster(管理节点组成的集群)的负担。

5 Ceph底层存储过程(Data Placement)

无论使用哪种存储方式(对象,块,文件),存储的数据当底层保存时,都会被切分成一个个大小固定的对象(Objects),对象大小可以由管理员自定义调整,RADOS中基本的存储单位就是Objects,一般为2MB或4MB(最后一个对象大小有可能不同)(文件9M, 4M 4M 1M) (1024TB -> PB , 1024PB -> EB )。

如上图,一个个文件(File)被切割成大小固定的Objects后,将这些对象分配到一个PG(Placement Group)中,然后PG会通过多副本的方式复制几份,随机分派给不同的存储节点(也可指定)。

当新的存储节点(OSD)被加入集群后,会在已有数据中随机抽取一部分数据迁移到新节点,这种概率平衡的分布方式可以保证设备在潜在的高负载下正常工作,更重要的事,数据的分布过程仅需要做几次随机映射,不需要大型的集中式分配表,方便且快速,不会对集群产生大的影响。

5.1 逻辑概念说明

上图两侧逻辑概念词的含义:

  • File:用户需要存储或者访问的文件
  • Objects:RADOS的基本存储单元,即对象。 Object与上面提到的file的区别是,object的最大size由RADOS限定(通常为2MB或4MB),以便实现底层存储的组织管理。以便实现底层存储的组织管理。因此,当上层应用向RADOS存入size很大的file时,需要将file切分成统一大小的一系列object进行存储。
  • PG(Placement Group):英文直译过来即为放置组,所以这里PG作用是对object的存储进行组织和位置映射,它是一个逻辑概念,在Linux系统中可以直接看到对象,但是无法直接看到PG,它在数据寻址中类似于数据库中的索引。用来放置若干个object(可以数千个甚至更多),但一个object只能被映射到一个PG中,即,PG和object之间是“一对多”的映射关系。同时,一个PG会被映射到n个OSD上,而每个OSD上都会承载大量的PG,即,PG和OSD之间是“多对多”映射关系。在实践当中,n至少为2(n代表冗余的份数),如果用于生产环境,则至少为3。一个OSD上的PG则可达到数百个。
  • OSD(object storage device):前文已详细说明,不再赘述,不过osd数量关系到系统的数据分布均匀性和性能问题,所以也不能太少。
  • oid 每个object都会有一个唯一的OID,由ino和ono生成。ino即文件的File ID,用于在全局唯一标识每一个文件,ono则是分片编号(对象编号)。例如:一个文件FileID为A,被切割为对象编号是A0,A1的两个对象。
  • pgid 使用静态hash函数对OID做hash去除特征码,用特征码与PG的数量去模,得到的序号即是PGID,由于这种设计方式,所以PG数量的多少会直接决定了数据分布的均匀性,所以需要合理设置PG的数量可以很好的提升CEPH集群的性能并使数据均匀分布。

5.2 存储过程中各层次之间的映射关系

  • file -> object
    object的最大size是由RADOS配置的,当用户要存储一个file,需要将file切分成若干个object。
  • object -> PG
    每个object都会被映射到一个PG中,然后以PG为单位进行副本备份以及进一步映射到具体的OSD上。
  • PG -> OSD
    通过CRUSH算法来实现,根据用户设置的冗余存储的个数r,PG会最终存储到r个OSD上。

5.3 存储过程具体说明

用户通过客户端存储一个文件时,在RAODS中,该File(文件)会被分割为多个2MB/4MB大小的 Objects(对象)。而每个文件都会有一个文件ID,例如A,那么这些对象的ID就是A0,A1,A2等等。然而在分布式存储系统中,有成千上万个对象,只是遍历就要花很久时间,所以对象会先通过hash-取模运算,存放到一个PG中。
PG相当于数据库的索引(PG的数量是固定的,不会随着OSD的增加或者删除而改变),这样只需要首先定位到PG位置,然后在PG中查询对象即可。之后PG中的对象又会根据设置的副本数量进行复制,并根据CRUSH算法存储到OSD节点上。

5.4 为什么引入PG概念?

因为Object对象的size很小,并不会直接存储进OSD中,在一个大规模的集群中可能会存在几百到几千万个对象,这么多对象如果遍历寻址,那速度是很缓慢的,并且如果将对象直接通过某种固定映射的哈希算法映射到osd上,那么当这个osd损坏时,对象就无法自动迁移到其他osd上(因为映射函数不允许)。为了解决这些问题,ceph便引入了归置组的概念,即PG。
最后PG会根据管理设置的副本数量进行副本级别的复制,然后通过CRUSH算法存储到不同的osd上(其实是把PG中的所有对象存储到节点上),第一个osd节点即为主节点,其余均为从节点。

6 Ceph IO流程及数据分布

image.png
线上应用,分布式文件系统,建议3个存储,存3份。

6.1 正常IO流程图

image.png
步骤:

  1. client 创建cluster handler。
  2. client 读取配置文件。
  3. client 连接上monitor,获取集群map信息。
  4. client 读写io 根据crshmap 算法请求对应的主osd数据节点。
  5. 主osd数据节点同时写入另外两个副本节点数据。
  6. 等待主节点以及另外两个副本节点写完数据状态。
  7. 主节点及副本节点写入状态都成功后,返回给client,io写入完成。

## 6.2 新主IO流程图 **说明:**
如果新加入的OSD1取代了原有的 OSD成为 Primary OSD, 由于 OSD1 上未创建 PG , 不存在数据,那么 PG 上的 I/O 无法进行,怎样工作的呢?

image.png
步骤

  1. client连接monitor获取集群map信息。
  2. 同时新主osd1由于没有pg数据会主动上报monitor告知让osd2临时接替为主。
  3. 临时主osd2会把数据全量同步给新主osd1。
  4. client IO读写直接连接临时主osd2进行读写。
  5. osd2收到读写io,同时写入另外两副本节点。
  6. 等待osd2以及另外两副本写入成功。
  7. osd2三份数据都写入成功返回给client, 此时client io读写完毕。
  8. 如果osd1数据同步完毕,临时主osd2会交出主角色。
  9. osd1成为主节点,osd2变成副本。

6.3 Ceph IO算法流程

image.png

  1. File用户需要读写的文件。File->Object映射:
  • a. ino (File的元数据,File的唯一id)。
  • b. ono(File切分产生的某个object的序号,默认以4M切分一个块大小)。
  • c. oid(object id: ino + ono)。
  1. Object是RADOS需要的对象。Ceph指定一个静态hash函数计算oid的值,将oid映射成一个近似均匀分布的伪随机值,然后和mask按位相与,得到pgid。Object->PG映射:
  • a. hash(oid) & mask-> pgid 。
  • b. mask = PG总数m(m为2的整数幂)-1 。
  1. PG(Placement Group),用途是对object的存储进行组织和位置映射, (类似于redis cluster里面的slot的概念) 一个PG里面会有很多object。采用CRUSH算法,将pgid代入其中,然后得到一组OSD。PG->OSD映射:
  • a. CRUSH(pgid)->(osd1,osd2,osd3) 。

6.4 Ceph IO伪代码流程

locator = object_name
obj_hash = hash(locator)
pg = obj_hash % num_pg
osds_for_pg = crush(pg) # returns a list of osds
primary = osds_for_pg[0]
replicas = osds_for_pg[1]

6.5 Ceph RBD IO流程

image.png
步骤:

  1. 客户端创建一个pool,需要为这个pool指定pg的数量。
  2. 创建pool/image rbd设备进行挂载。
  3. 用户写入的数据进行切块,每个块的大小默认为4M,并且每个块都有一个名字,名字就是object+序号。
  4. 将每个object通过pg进行副本位置的分配。
  5. pg根据cursh算法会寻找3个osd,把这个object分别保存在这三个osd上。
  6. osd上实际是把底层的disk进行了格式化操作,一般部署工具会将它格式化为xfs文件系统。
  7. object的存储就变成了存储一个文rbd0.object1.file。

6.6 Ceph RBD IO框架图

image.png

客户端写数据osd过程:

  1. 采用的是librbd的形式,使用librbd创建一个块设备,向这个块设备中写入数据。
  2. 在客户端本地同过调用librados接口,然后经过pool,rbd,object、pg进行层层映射,在PG这一层中,可以知道数据保存在哪3个OSD上,这3个OSD分为主从的关系。
  3. 客户端与primay OSD建立SOCKET 通信,将要写入的数据传给primary OSD,由primary OSD再将数据发送给其他replica OSD数据节点。

6.7 Ceph Pool和PG分布情况

image.png

说明:

  • pool是ceph存储数据时的逻辑分区,它起到namespace的作用。
  • 每个pool包含一定数量(可配置)的PG。
  • PG里的对象被映射到不同的Object上。
  • pool是分布到整个集群的。
  • pool可以做故障隔离域,根据不同的用户场景不一进行隔离。

6.8 Ceph 数据扩容PG分布

每个PG对应一个主分区和两个备份分区。

场景数据迁移流程:

  • 现状3个OSD, 4个PG
  • 扩容到4个OSD, 4个PG

现状:
image.png
PGa -> osd1 2 3
PGb -> osd1 2 3
PBc -> osd1 2 3
PBd -> osd1 2 3

扩容后:

image.png
PGa -> osd 2 3 4
PGb -> osd 1 2 4
PBc -> osd 1 3 4
PBd -> osd 1 2 3

说明
每个OSD上分布很多PG, 并且每个PG会自动散落在不同的OSD上。如果扩容那么相应的PG会进行迁移到新的OSD上,保证PG数量的均衡。

7 ceph集群搭建测试

ceph如果要搭建(使用centos,官方支持,红帽 centos ceph)

8 Ceph,TFS,FastDFS,MogileFS,MooseFS,GlusterFS 对比

对比说明
/文件系统
TFSFastDFSMogileFSMooseFSGlusterFSCeph
开发语言C++CPerlCCC++
开源协议GPL V2GPL V3GPLGPL V3GPL V3LGPL
数据存储方式文件/Trunk文件文件/块对象/文件/块
集群节点通信协议私有协议(TCP)私有协议(TCP)HTTP私有协议(TCP)私有协议(TCP)/ RDAM(远程直接访问内存)私有协议(TCP)
专用元数据存储点占用NS占用DB占用MFS占用MDS(元数据服务)
在线扩容支持支持支持支持支持支持
冗余备份支持支持-支持支持支持
单点故障存在存在存在存在存在存在
跨集群同步支持部分支持--支持不适用
易用性安装复杂,官方文档少安装简单,社区相对活跃-安装简单,官方文档多安装简单,官方文档专业化安装简单,官方文档专业化
适用场景跨集群的小文件单集群的中小文件-单集群的大中文件跨集群云存储单集群的大中小文件

9 参考

块存储、文件存储、对象存储意义及差异 https://www.cnblogs.com/hukey/p/8323853.html
“Ceph浅析”之三——Ceph的设计思想 https://zhuanlan.zhihu.com/p/56087062
“CEPH浅析”系列
关于存储技术的最强入门科普
https://mp.weixin.qq.com/s?__biz=MzI1NTA0MDUyMA==&mid=2456671031&idx=1&sn=6dab8b39023f4586ba628a8a261a7770&chksm=fda57e50cad2f746cca855d6d3d4b1c2ab9cd56a5d2fc7b882358bf5c63b29f9165e1992b8de&scene=21#wechat_redirect
一篇文章让你理解Ceph的三种存储接口(块设备、文件系统、对象存储) https://blog.csdn.net/wangmingshuaiguo/article/details/92628036

相关文章:

Converge: QoE-driven Multipath Video Conferencing over WebRTC 概略

这是一片2023sigcomm的文章。 论文指出多摄像头(multiple camera)和高分辨率(high resolution)场景下,视频会议的QoE还有提升空间,而作者将提升QoE的目光转到多路传输(multipath)上。所以总体来看这是一篇利用多路传输来优化视频会议体验的文章。 常用的多路协议包括MPT…...

【经验总结】Ubuntu 源代码方式安装 Microsoft DeepSpeed

1. 背景介绍 使用 DeepSpeed 在多服务器上分布式训练大模型 2. 安装方法 2.1 查看显卡参数 ~$ CUDA_VISIBLE_DEVICES0 python -c "import torch; print(torch.cuda.get_device_capability())" (8, 0) ~$ CUDA_VISIBLE_DEVICES0 python -c "import torch; pr…...

Java高级阶段面试题库(Redis数据库、MQ消息队列、kafka、SpringBoot + SpringCloud、MySQL、JVMJUC、其它)

文章目录 1. Redis数据库篇(忽略)1.1 简单介绍一下redis1.2 单线程的redis为什么读写速度快?1.3 redis为什么是单线程的?1.4 redis服务器的的内存是多大?1.5 为什么Redis的操作是原子性的,怎么保证原子性的?1.6 你还用过其他的缓存吗?这些…...

顺序表???

/******************************************************************************************************** * * * 提高可移植性 * * * * Copyright (c) 2023-2024 cececlmx@126.com All right Reserved * ********************************************************…...

贪心算法练习day.4

860.柠檬水找零 链接:. - 力扣(LeetCode) 题目描述: 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。 每位顾客只买一…...

QFD赋能人工智能:打造智能化需求分析与优化新纪元

在科技飞速发展的今天,人工智能(AI)已经渗透到我们生活的方方面面。然而,如何让AI更加贴合用户需求,提供更加精准和个性化的服务?这成为了一个亟待解决的问题。质量功能展开(Quality Function Deployment,简…...

【ceph】分布式存储ceph

1 块存储,文件存储,对象存储 1.1 简介 文件存储:分层次存储,文件存储在文件夹中;访问文件时系统需要知道文件所在的路径。 举例:企业部门之间运用网络存储器(NAS)进行文件共享。 …...

Spring框架(九):Spring注解开发Annotation

Spring注解开发引子如何用注解替代xml基础配置Bean可以加一些注解来实现原有的xml文件的功能Component注解及其衍生注解依赖注入AutowireSpring非自定义的注解开发Spring其他注解注解的原理解析-xml方式注解的原理解析-注解方式引子 痛定思痛,主要问题出现在自己雀…...

python隶属关系图模型:基于模型的网络中密集重叠社区检测方法

隶属关系图模型 是一种生成模型,可通过社区联系产生网络。下图描述了一个社区隶属关系图和网络的示例(图1)。最近我们被客户要求撰写关于社区检测的研究报告,包括一些图形和统计输出。 图1.左:社区关系图(圆…...

Java实现猜数游戏

1 问题 编写一个Java程序,实现以下功能: 2 方法 首先导入java.util包下的Random,让程序随便分配给用户一个数。 再导入java.util包下的Scanner类,构建Scanner对象,以便输入。 利用Random().nextInt()生成一个随机的i…...

阿里云安装mysql、nginx、redis

目录 安装mysql 安装nginx ​编辑安装redis 先看一下系统基本信息 安装mysql rpm -qa | grep mariadb 卸载mariadb rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64 下载mysql源 wget -i http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm yum…...

毕业设计-基于机器视觉的行人车辆跟踪出入双向检测计数

目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科…...

linux 安装nginx

1.安装依赖包 //一键安装上面四个依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 2.下载并解压安装包 /或上传解压包 //创建一个文件夹 cd /usr/local mkdir nginx cd nginx //下载tar包 wget http://nginx.org/download/nginx-1.13.7.tar.gz t…...

javaee之黑马旅游网1

这是一个用来锻炼javaweb基础知识的项目,先来导入一些我们准备好的文件 下面这些东西是我们项目必备的,我们提前准备好了 ,这个我会上传到我的资源,你们可以自己去下载 利用maven来创建一个项目 选择无骨架创建项目,域…...

【高并发基础】理解 MVCC 及提炼实现思想

文章目录1. 前言2. MVCC 概念2.1 MVCC 版本链2.2 MVCC trx_id2.3 MVCC Read View3. 提出问题4. 解决问题4.1 不读未提交的数据4.1.1 一般的并发情况4.1.2 特殊的并发情况4.1.3 剩下的并发情况4.2 如果自己修改了数据,要第一时间读到5. MySQL RC 使用 MVCC5.1 MVCC D…...

Flow-vue源码中的应用

认识 Flow Flow 是 facebook 出品的 JavaScript 静态类型检查工具。Vue.js 的源码利用了 Flow 做了静态类型检查,所以了解 Flow 有助于我们阅读源码。 #为什么用 Flow JavaScript 是动态类型语言,它的灵活性有目共睹,但是过于灵活的副作用…...

学习python第一天(数据类型)

关于Python的数据类型 Python数据类型包括: 数字类型,字符类型,布尔类型,空类型,列表类型,元组类型,字典类型 1、数字类型 包括:整型int 浮点型float(有小数位的都是是浮点型) 注…...

echarts:nuxt项目使用echarts

一、项目环境 nuxt 2.X vue2.X vuex webpack 二、安装 yarn add echarts 三、使用 3.1、plugins目录下创建echarts.js import Vue from vue import * as echarts from echarts // 引入echarts Vue.prototype.$echarts echarts // 引入组件(将echarts注册为全…...

认证服务-----技术点及亮点

大技术 Nacos做注册中心 把新建的微服务注册到Nacos上去 两个步骤 在配置文件中配置应用名称、nacos的发现注册ip地址,端口号在启动类上用EnableDiscoveryClient注解开启注册功能 使用Redis存验证码信息 加入依赖配置地址和端口号即可 直接注入StringRedisTempla…...

【计算机毕业设计】74.家教平台系统源码

一、系统截图(需要演示视频可以私聊) 摘 要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐…...

Hbase的SQL接口之Phoenix使用心得

PHOENIX 官方定义 A SQL layer over HBase delivered as a client-embedded JDBC drivertargeting low latency queries over HBase data 不同于Hive on HBase的方式,Phoenix将Query Plan直接使用HBaseAPI实现,目的是规避MapReduce框架,减少…...

Springboot萌宠社交分享系统的设计与实现hfdwz计算机毕业设计-课程设计-期末作业-毕设程序代做

Springboot萌宠社交分享系统的设计与实现hfdwz计算机毕业设计-课程设计-期末作业-毕设程序代做 【免费赠送源码】Springboot萌宠社交分享系统的设计与实现hfdwz计算机毕业设计-课程设计-期末作业-毕设程序代做本源码技术栈: 项目架构:B/S架构 开发语言…...

线性代数与解析几何——Part4 欧式空间 酉空间

线性代数与解析几何——Part4 欧式空间 & 酉空间 1. 欧氏空间 1. 定义 & 性质2. 内积表示与标准正交基3. 欧氏空间的同构4. 欧氏空间的线性变换5. 欧氏空间的子空间 2. 酉空间 1. 定义 & 性质2. 酉变换3. Hermite变换4. 规范变换 1. 欧氏空间 1. 定义 & 性质…...

带头双向循环链表的实现

目录前言节点声明链表的初始化尾插打印链表头插尾删头删查找节点指定位置插入指定位置删除链表销毁前言 之前讲过单链表的实现,在实现的过程中,我们会发现每次删除或者在前面插入节点的时候,都要提前保存上一个节点的地址。这样做十分麻烦&a…...

07【C语言 趣味算法】最佳存款方案(采用 从后往前 递推解决)

目录 一、前情回顾二、Problem:最佳存款方案2.1 Description of the problem2.2 Analysis of the problem2.3 Algorithm design2.4 The complete code and the results of the run(完整的代码 以及 运行结果)一、前情回顾 06【C语言 & 趣味算法】牛顿迭代法求方程根(可…...

游戏开发36课 cocoscreator scrollview优化

在cocoscreator内,ScrollView控件封装的挺完美的了,不过对于一些对性能要求比较高的场景,会存在问题,以top100排行榜排行榜举例子 1、应用卡顿甚至崩溃 按照官方用例使用ScrollView,插入100个玩家的item,理…...

屏幕开发学习 -- 迪文串口屏

一 前言 最近学习了一款基于图形化开发的屏幕,在摸索一周后,基本熟悉了这款产品的一个开发过程,今天给大家分享一下迪文串口屏的学习过程,有不足之处,还请见谅😁,包含了环境搭建和功能DEMO 二 …...

微机-------CPU与外设之间的数据传送方式

目录 一、无条件方式二、查询方式三、中断方式四、DMA方式一、无条件方式 外设要求:简单、数据变化缓慢。 外设被认为始终处于就绪状态。始终准备好数据或者始终准备好接收数据。 IN AL,数据端口 数据端口的地址通过CPU的地址总线送到地址译码器进行译码,同时该指令进行的是…...

从源码上解决rosdep update失败问题

(一)卸载官方的rosdep、rosdistro 卸载rosdistro # python2 sudo apt-get purge python-rosdistro# python3 sudo apt-get purge python3-rosdistro卸载rosdep # python2 sudo apt-get purge python-rosdep# python3 sudo apt-get purge python3-rosd…...

常用的shell命令

常用的shell命令 1、ls命令 功能:显示文件和目录的信息 ls 以默认方式显示当前目录文件列表 ls -a 显示所有文件包括隐藏文件 ls -l 显示文件属性,包括大小,日期,符号连接,是否可读写及是否可执行 ls -lh 显示文件的…...

新手入门SLAM必备资料

新手入门SLAM必备资料 文章目录 新手入门SLAM必备资料一、SLAM学习书籍1.必读经典2.有很多期,跟着会议一起出的文集3.入门书籍,简单实现及代码4.SLAM入门教材吐血推荐,对深入理解SLAM实质非常有帮助5.作者Joan Sola关于Graph-SLAM的教程,包含位姿变换、传感器模型、图优化以…...

如何选择和使用腾讯云服务器的方法新手教程

本文将介绍如何选择和使用腾讯云服务器的方法新手教程。云服务器能帮助快速构建更稳定、安全的应用,降低开发运维的难度和整体IT成本。腾讯云CVM云服务器提供多种类型的实例、操作系统和软件包。各实例中的 CPU、内存、硬盘和带宽可以灵活调整,以满足应用…...

亚马逊云科技re:Invent:Serverless是所有构想的核心

12月2日,2022亚马逊云科技re:Invent全球大会上,Amazon.com副总裁兼首席技术官Werner Vogels博士向开发者们展示了另一种可能。在一系列Serverless工具的帮助下,一些代码可以少写,因为未来你可能再也不需要写它们了。这恐怕是自云原…...

数据链路层(必备知识)

文章目录1、数据链路层的作用2、认识以太网<1>以太网帧格式<2>认识MAC地址<3>认识MTU<4>查看硬件地址和MTU3、ARP协议<1>什么是ARP协议<2>ARP数据报格式<3>ARP协议的工作机制4、其他重要协议或技术<1> DNS<2>NAT技术1、…...

【Spring系列】- Spring循环依赖

Spring循环依赖 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 一个有梦有戏的人 怒放吧德德 &#x1f31d;分享学习心得&#xff0c;欢迎指正&#xff0c;大…...

Python学习基础笔记二十一——迭代器

列表&#xff0c;我们使用for循环来取值&#xff0c;我们把每个值都取到&#xff0c;不需要关心每一个值的位置&#xff0c;因为只能顺序的取值&#xff0c;并不能跳过任何一个去取其他位置的值。那么我们为什么可以使用for循环来取值&#xff0c;for循环内部是怎么工作的呢&am…...

【云原生之Docker实战】使用docker部署IT资产管理系统GLPI

【云原生之Docker实战】使用docker部署IT资产管理系统GLPI 一、GLPI介绍1.GLPI简介2.GLPI功能二、检查本地docker环境1.检查docker版本2.检查docker状态三、下载GLPI镜像四、编辑docker-compose.yaml文件五、部署GLPI系统1.创建数据目录2.使用docker compose创建容器应用3.查看…...

【SSM框架 二】Spring

文章目录二、Spring1、简介2、IOC理论思想3、Hello Spring4、IOC创建对象的方式4.1 无参构造构造器注入4.2 有参构造器注入5、Spring的配置5.1 别名5.2 Bean的配置5.3 import6、DI依赖注入6.1 构造方法注入6.2 set方法注入6.3 扩展注入6.4、Bean的作用域7、Bean的自动装配7.1 正…...

基于java+ssm+vue+mysql的社区流浪猫狗救助网站

项目介绍 随着迅速的发展&#xff0c;宠物饲养也较以前发生很大的变化&#xff0c;社区流浪猫狗救助网站系统以其独有的优势脱颖而出。“社区流浪猫狗救助网站”是以JAVA程序设计语言课为基础的设计出适合社区流浪猫狗救助网站&#xff0c;其开发过程主要包括后台数据库的建立…...

推特营销引流入门指南

一、关注 当您关注另一个Twitter用户时&#xff0c;您进行订阅&#xff0c;即可立即阅读其内容分享。因此&#xff0c;请评估您关注的人&#xff0c;尤其是刚开始时。跟踪新用户的一种简单方法是找到他们的个人资料&#xff0c;然后单击“关注”按钮。 Twitter对于那些疯狂点…...

Seata概述基础

分布式事务原因&#xff1a; 单体架构的spring事务不能跨机器&#xff0c;不能跨数据源 分布式事务的概念&#xff1a; 一个业务流程&#xff0c;在分布式系统&#xff08;微服务&#xff09;中&#xff0c;每个业务模块都是一个分支&#xff0c;保证每个业务分支一起成功&am…...

Python学习基础笔记二十二——生成器

一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值&#xff0c;但是yield又不同于return&#xff0c;return的执行意味着程序的结束&#xff0c;调用生成器函数不会得到返回的具体的值&#xff0c;而是得到一个可迭代的对象。每一次获取这个可迭代对…...

python -- PyQt5(designer)中文详细教程(四)事件和信号

事件 signals and slots也 被其他⼈翻译成信号和槽机制。 所有的应用都是事件驱动的。事件大部分都是由用户的行为产⽣的&#xff0c;当然也有其他的事件产生方式&#xff0c;比如网络的连接&#xff0c;窗口管理器或者定时器等。调⽤应⽤的exec_()⽅法时&#xff0c;应⽤会进⼊…...

你绝对想象不到的端对端通信的几种方式

一、前言 今天要和大家说的是我们常用的一些端对端的通信方式&#xff0c;这里我们会以python和php语言为主&#xff0c;举例说明客户端、浏览器端和服务器端通信&#xff0c;部分代码可能展示不全&#xff0c;不过我会放在文末链接供大家下载测试&#xff0c;下面我们先来让大…...

序列化--Serial

序列化&#xff1a;将数据结构或对象转换成二进制串的过程。 反序列化&#xff1a;将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程。 Parcelable 与 Serializeable 的区别 SerializableParcelable通过IO对硬盘操作&#xff0c;速度较慢直接在内存操作&#x…...

BDD - SpecFlow ExternalData Plugin 导入外部测试数据

BDD - SpecFlow ExternalData Plugin 导入外部测试数据引言SpecFlow ExternalData 插件支持的数据源Tags实践创建一个 Class Libary Project添加 NuGet Packages添加测试数据源文件CSV 文件Excel 文件添加 Feature 文件实现 Step Definition执行Scenario 导入测试数据源Scenari…...

[Power Query] 日期和时间处理

Power Query查询编辑器为日期和时间数据提供了强大而快捷的处理方式 例1: 从日期中提取年、月份、日、季度、周、天等信息 数据源 步骤1:将数据源导入到Power BI Desktop&#xff0c;单击【转换数据】选项&#xff0c;进入Power Query查询编辑器界面 步骤2:选中"日期&qu…...

设计模式之抽象工厂模式

利用反射技术简单梳理抽象工厂模式 工厂模式实现 通常我们在实际工作中&#xff0c;经常遇到需要访问数据库的场景。 而常见的数据库又多种多样&#xff0c;怎么样针对不同的数据库来建立不同的数据库连接呢&#xff1f; 我们可以看下用抽象工厂模式加上反射技术来如何实现。…...

JavaWeb_第5章_会话技术_Cookie+Session

JavaWeb_第5章_会话技术_CookieSession 文章目录JavaWeb_第5章_会话技术_CookieSession1&#xff0c;会话跟踪技术的概述2&#xff0c;Cookie2.1 Cookie的基本使用2.2 Cookie的原理分析2.3 Cookie的使用细节2.3.1 Cookie的存活时间2.3.2 Cookie存储中文3&#xff0c;Session3.1…...

跟着实例学Go语言(一)

本教程全面涵盖了Go语言基础的各个方面。一共80个例子&#xff0c;每个例子对应一个语言特性点&#xff0c;非常适合新人快速上手。 教程代码示例来自go by example&#xff0c;文字部分来自本人自己的理解。 本文是教程系列的第一部分&#xff0c;共计20个例子、约1万字。 目…...

数据库基础 - 数据类型、关键字、cmd中操作数据库的命令

cmd中操作数据库的命令 mysql -hlocalhost -用户名 -密码 show database&#xff1b;查询数据库中的小数据库 show 数据库名&#xff1b;查询某一个小数据库 show 表名&#xff1b;查询表的结构 exit 退出数据类型 数值类型 int &#xff1a;整形 double&#xff1a;双精度&…...

2022SDNU-ACM结训赛题解

首先感谢一下各位出题人的精心准备、验题人的辛勤付出、以及选手的积极参加 题解 Problem A 柳予欣的归来【数学】 出题人&#xff1a; bhq 没想到一血是被打完山大的牛客比赛后来结训赛玩的wyx拿走的&#xff01; 题目描述&#xff1a; 计算(∑0<d<pd−1)m(\sum_{0…...

《人类简史》笔记三—— 历史从无正义

目录 一、尽管把人人生而平等喊得震天响&#xff0c;其实还是把人分成了上下等级 二、恶性循环 三、当男人究竟有什么好的&#xff1f; 一、尽管把人人生而平等喊得震天响&#xff0c;其实还是把人分成了上下等级 古时候&#xff1a; 上等人 平民和奴隶 现在&#xff1a;…...

Python实现基于用户的协同过滤推荐算法构建电影推荐系统

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 基于用户的协同过滤推荐&#xff08;User-based CF&#xff09;的原理假设&#xff1a;跟你喜好相似的人…...

阿里巴巴专场——第322场周赛题解

目录 模拟法&#xff1a;6253.回环句 排序后模拟&#xff1a;6254. 划分技能点相等的团队 BFS&#xff1a;6255. 两个城市间路径的最小分数 BFS&#xff1a;6256. 将节点分成尽可能多的组 模拟法&#xff1a;6253.回环句 这道题直接按照题目的意思暴力模拟即可&#xff1a;…...

【机器学习】支持向量回归

有任何的书写错误、排版错误、概念错误等&#xff0c;希望大家包含指正。 在阅读本篇之前建议先学习&#xff1a; 【机器学习】支持向量机【上】硬间隔 【机器学习】支持向量机【下】软间隔与核函数 支持向量回归 支持向量回归&#xff08;support vector regression&#xf…...

C++设计模式探讨(2)-单例模式

介绍 这段介绍来自网络&#xff1a; 单例模式是一种创建型的软件设计模式&#xff0c;在工程项目中非常常见。通过单例模式的设计&#xff0c;使得创建的类在当前进程中只有一个实例&#xff0c;并提供一个全局性的访问点&#xff0c;这样可以规避因频繁创建对象而导致的内存…...

JavaAPI操作hdfs

12.JavaAPI操作hdfs 1&#xff09;下载maven 解压 2&#xff09;配置环境变量 使用这个目录来放本地的jar包 我们在maven下新建一个名为repositories的文件夹 复制其路径添加到下面的文件位置 3&#xff09;下面我们打开idea 新建工程 输入组id 工程名 版本号 名字可以随便起…...

轮转数组(Leedcode)的题目

题目&#xff1a;给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步…...

【k8s】(二)kubernetes1.29.4离线部署之-镜像文件准备

备注&#xff1a; 完整版请参阅 【k8s】Kubernetes 1.29.4离线安装部署&#xff08;总&#xff09; 离线镜像文件准备 **注意&#xff1a; **离线安装需要准备大量的镜像&#xff0c;这一步千万要仔细否则会出现各种意想不到的问题 需要准备的镜像文件 kube-apiserverkube-con…...

蓝桥杯刷题-计算系数

本文自用&#xff0c;用作记录。 211. 计算系数 - AcWing题库 #include <bits/stdc.h>using namespace std;int a, b, k ,n ,m; const int mod 10007; int qmi(int a, int k) {a % mod;int res 1;while (k){if (k & 1) res res * a % mod;a a * a % mod;k >…...

Vue3 + Js + Element-Plus + VueX后台管理系统通用解决方案

前言 本文是作为学习总结而写的一篇文章&#xff0c;也是方便以后有相关需求&#xff0c;可以直接拿来用&#xff0c;也算是记录吧&#xff0c;文中有一些文件的引入&#xff0c;没给出来&#xff0c;完整项目地址&#xff08;后续代码仓库放这里&#xff09; 1、layout解决方…...