Ceph分布式存储系统以及高可用原理

Ceph分布式存储系统以及高可用原理

  • 1. Ceph原理和架构
    • 1.1 分布式存储系统抽象
    • 1.2 Ceph基本组件
  • 2 Ceph中的策略层
    • 2.1 CRUSH进行数据分发和定位
    • 2.2 PG(Placement Group): 集群管理的基本单元
    • 2.3 PG的代理primary OSD
    • 2.4 轻量级的集群元数据ClusterMap
    • 2.5 对PG的罗辑分组:Pool
    • 2.6 集群自治
    • 2.7 良好的扩展性
    • 2.8 EC(Erasure Coding)编码的支持
  • 3. 多存储引擎的支持
  • 4. 三种接口简介
    • 4.1 RadowGW
    • 4.2 RBD
    • 4.3 CephFS
  • 5. 疑问和思考
  • 6. 参考文档

Ceph是目前开源社区中非常火的一款分布式存储系统。其最初是Sage Weil的博士课题,并且在2004-2006两年多的时间开发出Ceph的原型。2007年Sage博士毕业以后继续全职从事Ceph的开发工作。在2012年Sage创立了专门提供Ceph服务和技术支持的公司Inktank,并且在当年7月份发布了Ceph的第一个稳定版本V0.48.1(代号Argonaut,Ceph和许多开源软件一样,选择首字母从A ~ Z依次递增的单词作为稳定版本的代号)。当前最新的稳定版本是0.94.1(Hammer)。目前,Ceph社区非常活跃,基本保持每三到六个月发行一个稳定版本的速率。Redhat公司于2014年4月份以1.75亿美金的价格收购了Ceph开发团队。Ceph和其他存储系统最大的不同就是它同时为用户提供了块、对象以及Posix文件三种通用的存储接口,并且Ceph对OpenStack,Hadoop等开源平台也提供了内在的支持。早在2010年,Linus就将Ceph的Posix接口的客户端代码merge进了Linux内核,用户在不需要另外安装软件包就可以直接通过Ceph的Posix文件系统接口挂载使用Ceph。

和大多数的由GFS(Google File System)衍生出来的分布式存储系统相比,Ceph采用了无中心元数据服务器的架构,在诸多概念上有自己的创新,这篇文章就从原理和架构和相关概念上对Ceph进行一个梳理。

关于常见分布式组件高可用设计原理的理解和思考


1. Ceph原理和架构

1.1 分布式存储系统抽象

自2003年谷歌发布了GFS论文以后,分布式存储系统在互联网业内有了快速的发展和广泛的使用。应该说,分布式存储系统的出现很好的满足了互联网公司诸多应用场景下的数据存储的需求。数据是互联网公司非常宝贵的财富,在进行数据存储时,首先要考虑的是其高可靠性,也就是在正常情况下,写入的数据不会无故丢失。但是计算机设备和磁盘是有一定的故障率的,特别是互联网公司普遍使用的比较廉价的x86通用服务器。在实际应用中,各大公司保证数据高可靠性的方法通常有两种。第一,花钱省事,购买价钱比较昂贵的EMC,NetApp等公司的商业存储。第二,进行及时的数据备份。考虑到互联网公司数据量太大,并且增长快,如果采用第一种方式,想必是一笔非常大的开销。第二种方式是比较合,但是在分布式存储系统出现之前,通常是基于单机存储进行数据备份,数据的维护和管理比较繁琐和复杂,还有可能增加业务代码的复杂性(通常在业务层就考虑数据的备份)。谷歌GFS论文出来以后,给业界带来了很大的震动,一批有理想的程序员心想:其实也不复杂嘛,就是用一台机器作为管理机进行数据定位和集群管理,一批机器进行数据存储,并且让备份的过程自动化并且对用户透明。于是业界就很快出现了一批类GFS的分布式存储系统。比较有名的开源分布式存储系统有HDFS,MooseFS和淘宝TFS等。

然而Ceph和业内其它比较流行的类GFS分布式存储系统是不一样的,在结构上它没有类似GFS中单点的管理机,而是独树一帜,采用独特的哈希算法进行数据的定位以及存储节点分组的方式进行节点的自我管理。但是和其他分布式存储系统一样,它解决的最重要问题也是让数据的备份工作自动化,高效的保证数据的高可靠性。

总体来说,分布式存储系统解决的最重要的问题是将数据高效高可靠的存储在由通用硬件组成的计算机集群中。根据当前大多数分布式存储的设计和实现,我们可以抽象出分布式存储系统的三个层次,如图1所示:
在这里插入图片描述

  • 接口层:定义分布式存储系统怎样被客户来进行使用,比较通用的接口有Posix文件系统接口,块存储接口和对象接口。当然,许多的存储系统还定义了自己原生的API接口。

  • 策略层:定义数据通过接口层写入系统时,系统本身要采用相应的策略对写入的数据进行处理和分配,以保证数据的高可用性,安全性,读写高性能等。同时,在集群某个节点发生故障时,需要策略层定义故障的修复机制。

  • 引擎层:定义了数据持久化的方式,数据经过策略层的处理最终都会被分配到存储集群中的相应节点上。数据到达节点之后,以什么样的方式持久化到磁盘上,是引擎层定义的。

在这三个层次中,引擎层通常采用目前比较成熟的一些单机存储软件,例如整存整取的文件存储通常使用比较常用的ext4,xfs等文件系统作为引擎层。Key-Value存储通常采用Leveldb,MySQL等单机数据库系统作为引擎层。可以说,在分布式存储系统出现之前,引擎层单机的技术发展已经比较成熟了。所以,引擎层通常不是分布式存储系统需要重点考虑一层,通常都会根据业务的需求,选择一款比较合适的引擎层的存储技术。那么,分布式存储系统所需要解决的问题主要集中在接口层和策略层。其中,以策略层所要解决的问题最为复杂。接下来就以Ceph策略层所要解决的数据定位,数据备份,错误检测和恢复等方面的问题为出发点,结合Ceph本身的架构设计对Ceph作一个较为详细的介绍。

1.2 Ceph基本组件

Ceph中所包含的基本组件如图2所示
在这里插入图片描述
我们从下往上看,Sage在当初发表关于Ceph的论文最重要的一个概念就是RADOS,意在构造一个高可靠的,可扩展的自治的分布式存储系统。Ceph中RADOS的实现是由OSD和Monitor两个组件完成的:

  • OSD:OSD(Object Storage Device)是Ceph中的一个核心概念,是Ceph自治系统进行自我管理和修复的基本单元。它要完成的任务就是负责策略层策略的最终落地。本质上来说,它是一个用户态进程,管理着一片数据存储区域(通常是一块磁盘)。对外,OSD接收或者发送策略层的集群管理信号;对内,OSD利用引擎层的读写接口实现数据的最终写入和读出。在实际的部署中,通常都是一个OSD进程管理一块磁盘。

  • Monitor:Monitor类似于Hadoop中的Zookeeper服务,是Ceph分布式系统的协调器,主要负责对集群中的各个组件进行状态一致性的协调。同时,集群中的安全认证机制也是由Monitor完成的。Monitor本身也有高可用的机制,在生产环境中,一个Ceph集群通常使用三个Monitor同时工作。这里要注意的是Monitor不是元数据服务器,以HDFS作为类比,它和HDFS中的Namenode有非常大的不同,它主要负责集群状态的监测和数据一致性的协调,而不负责存储在集群中数据的元数据管理,但是会负责轻量的集群状态元数据(主要是一些Map结构的数据Ceph称之为ClusterMap,后面讲到的CrushMap和PGMap都包含其中)的维护和存储。

当你的集群中拥有了OSD和Monitor你就拥有了一个高可用的数据存储的集群。当然,你得需要一个读写的接口,才能把自己的数据放上去。Ceph提供了一个统一的读写API:librados,目前,librados支持C/C++、Java、Python等大部分的语言。客户应用程序可以通过这个API实现数据高可靠的写入和快速的读取。然而,考虑到用户的使用习惯,和librados本身比较复杂,Ceph在librados之上开发出了三种比较常用的数据存取接口:CephFS、RBD、RadosGW,分别为用户提供Posix文件系统接口,RBD块存储接口和RadosGW对象存储接口。

2 Ceph中的策略层

2.1 CRUSH进行数据分发和定位

Ceph能够实现去中心化的架构,主要得益于CRUSH算法,客户端通过CRUSH算法定位每一个数据块所在的位置,进行读写, 从而省去需要保存元数据的中心组件(容易成为瓶颈)

  • 在有中心元数据节点的分布式存储系统中,如果要定位想要的数据,客户端一般先与元数据服务器(比如HDFS中Namenode)进行交互,获取数据的位置信息。在这种结构的分布式系统中通常存在单点瓶颈,导致集群的扩展性、高可用性、性能等一些方面的问题
  • 在Ceph中是通过CRUSH(Controlled Replication Under Scalable Hashing)算法来进行数据分发和定位的,从而去除了中心节点(实际上,ceph也是有中心节点的,但是在设计上保存的数据量很少,因此在monitor协调一致性的前提下,保存到了所有的osd节点,并保证数据一致性)

CRUSH:CRUSH是一个伪随机哈希算法,其实现目标是通过哈希的方式快速快速找到数据应该存入的存储设备,并且使数据在整个集群中比较均匀的分布。对其简单的描述如图3所示:
在这里插入图片描述

CRUSH算法中有两个重要的输入

  • 一个是要计算对象的ID(可以是一个对象或者一个对象组)
  • 另一个是从上到下描述存储集群拓扑结构的CrushMap。CrushMap是根据集群当前的拓扑结构进行定制的。比如一个CrushMap可以包含这些信息:集群中多少个机架,每个机架上有多少个服务器,每个服务器上有多少个磁盘。

Sage把CRUSH算法设计成了一个通用的哈希算法,也就是它也可以被用在和Ceph有类似需求的存储系统中。那么在Ceph中CRUSH算法完成了什么样的工作呢。如图4所示,当要将一个对象存入Ceph集群时,Client端先对该对象进行一次哈希,得到一个pgid(后面会讲到),然后将pgid作为CRUSH算法的输入,此时的CrushMap包含的信息是:此集群中拥有4个存储节点,每个存储节点上有三个osd。由于此时各个osd之间的隔离域(failure domain)只是到了机器(host)层。所以此时的CRUSH算法只是从不同机器上选取3个不同的osd,然后将对象写入。以上只是对CRUSH的工作过程做一个简单的描述,具体算法的实现,可以参考相应的源代码或文档。

在这里插入图片描述

2.2 PG(Placement Group): 集群管理的基本单元

图4中我们可以看到,数据映射到osd的过程中有个中间的PG层,PG是Ceph中的一个非常重要的概念,是对写入对象进行管理的基本单元。数据读写、集群状态监测,错误恢复等过程都是以PG为单位进行的。PG与OSD是多对多的映射关系(例如图中,PG1对应了[osd2, osd5, osd6],而osd5又可以同时属于PG1和PG100),这种映射关系被称为PGMap,是系统在运行过程中维护的一个重要信息。

通常在这种映射关系中,PG的密集度远高于osd的,一个PG所对应的一组OSD本质上是CRUSH算法对一个pgid计算出来的结果,集群中pgid的数目是由系统管理员进行设置的,Ceph的官方建议值是:pg_num = (osd总数 * 100)/3

PG概念的引入为集群的管理带来了很大的灵活性,这也是无中心Metadata Server架构设计的关键所在。前面我们讲到PGMap是保存集群状态信息的一个重要的元数据,也是ClusterMap中最大的一个Map。PGMap对每一个PG保存一个条目,该条目指示PG与OSD的映射关系以及其所处的状态。如图5所示就是截取的我们测试集群中PGMap中的一段。
在这里插入图片描述

其每个PG条目主要字段的意思如下:

  • pg_stat:该PG的pgid,pgid是一个RADOS集群中PG的唯一标识,由点(.)隔成的两部分组成,第一部分“1”是Pool号(见2.3.5),第二部分是0 ~ n-1(n是由管理员设定的PG数目)的十六进制表示。
  • state:标示PG当前所处的状态,active+clean表示该PG目前处于活动状态,并且由该PG所管理的数据都处于安全一致的状态。
  • up:表示该PG会映射到的OSD集合,由于我们设置的数据备份数是2,所以每个PG会映射到两个OSD。例如写入到pgid为1.17c的数据会对应的写入到osd53和osd14中。
  • up_primary:标识该PG所映射的OSD中primary OSD是osd53。通常,写在up集合中的第一个OSD就是primary OSD。
  • acting,acting_primary和对应的up以及up_primary含义基本相同。

pg有多种状态,可以通过命令ceph pg dump 获取

  • active+clean:表示PG正常运行,并且数据在Ceph存储集群中的OSD(Object Storage Device)上是一致的。该状态是最理想的状态。
  • active+recovery:表示PG正在从故障中恢复。这可能是因为OSD出现故障,或者数据丢失等原因导致的。
  • active+remapped:表示PG在进行重映射,即数据正在从一个OSD迁移到另一个OSD。
  • active+undersized:表示PG中的副本数量低于所需数量。这可能是因为OSD出现故障,或者手动调整了PG的副本数。
  • active+stale:表示PG中的数据副本已经过期,需要进行重新同步。
  • active+degraded:表示PG中的数据丢失或不一致,需要进行修复。
  • inactive:表示PG当前处于非活动状态,即没有进行任何操作。

2.3 PG的代理primary OSD

上一节提到的primary OSD是实现PG功能的总代理。客户端对RADOS中数据的读写最终会落到某一个PG中,我们知道,PG是一个逻辑概念,需要一个实体(进程)完成其功能,这个实体就是primary OSD。在数据读写,PG状态维护等方面,primary OSD都发挥了积极的主导作用。

在数据读写时,客户端都是直接与primary OSD进行沟通

  • 在数据读取时,客户端首先通过哈希算法计算到数据所在的PG,然后查找当前的PGMap,找到PG的primary OSD,直接从该OSD中读取数据。
  • 在写入数据写入时,Ceph的写入是强一致性的。客户端也是先找到primary OSD然后,将数据写入到primary OSD,然后再通过primary OSD将数据同步到PG中其他的OSD。在PG对应的OSD都获得写入的数据之后,再由primary OSD对用户返回。

在数据读写以外的大量集群状态维护的工作中,PG状态的检测和错误恢复过程通常也是由primary OSD进行发起。

2.4 轻量级的集群元数据ClusterMap

Ceph中RADOS集群虽然不像HDFS那样存储标示数据位置信息的元数据,但也会存储标示集群构成和状态的元数据。Ceph中维护的几种元数据都是由Map数据结构构成,用ClusterMap作为这些Map的统称。Ceph的ClusterMap由以下Map组成:

  • MonitorMap:MonitorMap主要标示当前monitor集群由哪些monitor节点组成,各个monitor节点是否正常服务等信息。
  • OSDMap:标示集群由哪些OSD节点组成,以及各自的健康信息。
  • MDSMap:标示集群中mds(专为CephFS提供服务的组件)节点的组成,以及各自的健康信息。
  • CrushMap: CrushMap定义了数据在存储集群中的分布方式,通过将数据分散到多个存储设备上,提高了系统的并发访问能力和容错性。CrushMap描述了存储集群中的各个设备之间的层次结构,包括存储节点、机架和数据中心等,以及各个设备的权重。当存储设备出现故障时,CrushMap能够自动将受影响的数据迁移到其他可用设备上,从而实现故障恢复。CrushMap可以根据存储设备的负载情况,实现数据的动态负载均衡。通过动态分配数据到负载较低的存储设备上,避免了系统中某些设备负载过高的情况
  • PGMap: PGMap记录了每个PG的当前状态,包括活动(active)、未激活(inactive)、恢复(recovering)等状态。通过监控PGMap的变化,可以及时了解到PG的状态变化和健康状况。PGMap记录了每个PG的位置和复制策略,包括PG所在的OSD(Object Storage Daemon)和PG副本的分布情况。通过PGMap可以掌握到数据的分布情况,确保数据的可靠性和高可用性。当有OSD故障或数据损坏时,PGMap会提供故障恢复所需的信息,如需要恢复的PG和副本的位置等。通过PGMap可以方便地进行故障恢复操作,保证数据的完整性和可靠性

这5中Map共同构成了Ceph集群所需要维护的元数据ClusterMap。并且,这些Map所需要维护的数据量都比较小(在一个上百节点的集群中ClusterMap通常不过几MB的数据)。这给集群的维护带来了巨大的好处,集群中就不需要中心的元数据服务节点来存储和维护元数据。

Ceph集群中每一个节点都保存着ClusterMap,由Monitor维护着这些ClusterMap的协调一致,负责调整ClusterMap并同步到osd节点。这样,正常情况下,任意节点的元数据查找都只在本地进行Map查找,这也提高了集群的性能。

2.5 对PG的罗辑分组:Pool

当我们的Ceph集群资源比较充裕,单个业务用不完这么多资源,而需要多种业务混合使用单集群;或者集群中有些数据需要3份备份,而数据可靠性不需要那么高只需要2份备份该怎么办呢?针对这些相关的场景,Ceph引入了Pool的概念对PG进行了罗辑划分。在图5展示的pgid部分,第一部分的数字“1”就是Pool号。当Client要将数据写入到RADOS集群时,必须先指定相应的Pool号,这样就对不同类型的数据进行了划分。同时,还可以对Pool设置配额,设置对不同用户的读写权限等。

2.6 集群自治

Ceph集群中最多的节点就是存储数据的OSD节点,这些OSD节点的状态如果都由Monitor节点进行维护,会给Monitor节点带来沉重的负担。Ceph采取OSD节点自治的方式来进行自身状态的维护。具体操作方案就是每一个OSD节点会有自己的一组peer节点,OSD节点会定时的给自己的peer节点发出heartbeat,这样就能获取peer节点的状态信息。如果OSD节点获知peer节点有异常,就立即向Monitor节点进行报告,这样就能使集群的信息得到及时的更新。当前OSD所处的PG是其peer节点选取的重要依据,当然其中还有相关的算法策略,以确保用最少的heartbeat来保证不遗漏集群中每一个OSD节点状态的监测。

2.7 良好的扩展性

当Ceph进群需要扩容时,我们只需要向集群中增加OSD节点。新的OSD节点加入时,会主动告知Monitor,并被加入到OSDMap中。同时,Monitor会根据当前集群的状态,采取相应的策略,将新增的OSD节点加入到合适的一些PG中以保证集群中数据的负载均衡,同时,Monitor会更改PGMap。然后该OSD所对应的PG会进行相应的数据迁移(将PG中的数据迁移到该OSD节点上)。这样,OSD节点就能很快速的加入到了Ceph集群中,以实现对集群的扩容。

2.8 EC(Erasure Coding)编码的支持

和许多其他的分布式存储系统类似,Ceph原始的设计是基于存储对象的多份拷贝来保证数据高可用性的。随着EC编码在分布式存储系统中应用的增多,Ceph也顺应潮流加入了对EC编码的支持。得益于Ceph良好的结构设计,EC编码这个特性也很快的被Ceph所吸纳。

Ceph中的EC编码是基于Pool这一层做的。我们知道,RADOS可以通过对Pool指定数据对象的备份数来保证数据的高可用性。与之对应,RADOS还支持用户创建EC Pool,这样用户通过EC Pool写入RADOS集群的数据就能由EC编码的方式保证数据的高可用性。同时,在创建EC Pool时,还支持指定m,k值以及使用的具体EC编码算法等。

3. 多存储引擎的支持

前面的章节我们看到,Ceph中非常完善的策略层的设计,CRUSH算法以及RADOS的设计确保了数据的高可用性,集群的可靠性和扩展性。得益于Ceph良好的架构设计,在引擎层,Ceph也支持多种存储产品。如图6所示,我们可以将单OSD节点分成三个层
在这里插入图片描述

PGs层表示在PG与OSD多对多的关系中,一个OSD节点通常被多个PG所包含,OSD节点上的存储资源在逻辑上被落在该节点上的各个PG划分成了多个部分。

OSD层表示OSD主进程,前面讲到RADOS中数据的读写以及状态的维护都是以PG为单位,落到该OSD节点上PG的操作,都由OSD主进程进行完成。同时,数据的读写等操作OSD层会调用相应的引擎层进行完成。

目前,Ceph的引擎层不仅支持btrfs,xfs等文件系统,还支持一些单机的Key-Value存储如LevelDB,RocksDB等。这样Ceph不仅可以用于高吞吐的文件存储,也可以用于低延时的Key-Value存储。由于Ceph有强大的策略层的设计,和良好的架构设计,我们可以把Ceph看做是一个强大的分布式存储框架,用户可以根据自己的业务需求选择底层的存储引擎。

4. 三种接口简介

在Sage设计Ceph之初,业界使用最多的存储系统接口还是文件系统接口,文件系统接口最流行的标准是Posix。当时,对象存储还没有流行开来,并且也缺少统一的接口。因此,最初Sage仅仅实现了把Posix文件系统接口(CephFS)作为Ceph对外提供服务的接口。在亚马逊推出S3之后,对象存储迅速流行,并且S3的对象存储接口也基本成为了事实上的标准。并且随着以虚拟机作为服务形式的云计算服务的流行,块存储接口的需求也迅速增长。Sage很敏锐感觉到存储接口的设计是满足用户需求和用户体验的大事,于是在Ceph原有的librados原生API的基础上又开发出了对象存储接口RadosGW和块存储接口RBD。

4.1 RadowGW

谈到对象存储接口,那么什么是对象存储呢?目前,业内还没有对象存储的统一定义。通常可以认为,对象存储和其他存储最大的不同在于因用户需求的不同而导致的接口语义以及内部设计的不同。不同对象存储系统内部的设计千差万别,但是接口的语义基本相同:不提供文件的随机读写,数据的存取过程以对象的方式进行整存整取为主。并且,维护数据信息的元数据和数据本身进行分开存储和管理(在传统的文件系统中,元数据的操作占据了大量数据磁盘的IO)。这种存储方式天生的迎合了互联网中的诸多服务,例如图片、视频、音频等的存储。

RadosGW(Rados GateWay)是Ceph中的对象存储接口,同时兼容S3接口和Swift接口。其包含的主要模块的结构如图7所示:
在这里插入图片描述
图中我们可以看到RadosGW支持Civetweb,Apache等HTTP服务器作为接收REST请求的服务器,然后根据请求的类型,进行相应的解析。最终,RadosGW会将REST请求转化成对librados的调用,据此对RADOS集群进行数据的读写操作。

4.2 RBD

RBD(RADOS Bolck Device)是Ceph对外提供的块存储接口。通常块存储是由系统管理员进行管理和维护,主要是给虚拟机或者物理机提供虚拟磁盘服务。目前RBD被广泛应用于OpenStack中,为虚拟机提供虚虚拟磁盘服务。RBD接口的结构如图8所示:
在这里插入图片描述
我们可以看到,RBD接口是通过RBD Kernel Module将对存储块的操作转换成通过librados对RADOS集群进行的读写操作。RBD接口也是Ceph三种接口技术栈最简单的一种接口,并且RBD Kernel Module的代码已经被merge进了Linux内核当中,配置起来也比较简单。

4.3 CephFS

文件系统接口是历史悠久,使用最广泛的存储接口,Posix文件系统接口是最流行的文件系统接口的标准。Ceph文件系统接口是符合Posix标准的。相比于块和对象接口,文件系统接口是一种语义更复杂的存储接口。其支持的元数据操作、文件夹操作等给存储系统带来了比较大的额外负担,并且给实现也增加了很大的复杂性。在Ceph中,CephFS接口也是实现起来最复杂的一种接口,其结构图9如下所示:
在这里插入图片描述
由图我们可以看到,CephFS接口同时支持Kernel级的文件系统接口和用户态的文件系统接口(FUSE)。在CephFS接口中增加了一个非常重要的组件MDS(Metadata Server),负责对CephFS中的元数据进行管理。根据集群的负载情况,我们可以使用一个或多个MDS节点。并且,MDS本身并不进行数据的存储,而是将所有的元数据都存储到RADOS中对应的Metadata Pool中,依赖于RADOS中数据的高可用性,MDS所管理的数据也是高可用的。还可以为MDS节点添加热备用节点,在节点失效时,备用节点可以立即接收工作,以保证集群的高可用性。

5. 疑问和思考

一些总结

Ceph分布式存储系统具有优秀的策略层的设计,无中心元数据节点,无单点问题,完善的错误恢复机制,良好的扩展性等特性是它的核心竞争力。同时,良好的架构设计为其带来的多存储接口以及多存储引擎的支持也为其吸引了大量的用户和开发者。目前从社区以及我们自己的测试情况来看,Ceph已经具备非常高的可靠性。并且从社区来看,RadosGW和RBD接口已经在生产环境中得到了很好的检验,CephFS接口目前还有待得到生产环境的检验。当前,Ceph社区也非常活跃,并且背靠OpenStack这棵大树,相信Ceph的发展会越来越好。

6. 参考文档

  • 暂无

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

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

相关文章

谷粒商城——通过接口幂等性防止重复提交订单

如果用户向后端服务提交多次相同订单的提交服务,那么后端应该只生成一条订单记录。 有一些操作天然是幂等的,如查询操作和删除操作等。 幂等性实现 1.token机制(仅这个方法适用于订单的重复提交) 后端先生成1个令牌将其记录在R…

通用开发技能系列:SQL基础学习

云原生学习路线导航页(持续更新中) 本文是 通用开发技能系列 文章,主要对编程通用技能 SQL基础 进行学习 1.数据库简介 1.1.数据库中的一些名称 DataBase:数据库 程序员只负责怎么维护存取数据,不管数据库是什么 DBA…

Django之关系模型的序列化

一、关系模型的序列化-多查1 1.1、模型准备 from django.db import models# Create your models here. class Classes(models.Model):name = models.CharField(max_length=20, verbose_name=班级)class Student(models.Model):SEX_CHOICES = ((1,男)), (2, 女)name = models.C…

【HTML】制作一个简单的三角形动态图形

目录 前言 开始 HTML部分 CSS部分 效果图 总结 前言 无需多言,本文将详细介绍一段HTML和CSS代码,具体内容如下: 开始 首先新建文件夹,创建两个文本文档,其中HTML的文件名改为[index.html],CSS的文件名…

【Python的第三方库】flask

1. Flask是什么? 基于python的web后端开发轻量级框架; 基于MVT设计模式即Models,Views,Templates(html模板语言) 2.中文文档: https://dormousehole.readthedocs.io/en/2.1.2/index.html 3.依赖3个库: Jinja2 模版&#xff1…

【Unity灶台】食品加工系统模型搭建

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:uni…

pwn学习笔记(7)--堆相关源码

相关源码: 1. chunk 相关源码: ​ 对于用户来说,只需要确保malloc()函数返回的内存不会发生溢出,并且在不用的时候使用free() 函数将其释放,以后也不再做任何操作即可。而对于glibc来说’它要在用户第一次调用malloc…

4.4总结

这两天学习了线段树和树状数组,今晚上学长还在进行JDBC和MYSQL的教学,也收获到了一些东西 树状数组与完全二叉数结构上大致相同,但是完全二叉树每个节点只能存储单个数,而树状数组存储的是数组的范围。 从头结点开始为一整个数组…

Linux之实现Apache服务器监控、数据库定时备份及通过使用Shell脚本发送邮件

目录 一、Apache服务器监控 为什么要用到服务监控? 实现Apache服务器监控 二、数据库备份 为什么要用到数据库备份? 实现数据库备份 三、Shell脚本发送邮件 为什么要用使用Shell脚本发送邮件? 实现Shell脚本发送邮件 一、Apache服务器…

Spring声明式事务以及事务传播行为

Spring声明式事务以及事务传播行为 Spring声明式事务1.编程式事务2.使用AOP改造编程式事务3.Spring声明式事务 事务传播行为 如果对数据库事务不太熟悉,可以阅读上一篇博客简单回顾一下:MySQL事务以及并发访问隔离级别 Spring声明式事务 事务一般添加到…

VSCODE使用VSIX安装扩展

VSCode安装扩展特别慢,使用命令行安装告别龟速: code --install-extension当然,我这个是在WSL 的linux上安装的,Windows一样的。 VSCode扩展商店网页链接:https://marketplace.visualstudio.com/vscode

号卡极团分销管理系统 index.php SQL注入漏洞复现

0x01 产品简介 号卡极团分销管理系统,同步对接多平台,同步订单信息,支持敢探号一键上架,首页多套UI+商品下单页多套模板,订单查询支持实时物流信息、支持代理商自定义域名、泛域名绑定,内置敢探号、172平台、号氪云平台第三方接口以及号卡网同系统对接! 0x02 漏洞概述…

数字信号处理实验---FFT分析

一、题目: 二、实验要求: 1、绘制图形时,尽量选用已经提供的函数。 2、所有的图形,需要加上横坐标、纵坐标以及标题的说明。 3、将设计的程序保存为脚本文件,在实验报告中,需写出程序语句。 4、Matlab程…

ECC升级S/4HANA“沙箱模拟方案包“:更适用于升级环境复杂、体量大的客户

“作为一家业务体量大的公司,分支机构众多、数据复杂,想从ECC升级会有什么风险?”面对技术更新换代、公司业务不断扩展、网络安全问题的日益突出,将ECC升级到S/4HANA是企业的当务之急。为解决客户的顾虑,无论是对于历史…

51单片机入门_江协科技_19~20_OB记录的笔记

19. 串口通讯 19.1. 串口介绍: •串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。 •单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的…

设计模式总结-建造者模式

建造者模式 模式动机模式定义模式结构模式分析建造者模式实例与解析实例:KFC套餐 模式动机 无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮、方向盘、发送机等各种…

使用labelImg标注yolov5数据集并在kaggle中使用yolov5

使用labelImg标注yolov5数据集并在kaggle中使用yolov5 文章目录 前言一、labelImg标注1.1. 下载exe文件1.2. labelImg 下载(源码)1.3. 环境配置1.4. 使用1.4.1. 设置1.4.2. 导入图片并标注 二、在kaggle中使用2.1. 下载源码2.2. 编辑配置文件2.3. 将压缩…

[蓝桥杯 2017 国 C] 合根植物

[蓝桥杯 2017 国 C] 合根植物 题目描述 w 星球的一个种植园,被分成 m n m \times n mn 个小格子(东西方向 m m m 行,南北方向 n n n 列)。每个格子里种了一株合根植物。 这种植物有个特点,它的根可能会沿着南北…

StarRocks使用Minio备份和还原

1.安装minio Centos7安装minio-CSDN博客 minio api端口&#xff1a;9090 下文用到这个端口 必须提前创建好桶: packfdv5 名称自定义和后面对上就可以 2.创建备份仓库 格式&#xff1a; CREATE REPOSITORY <repository_name> WITH BROKER ON LOCATION "s3a:/…

支付类漏洞挖掘技巧总结

前言&#xff1a; 支付类逻辑漏洞在漏洞挖掘中是常常出现的问题之一。此类漏洞挖掘思路多&#xff0c;奖励高&#xff0c;是炙手可热的漏洞。此篇文章主要围绕挖掘支付逻辑漏洞时的一些思路分享。 支付逻辑漏洞成因&#xff1a; 支付漏洞可能由以下原因造成&#xff1a; 前…