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.rhkb.cn/news/296700.html

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

相关文章

观察和配置MAC地址表

目录 原理概述 实验目的 实验内容 实验拓扑 ​编辑1.基本配置 2.观察正常状态时的MAC地址表 4.配置静态MAC地址表项 原理概述 MAC 地址表是交换机的一个核心组成部分,交换机主要是根据 MAC 地址表来进行帧的转发的。交换机对帧的转发操作行为一共有…

车道线检测_Canny算子边缘检测_1

Canny算子边缘检测(原理) Canny算子边缘检测是一种经典的图像处理算法,由John F. Canny于1986年提出,用于精确、可靠地检测数字图像中的边缘特征。该算法设计时考虑了三个关键目标:低错误率(即尽可能多地检…

【漏洞复现】WordPress Plugin LearnDash LMS 敏感信息暴漏

漏洞描述 WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是一个应用插件。 WordPress Plugin LearnDash LMS 4.10.2及之前版本存在安全漏洞&#x…

从汇编看函数调用

文章目录 函数调用流程栈相关寄存器及的作用简介寄存器功能指令功能 栈函数的括号{}正括号反括号 参数传递传值,变量不可改传指针,变量可改C 传引用 函数调用实例 函数调用流程 目标:函数调用前后栈保持不变 保存main函数的寄存器上下文移…

使用MySQL和PHP创建一个公告板

目录 一、创建表 二、制作首页(创建主题以及显示列表) 三、制作各个主题的页面(输入回帖和显示列表) 四、制作消息的查询界面 五、制作读取数据库信息的原始文件 六、制作数据重置页面 七、效果图 八、问题 1、目前无法处…

商务电子邮件: 在WorkPlace中高效且安全

高效和安全的沟通是任何组织成功的核心。在我们关于电子邮件类型的系列文章的第二期中,我们将重点关注商业电子邮件在促进无缝交互中的关键作用。当你身处重要的工作场环境时,本系列的每篇文章都提供了电子邮件的不同维度的视角。 “2024年,全…

基于springboot实现房屋租赁管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现房屋租赁系统演示 摘要 房屋是人类生活栖息的重要场所,随着城市中的流动人口的增多,人们对房屋租赁需求越来越高,为满足用户查询房屋、预约看房、房屋租赁的需求,特开发了本基于Spring Boot的房屋租赁系统。 …

保健品wordpress外贸模板

保健品wordpress外贸模板 健康保养保健品wordpress外贸模板,做大健康行业的企业官方网站模板。 https://www.jianzhanpress.com/?p3514

防火墙状态检测和会话机制

FW对TCP,UDP和ICMP协议的报文创建会话

【如何解决一些常见的 Composer 错误的保姆级讲解】

🌈个人主页:程序员不想敲代码啊🌈 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家🏆 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提…

如何使用免费的ChatGpt3.5

如何使用免费的ChatGpt 最近免费的gpt3.5很多都不怎么行了实在是太给力了尾声 最近免费的gpt3.5很多都不怎么行了 原因是什么呢?因为openai已经取消了免费的5刀赠送,那么这些人手上的免费的sses-key 用完后,就基本上全军覆没了,再…

在 Amazon Timestream 上通过时序数据机器学习进行预测分析

由于不断变化的需求和现代化基础设施的动态性质,为大型应用程序规划容量可能会非常困难。例如,传统的反应式方法依赖于某些 DevOps 指标(如 CPU 和内存)的静态阈值,而这些指标在这样的环境中并不足以解决问题。在这篇文…

vscode + wsl1 搭建远程C/C++开发环境

记录第一次搭建环境过程。 搭建C/C开发环境有很多种方式,如 MinGW vscode(MinGW 是GCC的Windows版本,本地编译环境)SSH隧道连接 vscode(远程Linux主机)wsl vscode(远程Linux环境&#xff09…

flink1.18源码本地调试环境

01 源码本地调试环境搭建 1. 从github拉取源码创建本地项⽬ https://github.com/apache/flink.git 可以拉取github上官⽅代码 https://github.com/apache/flink.git GitHub - apache/flink: Apache Flink 2. 配置编译环境 ctrlaltshifts (或菜单)打…

node.js的错误处理

当我打开一个不存在的文件时,错误如下: 在读取文件里面写入console.log(err),在控制台中可以看到我的错误代码类型:文件不存在的错误代码 ENOENT。见更多错误代码---打开node.js官方API文档Error 错误 | N…

Redhat 7.9 安装dm8配置文档

Redhat 7.9 安装dm8配置文档 一 创建用户 groupadd -g 12349 dinstall useradd -u 12345 -g dinstall -m -d /home/dmdba -s /bin/bash dmdba passwd dmdba二 创建目录 mkdir /dm8 chown -R dmdba:dinstall /dm8三 配置/etc/security/limits.conf dmdba soft nproc 163…

Springboot Thymeleaf 实现数据添加、修改、查询、删除

1、引言 在Spring Boot中使用Thymeleaf模板引擎实现数据的添加、修改、查询和删除功能,通常步骤如下: 在Controller类中,定义处理HTTP请求的方法。创建Thymeleaf模板来处理表单的显示和数据的绑定。 2、用户数据添加 1、 在Controller类中…

【javaScript】DOM编程入门

一、什么是DOM编程 概念:DOM(Document Object Model)编程就是使用document对象的API完成对网页HTML文档进行动态修改,以实现网页数据和样式动态变化的编程 为什么要由DOM编程来动态修改呢?我们就得先理解网页的运行原理: 如上图&a…

达梦配置ODBC连接

达梦配置ODBC连接 基础环境 操作系统:Red Hat Enterprise Linux Server release 7.9 (Maipo) 数据库版本:DM Database Server 64 V8 架构:单实例1 下载ODBC包 下载网址:https://www.unixodbc.org/ unixODBC-2.3.0.tar.gz2 编译并…

C++的并发世界(六)——互斥解决数据共享冲突

0.数据共享的问题 在多个线程中共享数据时。需要注意线程安全问题。如果多个线程同时访问同一个变量。并且其中至少有一个线程对该变量进行了写操作。那么就会出现数据竞争问题。数据竞争可能会导致程序崩溃,产生来定义的结果,或者得到错误的热果。为了避免数据竞争问题。需要…