Ceph集群扩容及数据再均衡原理分析

news2025/1/16 1:00:47

用户文件在Ceph RADOS中存储、定位过程大概包括:用户文件切割成对象、对象映射到PG、PG分组PGP、PG映射到OSD。这些过程中,可能涉及了大量概念和变量,而其实它们大部分是通过HASH、CRUSH等算法计算出来的,初始参数可能也就只有这么几个:用户文件inode、layout、crush_map等。Ceph所有组件和客户端通过计算就能得到所有对象的Location,而且只要输入的参数信息不变,Location就不会变,另外通过PG作为中间层将对象与OSD解绑,使得对象在Ceph RADOS分布更均匀,在OSD增删时,能够保证只有尽可能少的对象发生迁移。在PG、PGP调整或OSD增删后,某些Location发生变化的对象的迁移路线,需要了解各级HASH映射的原理、步骤,更多的计算和分析才能得知。在此基础上才能分析调整PG和PGP对Ceph集群的影响做一些可靠的定性分析,进而指导我们采用更合适的策略去实现Ceph集群的扩容和数据再均衡。

1. 从用户文件到对象

从用户文件到对象的映射过程就是对用户文件进行切割的过程。CephFS会将用户文件按照一定的对象大小进行切割,得到若干对象,OSD负责对象的管理。例如,设定对象大小为4MB,则CephFS按照文件字节逻辑地址将1GB的用户文件切割成1GB/4MB=1024个对象,对象的编号obj_offset取值范围为[0,1024)。Obj_name = FileInode.obj_offset,FileInode为用户文件inode的十六进制码,obj_offset是用户文件被切割后对象的编号,代表用户文件的第几个对象。

如下图所示:

通过Striper::file_to_extents将用户文件内容映射到各对象,参数包括用户文件的布局layout,用户文件内容的字节逻辑地址偏移offset和长度len等。

对象大小是否可配置?

文件布局可以控制如何把文件内容映射到各Ceph RADOS对象,可以使用虚拟扩展属性或xattrs来读、写某一个文件的布局。布局字段包括object_size,但只能在文件size为0的情况下,才能重新配置。

# 通过以下命令读取布局字段:
getfattr -n ceph.file.layout.object_size file


# 通过以下命令修改布局字段:
setfattr -n ceph.file.layout.object_size -v 10485760 file

2. 从对象到OSD

从对象到OSD的过程包括:对象名hash、对象到PG、PG分组PGP、PG到OSD等主要过程。这里将以某个cephfs用户文件为例阐述详细的映射过程。

2.1. 创建文件

  1. 创建一个文件

touch /mnt/cephfs/file002
  1. 查看文件ino

ls -i /mnt/cephfs/file002

1099511876737 /mnt/cephfs/file002

  1. Ino进制转换

printf "%x\n" 1099511876737

1000003cc81

  1. 查看pool信息

ceph osd  pool ls detail


pool 5 'cephfs_data' replicated size 2 min_size 1 crush_rule 0 object_hash rjenkins pg_num 1024 pgp_num 1024 last_change 142 flags hashpspool stripe_width 0 expected_num_objects 16986931 application cephfs

pool 7 'cephfs_meta' replicated size 2 min_size 1 crush_rule 0 object_hash rjenkins pg_num 1024 pgp_num 1024 last_change 142 flags hashpspool stripe_width 0 expected_num_objects 169869 application cephfs

一个pool有pool_id、pool_name、副本数、pg_num、pgp_num等主要信息参数。pg_num和pgp_num调整分析也是本文的主要内容。从pool的详细查询结果可知,5号pool的名字为cephfs_data,采用2副本策略,pg和pgp都为1024。

2.2. 查找零号对象

通过命令可以找到/mnt/cephfs/file002的零号对象存储在哪个OSD上。

ceph osd map cephfs_data 1000003cc81.00000000

osdmap e213 pool 'cephfs_data' (5) object '1000003cc81.00000000' -> pg 5.b184543c (5.3c) -> up ([4,10], p4) acting ([4,10], p4)

从以上结果可知,零号对象1000003cc81.00000000存储在pg 5.3c,对应的OSD SET是 [4,10],OSD SET为2副本,pg 5.3c的主副本存储在osd.4中,次副本存储在osd.10中。

2.3. 对象名HASH

pg 5.b184543c是如何组成的?

以‘.’为分割符,可以分成两部分5和0xb184543c。5取自pool ‘cephfs_data’的pool_id,而0xb184543是obj_name ‘1000003cc81.00000000’的HASH hex值。

在源码中,HASH函数ceph_str_hash_rjinkins,根据obj_name计算出一个随机值。对于同样的对象名,计算出来的结果永远都是相同的。而对象名字构成中,用户文件inode号保证了不同文件之间的对象名字不同,而obj_offset确保了同一用户文件中不同对象的名字不同。

2.4. 从对象到PG

从“pg 5.b184543c (5.3c)”可知,使用的是5号pool,object 1000003cc81.00000000的HASH hex为“0xb184543c”,本文用obj_hash表示,也称为对象的placement seed,此值会被保存在代表pg的类pg_t的对象中,这里简称为pg_seed。

那pg 5.3c为什么只取了object hash hex码的后2两位呢?

是因为5号pool的pg总数为1024个,1024对应0x400,则mask = 0x400 - 1 =0x3ff,因此只需要取0x3ff & b184543c = 0x3c,这样就完成了从对象到PG的映射。最终,一个pg可以表示为pool_id.(mask & obj_hash),一个pool中pg的编号取值范围为[0,mask]。

2.5. PG分组PGP

众所周知,Ceph官方建议一个pool的pg_num = pgp_num,而且为2的幂次方。而说白了,PG分组PGP就是将众多PG分成各个PGP组。在二者相等的情况下,一个PGP中就只有一个PG。

但如果PGP小于PG呢?根据抽屉原理,肯定存在某些PGP分配到了2个或2个以上的PG。这种情况是否存在呢?答案是肯定的,该状态可能只是个中间态,在用户采用了小步调多次调整策略实施PG和PGP的调整,来配合集群OSD添加,最终pg_num会等于pgp_num。

例如,Ceph集群通过增加OSD数量达到扩容的目的,扩容后每个OSD平均承担的PG数量将会小于Ceph官方建议的100~200个,因为在这个取值范围内,集群数据分布均衡度与OSD负载都是比较合适的。因此,扩容后需要相应的调大pg_num和pgp_num,二者的调整是两个独立的顺序操作,因此会存在二者不相等的中间状态。另外,为了保证集群的稳定性,通常是小步调多次的调整pg_num和pgp_num,经过多轮的调整后达到整体调整目标。

这里可能会有一个疑问是,处于相同或不同PGP中的各PG,会有什么联系呢?

答案是,同一个pool中处于相同PGP中的各个PG会被映射到相同的OSD SET,而处于不同PGP中的各个PG一般会被映射到不同的OSD SET,但也不能完全排除被映射到相同OSD SET的可能性,这块的内容涉及到了ceph引以为傲的CRUSH算法,由于本文重点不在此,后期将有专门的文章做介绍。

下图中,ceph_state_mod通过PG的pg_seed与pgp_num_mask按位&,将各PG映射到PGP。

2.6. 从PG到OSD

Ceph数据存储策略有副本和EC两种,本文基于副本策略。用户可以选择2副本、3副本等,副本越多空间利用率就越低,而可靠性就越高,因此需要用户在空间利用率与可靠性二者之间做平衡。多副本情况下,PG到OSD的映射其实是PG到OSD SET的映射,OSD SET的成员个数为副本数,而首成员为主副本,其他成员为次副本,客户端的读写由主副本负责,这块内容涉及到了ceph集群的读写流程,这里不做太详细的介绍,后期文章再做分析。

下图中,_pg_to_raw_osds完成PG到OSD SET的映射,首先调用了pool.raw_pg_tp_pps完成了PG到PGP的分组,会得到分组唯一标识的placement ps即pps。然后,通过crush->find_rule找到pool的ruleno。最后,调用crush->do_rule基于ruleno和pps完成PG到OSD SET的映射。

虽然,两个PG的ps可能不同,但pps可能相同,那映射到的OSD SET就会相同,可以说它们选择了相同的OSD SET来存储数据,也就是说同一个OSD上会承担多个PG,每个OSD上平均承担的PG越多,在非常大量的对象情况下,每个OSD上存储的数据就越均衡。每个OSD上承担的PG越多,OSD管理PG的压力就越大,因此官方对每个OSD平均承担的PG数的合理取值范围为100~200。

CRUSH算法是ceph非常非常引以为傲的的特色,通过它,ceph中的每个组件或客户端都能自己计算出对象到OSD SET的映射,并不需要提供映射表查询的中心节点,从而避免了中心节点的瓶颈问题。本文重点不在CRUSH算法,此处不做详细阐述分析,后期会有单独文章做介绍。

3. 对象文件的命名规则

这里需要说明一下,本文中涉及的对象文件名字与对象名字不同,尽管二者就是同一个对象。对象文件名字指的是对象在linux xfs文件系统中的文件名字。

当前,OSD的两个主要类型为Filestore和Bluestore,本文基于Filestore。Filestore类型的OSD一般利用linux本地文件系统xfs存储和管理对象文件,用户文件被切割成对象文件后,一个对象就对应xfs的一个文件,一个xfs文件通过文件路径Path和文件名FileName定位,举例如下:

 /var/lib/ceph/osd/ceph-4/current/5.3c_head/DIR_C/DIR_3/DIR_4/1000003cc81.00000000__head_B184543C__5

该对象文件的Path = “/var/lib/ceph/osd/ceph-4/current/5.3c_head/DIR_C/DIR_3/DIR_4/”,FileName = “1000003cc81.00000000__head_B184543C__5”。

Path也包含了许多含义,ceph-4代表了osd.4,5.3c代表了5号pool中0x3c的pg,这些信息与前面章节一致。而DIR_C、DIR_3和DIR_4是pg dir split的结果,目的是为了保证每个目录中文件数不要过多,xfs某个目录特别大时,对于执行目录的ls等操作不利,而且过大的目录在被读进内存时,会消耗过多的内存,对该目录进行flush时也会花费更多的时间,当然还有其他缺点存在。

不难发现,将“_”作为分隔符,可以将FileName分割成若干部分,1000003cc81.00000000是对象名字,B184543C为对象名字的HASH hex值即pg的ps,5就是pool cephfs_data的号。对象文件名字结构如下所示:

很多组成部分在文章前面已经做了介绍,这里只做以下补充:

  1. key和hash不能同时指定,而且常见的是hash;

  2. snap_num为head,代表普通对象,否则为snapshot对象。可以给rbd image创建snapshot,这时候底层对象就有snapshot信息了;

  3. namespace可以认为是对pool空间的进一步划分,在逻辑上隔离各个用户。一个pool可以划分多个namespace,这些namespace中的对象都使用该pool。尤其应用在ceph rgw服务中。

到此为止,我们已经对用户文件是如何在Ceph中存储的过程有了大概的了解。该过程可以概括为:用户文件切割成对象、对象映射到PG、PG映射到OSD。这个过程中,可能涉及了大量概念和变量,而其实它们大部分是通过HASH、CRUSH等算法计算出来的,初始参数可能也就只有这么几个:用户文件inode、layout、crush_map等,通过计算就能得到所有对象的Location,而且只要输入的参数信息不变,Location就不变,另外通过PG作为中间层将对象与OSD解绑,而且使得对象在ceph RADOS中均匀分布。但本人觉得这也有一点点的小缺点,就是在PG、PGP调整或OSD增删后,某些Location发生变化的对象迁移路线并不是那么直接和直观,需要了解各级HASH映射的原理、步骤,更多的计算和分析才能得知。

4. PG调整的影响

为了简化问题,抓住重点,假设对象的分布如下:

根据文章前面的内容,表格中所有代号都能找到定义和计算方法,这里做一个简单的总结: 

  1. obj_hash = hash(obj_name);

  2. pg_seed = obj_hash;

  3. pgId = pg_seed & pg_mask;

  4. pgpId = pg_seed & pgp_mask;

4.1. PG非幂次方调整

将pg_num由2调整为3,pgp_num依然为2。调整后,对象的分布如下:

从表中可知: 

  1. pg_2分担了原属于pg_0的obj_2和obj_8,pg_2与pg_0对应同一个OSD SET,因此obj_2和obj_8只是OSD内部的迁移;

  2. pg_2分担了原属于pg_1的obj_5和obj_11,pg_2与pg_1对应不同的OSD SET,obj_5和obj_11涉及到了OSD之间的迁移,不同OSD之间就会有网络通信开销;

  3. pg_0分担了原属于pg_1的obj_3和obj_9,也会涉及网络通信开销;

  4. pg_1分担了原属于pg_0的obj_4和obj_10,也会涉及网络通信开销。

总之,共涉及OSD内部迁移2次,共涉及OSD之间迁移6次。我们将OSD内部迁移率定义为inter_mig_ratio,将OSD之间迁移率定义为ext_mig_ratio,则计算结果为:

由于OSD内部迁移,只是将一个对象文件从源目录mv到目的目录,由于源目录与目的目录共享同一个OSD的根目录,因此mv操作只涉及xfs文件系统元数据的更新,不涉及对象文件数据的读取和写入,可以称OSD内部迁移为轻迁移;

而OSD之间迁移,源OSD需要读取对象文件数据,网络通信发送到目的OSD,目的OSD再创建该对象文件,目的OSD写入对象文件数据,源OSD删除该对象文件,称OSD之间迁移为重迁移。

我们将OSD内部一次对象迁移的工作量定义为1,将OSD之间一次对象迁移的工作量定义为4,则总的工作量为:

因此,inter_mig_ratio反应了轻迁移率,而ext_mig_ratio反应了重迁移率,尽量减少重迁移,降低重迁移率,将重迁移变成轻迁移,最终减少数据迁移对ceph集群整体稳定性和性能的影响。

4.2. PG幂次方调整

将pg_num由2调整为4,pgp_num依然为2。调整后,对象的分布如下:

从表中可知: 

  1. pg_2分担了原属于pg_0的obj_2、obj_6和obj_10,pg_2与pg_0对应同一个OSD SET,因此obj_2、obj_6和obj_10只是OSD内部的迁移;

  2. pg_3分担了原属于pg_1的obj_3、obj_7和obj_11,pg_3与pg_1对应同一个OSD SET,因此obj_3、obj_7和obj_11也只是OSD内部的迁移。

总之,共涉及OSD内部迁移6次。

4.3. PG非幂次与幂次调整对比

inter_mig_ratio

ext_mig_ratio

work_load

非幂次(2->3)

16.67%

50%

2.17

幂次(2->4)

50%

0%

0.5

由上表可知,本文中PG非幂次调整引入的工作量远远高于幂次调整引入的工作量,因此建议PG调整最好选择幂次调整,尽量减少PG调整引入的工作量,降低PG调整对ceph集群稳定性和性能的负面影响。

比如,PG由2调整到16,当然可以选择直接调整到目标16,PG调整一步到位。也可以选择小步调多次调整,推荐这样的调整步调2->4->8->16。一步到位的调整策略与小步调多次调整策略各有优缺点,前者实现PG调整一次到位,但单次调整就引入大量的OSD内部迁移,虽然没有OSD之间迁移;后者将单次引入的大量OSD内部迁移分散到了多次调整里,因此单次小步调调整引入的OSD内部迁移相对较少,降低了PG调整对ceph集群稳定性和性能的负面影响,但是由于后者分成多次调整达到最终目标,相对前者会引入额外的中间态OSD内部迁移,因此后者总的OSD内部迁移量会高于前者。因为实践证明,后者的优点大于缺点,因此推荐采用PG小步调多次调整策略。

5. PGP调整的影响

为了简化问题,抓住重点,假设OSD SET只有0和1,对象的分布如下:

5.1. PGP非幂次方调整

将pgp_num由2调整为3,pg_num依然为4。调整后,对象的分布如下:

从表中可知: 

  1. pgp_2分担了原属于pgp_0的pg_2,而pgp_2使用OSD SET 0,而pg_2原本就使用OSD SET 0,因此这一变动不会有任何数据迁移;

  2. pgp_0分担了原属于pgp_1的pg_3,而pg_3对应的OSD SET由1号变成了0号,因此pg_3的所有对象将由OSD SET 0迁移到OSD SET 1,涉及到了OSD之间的迁移,不同OSD之间就会有网络通信开销。

总之,共涉及OSD内部迁移0次,涉及OSD之间迁移6次。则inter_mig_ratio、ext_mig_ratio和work_load为:

因此,inter_mig_ratio代表了轻迁移率,而ext_mig_ratio代表了重迁移率,尽量减少重迁移,降低重迁移率,将重迁移变成轻迁移,最终减少数据迁移对ceph集群整体稳定性和性能的影响。

5.2. PGP幂次方调整

将pgp_num由2调整为3,pg_num依然为4。调整后,对象的分布如下:

总之,共涉及OSD内部迁移0次,涉及OSD之间迁移0次。则inter_mig_ratio、ext_mig_ratio和work_load为:

通过以上表格发现,虽然pg_2和pg_3对应的pgp有变化,但对应的OSD SET未发生变化,因此该调整,不会发生任何的数据迁移。 

5.3. PGP非幂次与幂次调整对比

PGP调整章节的分析内容仅限于ceph集群OSD SET组合情况未变话,而实际情况导致OSD SET组合情况变更的条件包括:副本策略变化、OSD增减、故障域变更等等。

inter_mig_ratio

ext_mig_ratio

work_load

非幂次(2->3)

0%

25%

1

幂次(2->4)

0%

0%

0

由上表可知,PGP幂次调整优于非幂次调整。

6. 疑问和思考

用户文件的对象切割,对象名字的组成部分,对象到PG的映射过程,PG与PGP的关系,PG到OSD的映射过程,最后介绍了PG和PGP幂次和非幂次调整策略对ceph集群稳定性和性能的负面影响分析,但PG和PGP调整最终目标是好的,是为了配合ceph集群OSD扩容,是为了ceph集群数据分布的更均衡和合理,只是在选择PG和PGP调整策略时要有所选择,而并不是盲目的去实施。

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

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

相关文章

号卡极团分销管理系统 ue_serve.php 任意文件上传漏洞复现

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

caj文件是什么?caj是什么文件?考研学生赶紧收藏!

在学术研究的广阔领域中,尤其是对于那些致力于深入研究、不断拓宽知识边界的考研学子们来说,了解并掌握各种学术资源的获取与利用方法显得尤为重要。其中,CAJ文件作为一种常见的学术文件格式,其重要性和使用频率不容忽视。那么&am…

在Linux上安装并启动Redis

目录 安装gcc环境 上传redis文件 启动redis-server 后台启动redis-server 查看redis启动状态 参考文章:Linux 安装 Redis 及踩坑 - 敲代码的阿磊 - 博客园 (cnblogs.com) 准备:打开VMware Workstation,创建一个虚拟机,进入管…

FinnConverter格式转换工具

FinnConverter简介 1. 简洁的操作界面 2. 支持多种格式相互转换 支持word转pdf;ppt转pdf;raw格式转png/jpng…;其他格式相互转换 2.1 输入格式支持 bmp、cr2、cr3、crw、cur、dcr、dng、doc、docx、gif、ico、jpeg、jpg、kdc、mos、nef、…

具身智能论文(四)

目录 1. Alexa Arena: A User-Centric Interactive Platform for Embodied AI2. EDGI: Equivariant Diffusion for Planning with Embodied Agents3. Efficient Policy Adaptation with Contrastive Prompt Ensemble for Embodied Agents4. Egocentric Planning for Scalable E…

ICode国际青少年编程竞赛- Python-5级训练场-综合练习5

ICode国际青少年编程竞赛- Python-5级训练场-综合练习5 1、 a 16 for i in range(6):Dev.step(1)Dev.turnLeft()Dev.step(a)Dev.step(-a)Dev.turnRight()while Dev.energy < 100:wait()Dev.step(1)a a - 5 i2、 for i in range(5):Dev.step(11 - i * 2)Dev.turnRight()wh…

1146 -Table ‘performance schema.session variables‘ doesn‘t exist的错误解决

一、问题出现 今天在本地连数据库的时候&#xff0c;发现这个问题&#xff0c;哎呦我擦&#xff0c;差点吓死了 二、解决办法 1&#xff09;找文件 用everything搜一下MySQL Server 5.7 然后去Windows服务找一下MySQL配置文件的具体路径 如果知道那最好&#xff0c;不知道那…

水雨情监测系统—实时监测水位信息

TH-SW3水雨情监测系统是一种专门用于实时监测和收集水文气象数据的自动化系统。它能够实时获取区域内降雨和水情数据&#xff0c;并将其存储到数据库中进行分析处理&#xff0c;从而为防汛指挥人员提供及时准确的信息服务。 水雨情监测系统的主要功能包括实时监测水位、流速、流…

qt cmake加入程序exe图标

可以看到qt自动编译出来的图标是默认的&#xff0c;如下图所示 我想要更改成自定义的图标&#xff0c;比如下方的样子 下边是操作步骤&#xff1a; 图标选择与转化成ico 通过这个网站将正常图片转化成ico&#xff1a;https://www.bitbug.net/创建rc文件 将ico复制到cmakelis…

Windows内核--Kernel API简析(3.1)

如果所有的内核提供的功能&#xff0c;内核提供进程/线程创建和终止&#xff0c;内存分配和释放&#xff0c;文件操作&#xff0c;网络功能&#xff0c;驱动程序加载和卸载等功能。这些API将在后面陆续介绍&#xff0c;如下先介绍Kernel提供的基础API(Kernel自身或Driver使用).…

k8s v1.20二进制部署 部署 CNI 网络组件 部署 Calico

一、部署 flannel 1.1.K8S 中 Pod 网络通信 ●Pod 内容器与容器之间的通信 在同一个 Pod 内的容器&#xff08;Pod 内的容器是不会跨宿主机的&#xff09;共享同一个网络命名空间&#xff0c;相当于它们在同一台机器上一样&#xff0c;可以用 localhost 地址访问彼此的端口。…

【Web】2023香山杯决赛 security system 题解

目录 step -1 step 0 step 1 step 2 step 3 step -1 ①题目hint&#xff1a;想办法修改属性值后进入java的原生反序列化&#xff0c;然后利用jackson链写入内存马 ②jackson反序列化基础&#xff1a; ObjectMapper objectMapper new ObjectMapper(); String jsonStrin…

Java毕业设计 基于SpringBoot vue药店管理系统

Java毕业设计 基于SpringBoot vue药店管理系统 SpringBoot 药店管理系统 功能介绍 员工 登录 个人中心 修改密码 个人信息 查看供应商信息 查看药品 查看进货 查看销售 管理员 登录 个人中心 修改密码 个人信息 供应商类型管理 供应商信用等级类型管理 药品类型管理 供应商信…

基于STM32F401RET6智能锁项目(BS82166A_3触摸按键)

一、BS81x 特征 • 工作电压&#xff1a; 2.2V~5.5V • 低待机电流 • 自动校准功能 • 可靠的触摸按键检测 • 自动切换待机 / 工作模式 • 最长按键输出时间检测 • 具备抗电压波动功能 • Level Hold &#xff0c;可选高有效或低有效 • NMOS 输出内建上…

卷积网络项目:实现识别鲜花四分类对比LeNet5、VGG16、ResNet18、ResNet34分类网络

卷积四分类项目 Gitee传送门 分类目标选取 鲜花 杏花 apricot_blossom桃花 peach_blossom梨花 pear_blossom梅花 plum_blossom 模型选择 卷积 LeNet5VGG16ResNet18ResNet34 以图搜图 获取相似度前10的搜图结果 数据清洗 鲜花四分类 删除非图片文件 删除重复图片 整理…

RS3236-3.3YUTDN4功能和参数介绍及PDF资料

RS3236-3.3YUTDN4功能和参数介绍及PDF资料-公司新闻-配芯易-深圳市亚泰盈科电子有限公司 品牌: RUNIC(润石) 封装: XDFN-4-EP(1x1) 描述: 带过温保护 输出类型: 固定 最大输入电压: 7.5V 输出电压: 3.3V 最大输出电流: 500mA RS3236-3.3YUTDN4 是一款低压差线性稳压器&#x…

数据结构 顺序表1

1. 何为顺序表&#xff1a; 顺序表是一种线性数据结构&#xff0c;是由一组地址连续的存储单元依次存储数据元素的结构&#xff0c;通常采用数组来实现。顺序表的特点是可以随机存取其中的任何一个元素&#xff0c;并且支持在任意位置上进行插入和删除操作。在顺序表中&#xf…

npm install 卡在reify:rxjs: timing reifyNode的解决办法

今天要逆向跑一个electron&#xff0c;但是npm install一直卡在 reify:element-plus: timing reifyNode:node_modules/lodash Completed in 6664ms这里一动不动&#xff0c;一番研究之后发现可能跟用的镜像有关系&#xff0c;我原本是官方镜像&#xff0c;总感觉第三方镜像有一…

mysql主从热备部署

1、主从复制原理 mysql之间数据复制的基础是二进制日志文件。一台mysql数据库一旦开启用日志文件后&#xff0c;其作为master&#xff0c;它的数据库所有操作都会以事件的方式记录在二进制日志中&#xff0c;其他数据库作为slave通过一个I/O线程与主数据库保持通信&#xff0c;…

MATLAB蚁群算法求解带时间窗的旅行商TSPTW问题代码实例

MATLAB蚁群算法求解带时间窗的旅行商TSPTW问题代码实例 蚁群算法编程求解TSPTW问题实例&#xff1a; 在经纬度范围为(121, 43)到(123, 45)的矩形区域内&#xff0c;散布着1个商家&#xff08;编号1&#xff09;和25个顾客点&#xff08;编号为226&#xff09;&#xff0c;各个…