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

Ceph 基本架构(一)

Ceph架构图 

Ceph整体组成 

Ceph 是一个开源的分布式存储系统,设计用于提供优秀的性能、可靠性和可扩展性。Ceph 的架构主要由几个核心组件构成,每个组件都有特定的功能,共同协作以实现高可用性和数据的一致性。

以下是 Ceph 的整体架构及其各个组件的作用:

1. Ceph 存储集群 (Ceph Storage Cluster)

Ceph 存储集群是整个系统的核心,负责存储和检索数据。它由以下几种类型的节点组成:

  • OSD (Object Storage Device): 负责存储数据的对象,每个 OSD 实际上是一个进程,通常运行在一个物理硬盘上。OSD 处理数据的读写请求,并参与数据的复制、恢复、再平衡等过程。
  • Monitor (MON): 监控节点,负责维护 Ceph 集群的健康状态和元数据信息,包括但不限于监视器图(Monitor Map)、OSD图(OSD Map)、PG图(PG Map)和CRUSH图。Mon节点还负责维护集群成员关系、处理客户端请求的身份验证等。Mon节点不直接参与数据存储或PG的具体维护工作,但它们对于确保集群的健康状态和一致性至关重要。MON 节点必须是奇数个,以避免“裂脑”现象(即在集群分裂时无法达成多数派共识)。
  • Manager (MGR): 管理节点,负责收集各种监控数据和性能指标,提供给管理员和用户界面。MGR 还可以运行插件来扩展其功能。

2. Ceph 客户端 (Ceph Clients)

Ceph 客户端通过不同的接口与存储集群交互,主要包括:

  • RADOS Gateway (RGW): 提供 S3 和 Swift 兼容的对象存储接口,使 Ceph 可以作为云存储解决方案。
  • CephFS: 分布式文件系统,允许通过标准文件系统接口访问 Ceph 集群。
  • RBD (RADOS Block Device): 块设备接口,可以将 Ceph 集群中的对象存储呈现为块设备,常用于虚拟机的磁盘镜像。
  • Librados: 一个库,直接与 RADOS 层通信,开发者可以使用 Librados 构建自定义的应用程序。

3. 数据放置策略 (CRUSH Algorithm)

  • CRUSH (Controlled Replication Under Scalable Hashing): 是 Ceph 使用的一种智能算法,用于确定数据应该存储在哪里。CRUSH 根据预定义的规则(如数据中心布局、服务器分布等)决定数据的副本位置,从而实现数据的均匀分布和高效的故障恢复。

4. 其他辅助组件

  • Metadata Server (MDS): 在 CephFS 中使用,负责管理文件系统的元数据,如目录结构和文件属性。MDS 节点确保文件系统的高效运行和数据一致性。根据文件系统的规模和性能需求,可以部署一个或多个 MDS 节点。多个 MDS 节点可以提高元数据处理的性能和可靠性。
  • iSCSI Gateway: 提供 iSCSI 接口,使得 Ceph 可以作为传统的 SAN 存储使用。

OSD存储释意

OSD(Object Storage Device)是 Ceph 分布式存储系统中的一个重要组件,负责实际的数据存储和管理。理解 OSD 的作用和工作机制对于了解 Ceph 的整体架构和性能至关重要。以下是关于 OSD 的详细解释:

1. 基本概念

OSD:全称为 Object Storage Device,是 Ceph 中的基本存储单元。每个 OSD 实际上是一个运行在物理硬盘上的进程,负责存储和管理数据对象。
对象:Ceph 中的数据以对象的形式存储。每个对象包含数据和元数据,元数据包括对象的 ID、大小、版本号等信息。

2. 主要职责:

数据存储:OSD 负责将数据对象存储在物理硬盘上,并确保数据的持久性和完整性。
数据读写:处理客户端的读写请求,将数据写入硬盘或将数据从硬盘读出。
数据复制:根据 Ceph 的配置,OSD 会将数据对象复制到其他 OSD 上,以确保数据的高可用性和容错性。
数据恢复:当某个 OSD 失效时,其他 OSD 会自动进行数据恢复,将缺失的数据副本重新创建。
数据再平衡:当新的 OSD 加入集群或现有 OSD 离开集群时,OSD 会自动进行数据的再平衡,确保数据在集群中的均匀分布。

3. 工作流程:

接收请求:OSD 从客户端或其他 Ceph 组件(如 MDS、RGW)接收数据读写请求。
数据处理:根据请求类型,OSD 执行相应的操作,如将数据写入硬盘或从硬盘读取数据。
数据复制:根据 CRUSH 算法,OSD 将数据对象复制到其他指定的 OSD 上,确保数据的冗余。
心跳检测:OSD 与其他 OSD 和 MON 节点定期进行心跳检测,以确保集群的健康状态。
故障检测与恢复:当某个 OSD 失效时,其他 OSD 会检测到这一情况,并启动数据恢复过程,将缺失的数据副本重新创建。
数据再平衡:当集群结构发生变化(如新增或移除 OSD)时,OSD 会自动进行数据的再平衡,确保数据在集群中的均匀分布。

4. 配置与管理

配置文件:OSD 的配置信息通常保存在 Ceph 配置文件中,包括存储路径、网络配置、日志级别等。
启动与停止:OSD 进程可以通过命令行工具(如 ceph-osd)进行启动和停止。
监控与日志:OSD 会生成详细的日志信息,帮助管理员监控和调试集群状态。

5. 性能优化

缓存机制:OSD 可以利用内存缓存来加速数据读写操作,提高性能。
并行处理:OSD 支持并行处理多个请求,充分利用多核 CPU 的性能。
I/O 调度:OSD 可以配置不同的 I/O 调度策略,以优化磁盘的读写性能。

总结

OSD 是 Ceph 分布式存储系统中负责实际数据存储和管理的核心组件。通过数据复制、故障检测与恢复、数据再平衡等机制,OSD 确保了数据的高可用性和一致性。理解 OSD 的工作原理有助于更好地管理和优化 Ceph 集群的性能。

CRUSH 算法解释

CRUSH(Controlled Replication Under Scalable Hashing)算法是 Ceph 分布式存储系统中一个非常重要的组件,用于决定数据对象在集群中的存储位置。CRUSH 算法的设计目标是实现数据的均匀分布、高效的数据访问和高可用性。下面是 CRUSH 算法的详细解释:

1. 基本概念
  • 数据对象:Ceph 中的数据以对象的形式存储,每个对象包含数据和元数据。
  • 存储设备(OSD):Ceph 中的实际存储单元,每个 OSD 负责存储和管理数据对象。
  • 存储桶(Bucket):CRUSH 算法中的一种逻辑容器,用于组织和分组存储设备(OSD)。
  • 权重:每个 OSD 和存储桶都有一个权重值,表示其存储容量或重要性。权重值影响数据对象的分配。
2. CRUSH 算法的主要特点
  • 无中心化:CRUSH 算法不需要中心化的管理节点,每个节点都可以独立计算数据对象的存储位置。
  • 可扩展性:CRUSH 算法支持动态添加或删除存储设备,而不会导致大量数据迁移。
  • 故障容忍:CRUSH 算法考虑了故障容忍性,确保数据的多个副本分布在不同的故障域中,提高数据的可靠性。
3. CRUSH 算法的工作原理
3.1 映射层次结构

CRUSH 算法使用一个层次化的映射结构,将数据对象映射到具体的存储设备(OSD)。这个层次结构通常包括以下几层:

  • 根节点(Root):最顶层的节点,代表整个存储集群。
  • 故障域(Failure Domain):通常对应于数据中心、机架或主机等物理位置,用于确保数据副本的分散。
  • 存储桶(Bucket):逻辑容器,用于组织和分组存储设备(OSD)。
  • 存储设备(OSD):实际的存储单元,负责存储数据对象。
3.2 权重分配

每个 OSD 和存储桶都有一个权重值,表示其存储容量或重要性。权重值决定了数据对象在选择存储位置时的偏好。例如,一个权重较高的 OSD 更有可能被选中存储数据对象。

3.3 哈希函数

CRUSH 算法使用哈希函数将数据对象的 ID 映射到一个数值,然后根据这个数值和层次结构中的权重值,计算出数据对象应该存储的具体位置。

3.4 选择存储位置

CRUSH 算法通过以下步骤选择数据对象的存储位置:

  1. 计算哈希值:使用哈希函数将数据对象的 ID 转换为一个数值。
  2. 选择根节点:从根节点开始,根据哈希值和权重值,选择一个子节点。
  3. 递归选择:在选定的子节点中,继续根据哈希值和权重值选择下一个子节点,直到达到存储设备(OSD)。
  4. 数据复制:根据配置的复制因子,选择多个存储设备(OSD)来存储数据对象的副本。
4. 故障容忍

CRUSH 算法通过以下机制确保数据的高可用性:

  • 故障域分离:数据的多个副本会被分散到不同的故障域中,确保即使某个故障域发生故障,数据仍然可用。
  • 动态调整:当存储设备(OSD)或存储桶发生变化时,CRUSH 算法会自动调整数据的分布,确保数据的均匀分布和高可用性。
5. 示例

假设我们有一个 Ceph 集群,包含两个机架(rack1 和 rack2),每个机架中有两个主机(host1 和 host2),每个主机上有两个 OSD(osd1 和 osd2)。CRUSH 算法可能会构建如下层次结构:

root (cluster)
├── rack1
│   ├── host1
│   │   ├── osd1
│   │   └── osd2
│   └── host2
│       ├── osd1
│       └── osd2
└── rack2├── host1│   ├── osd1│   └── osd2└── host2├── osd1└── osd2

当需要存储一个新的数据对象时,CRUSH 算法会从根节点开始,根据哈希值和权重值,逐步选择子节点,最终确定数据对象的存储位置。例如,数据对象可能会被存储在 rack1 的 host1 的 osd1 上,同时其副本可能会被存储在 rack2 的 host2 的 osd2 上,以实现故障域分离。 

简化的 Ceph OSD (Object Storage Device) 集群的数据存储过程:

1. 客户端请求

  • 客户端应用程序需要存储一个数据对象(例如,文件或块)。
  • 客户端通过网络连接到 Ceph 集群,通常是通过 Ceph 的 RADOS (Reliable Autonomic Distributed Object Store) 接口。

2. 获取集群地图

  • 客户端联系 Ceph Monitor 节点,获取最新的集群地图(Cluster Map)。集群地图包含了当前集群的拓扑结构、OSD 状态、PG 分配等信息。

3. 计算放置组 (PG)

  • 客户端根据数据对象的标识符(通常是对象ID)和集群地图中的 PG 映射表,计算出该对象所属的 PG。每个 PG 都映射到一组特定的 OSD,这组 OSD 负责存储该 PG 内的所有数据对象及其副本。

4. 确定主OSD

  • 根据 PG 映射表,客户端确定该 PG 的主OSD。主OSD 负责协调该 PG 内的数据写入操作。

5. 发送写入请求

  • 客户端将写入请求发送给主OSD,请求中包含要存储的数据对象。

6. 主OSD 处理请求

  • 主OSD 接收到写入请求后,将数据写入自己的本地存储中,并记录这次写入操作。

7. 同步副本

  • 主OSD 将写入请求转发给该 PG 对应的其他副本OSD。
  • 副本OSD 也执行相同的写入操作,将数据存储在各自的本地存储中。

8. 确认响应

  • 当所有副本OSD 成功完成数据写入操作后,它们会向主OSD 发送确认消息。
  • 主OSD 收集到所有副本OSD 的确认后,向客户端发送写入成功的响应。

9. 数据一致性

在整个过程中,Ceph 使用多种机制来保证数据的一致性和可靠性,例如:

  • 心跳检测:定期检查 OSD 的状态,确保它们正常运行。
  • 数据校验:定期进行数据校验和修复,确保数据的完整性。
  • 故障恢复:如果某个 OSD 失效,Ceph 会自动将数据重新分配到其他可用的 OSD 上,以保持数据的冗余度。

MON监控节点释意

在 Ceph 中,Monitor (MON) 节点确实负责维护集群的状态和元数据信息,但是它们的工作方式并不涉及传统意义上的“主从”选举。相反,Ceph MON 节点采用了一种无中心化的共识机制来确保集群的一致性和高可用性。以下是关于 MON 节点的一些关键点:

1. 无中心化共识

Paxos 或 Raft 协议:Ceph MON 节点使用 Paxos 或 Raft 这样的共识协议来达成一致。这些协议确保了在大多数节点同意的情况下,集群的状态和元数据信息是准确和一致的。
多数派原则:为了防止“裂脑”现象(即在集群分裂时无法达成多数派共识),Ceph 要求 MON 节点的数量必须是奇数个(通常是 3 个或 5 个)。这样,在某个 MON 节点失效时,剩余的节点仍然可以形成多数派,继续维持集群的正常运行。

2. 故障检测与恢复

故障检测:MON 节点之间定期进行心跳检查,以检测其他节点的健康状态。如果某个 MON 节点失效,其他节点会检测到这一点。
自动恢复:当某个 MON 节点失效后,剩余的 MON 节点会继续工作,并尝试重新建立集群的共识。一旦失效的 MON 节点恢复,它会从其他健康的 MON 节点同步最新的状态信息,重新加入集群。

3. 集群状态的维护

集群地图:MON 节点维护着集群的地图(Cluster Map),其中包括 OSD 地图、MON 地图、MDS 地图等。这些地图描述了集群中各个组件的状态和位置。
一致性更新:当集群状态发生变化(如新的 OSD 加入或某个 OSD 失效)时,MON 节点会更新集群地图,并将这些变化传播到所有相关的组件。

4. 选举机制

无明确的主节点:Ceph MON 节点没有明确的主节点概念。所有的 MON 节点都是平等的,共同维护集群的状态。
领导节点:虽然没有主节点,但在某些情况下,MON 节点会选举一个“领导者”(Leader)来协调某些操作。例如,在更新集群地图时,需要一个领导者来确保更新的一致性。但是,这个领导者并不是固定的,而是动态选举的。

总结

Ceph 的 MON 节点通过无中心化的共识机制来确保集群的一致性和高可用性。当某个 MON 节点失效时,剩余的 MON 节点会继续工作,并在必要时重新选举一个领导者来协调特定的操作。这种设计使得 Ceph 能够在单点故障的情况下继续保持正常运行,提高了系统的可靠性和稳定性。

MGR管理节点释意

Ceph 是一个开源的分布式存储系统,设计用于提供优秀的性能、可靠性和可扩展性。Ceph 能够提供对象存储、块存储以及文件系统接口,适用于各种存储需求。在 Ceph 集群中,Manager (MGR) 节点扮演着重要的角色,负责管理和监控集群的状态,并为用户提供有关集群健康状况和性能的信息。

MGR 节点的主要职责包括:

1. 监控和报告:MGR 节点持续收集关于 Ceph 集群各个方面的数据,如存储利用率、网络状态、性能指标等。这些信息可以通过 Ceph 的仪表板(Dashboard)或其他监控工具展示给用户。

2. 提供服务:除了基本的监控功能外,MGR 模块还可以提供额外的服务,比如:

  • 仪表板:允许管理员通过 Web 界面查看集群状态、配置设置等。
  • 性能分析:帮助识别集群中的瓶颈或性能问题。
  • 自动恢复:某些情况下,MGR 可以自动采取措施来恢复集群到健康状态。

3. 模块化设计:Ceph MGR 是高度模块化的,支持多种插件。这意味着可以根据需要启用不同的功能模块,以适应特定的应用场景或提高管理效率。

4. 高可用性:为了确保系统的稳定运行,通常会部署多个 MGR 节点。这些节点之间会进行选举,选出一个主 MGR 节点来执行任务。如果主节点失败,其他备用节点可以迅速接管其职责,保证服务的连续性。

5. 配置管理:MGR 还可以用来简化集群的配置管理工作,例如动态调整配置参数而无需重启整个集群。

        总之,Ceph 中的 MGR 管理节点是实现高效、可靠集群管理的关键组件之一。它不仅提供了丰富的监控和诊断工具,还支持灵活的服务扩展能力,有助于维护大型分布式存储系统的正常运作。

        在 Ceph 集群中,MGR(Manager)节点的数量并不强制要求是奇数个,主要是因为 MGR 节点的设计与 Monitor(MON)节点有所不同。MON 节点负责维护集群的逻辑时钟和状态图,因此它们需要形成一个法定多数(quorum)来防止“脑裂”现象——即集群分裂成两个或多个独立运作的部分,每个部分都认为自己是合法的主集群。为了避免这种情况,MON 节点通常建议部署为奇数个(如3个或5个),这样更容易达成多数共识。

        相比之下,MGR 节点的主要职责是提供管理和监控服务,而不是直接参与集群状态的决策过程。MGR 节点之间采用了一种领导者选举机制,即任何时候只有一个主 MGR 节点在工作,其余的作为备用。如果主 MGR 节点发生故障,集群中的其他 MGR 节点将自动选举出新的主节点继续提供服务。这种设计减少了对节点数量为奇数的需求,因为即使只有两个 MGR 节点,也能实现高可用性。

        然而,虽然理论上两个 MGR 节点就足够了,但在实际部署中,通常还是会配置三个或更多 MGR 节点,以增加系统的容错能力和稳定性。这样做可以在一个或多个节点出现故障时,仍然保持足够的冗余度和服务连续性。因此,虽然不是必须的,但在生产环境中推荐使用至少三个 MGR 节点来增强集群的可靠性。

Ceph基本查询命令

命令描述
ceph -s 或 ceph health detail查看集群的整体状态和健康状况,包括OSD、PG、Pool等关键信息
ceph osd stat查看OSD(对象存储守护进程)的状态,包括数量、状态分布等
ceph osd lspools 或 ceph osd pool ls列出集群中所有的存储池
ceph osd pool ls detail列出存储池的详细信息,包括名称、ID、副本数、状态等
ceph osd tree显示OSD的层次结构和归属关系,包括crush map的信息
ceph mon stat查看监控节点(MON)的状态,包括法定人数、健康状态等
ceph mon dump显示监控节点(MON)的详细信息,包括映射、状态等
ceph pg stat查看归置组(PG)的状态,包括数量、活跃/干净状态等
ceph pg dump显示归置组(PG)的详细映射信息
ceph osd df显示OSD的磁盘使用情况,包括总容量、已用容量、可用容量等
ceph df显示集群的总体磁盘使用情况,包括各个存储池的使用情况
ceph config dump查看集群的当前配置信息
ceph daemon osd.{osd-id} osd status查看特定OSD节点的运行状态,包括使用率、IO情况等
ceph daemon mon.{mon-id} mon_status查看特定监控节点的运行状态,包括monmap版本、选举状态等
ceph osd crush rule ls列出所有的CRUSH规则
ceph osd crush rule dump {rule-name}显示特定CRUSH规则的详细信息
ceph quorum_status查看监控节点的法定人数状态和选举状态
ceph osd in {osd-id}将OSD加入集群
ceph osd out {osd-id}将OSD从集群中逐出
ceph osd up {osd-id}启用OSD,使其接受读写请求
ceph osd down {osd-id}禁用OSD,不接受读写请求但保持在线
ceph -w实时监视Ceph集群的状态变化,包括OSD、PG、Pool等的状态更新
ceph orch device ls列出集群中所有被Orchestrator管理的设备的状态和信息
ceph orch host ls列出集群中所有被Orchestrator管理的主机(或节点)的状态和信息

Ceph OSD 操作命令总结

操作类型命令描述
创建新的 OSDsudo ceph-deploy disk zap <hostname> /dev/<device>清除指定设备上的数据,使其成为干净的磁盘。
sudo ceph-deploy osd create --data /dev/<device> <hostname>在指定设备上创建新的 OSD。
sudo mkfs.xfs /dev/<device>格式化磁盘为 XFS 文件系统。
sudo mkdir /var/lib/ceph/osd/ceph-<new_osd_id>创建用于挂载新文件系统的目录。
sudo mount /dev/<device> /var/lib/ceph/osd/ceph-<new_osd_id>挂载格式化后的磁盘到新创建的目录。
sudo ceph-osd -i <new_osd_id> --mkfs --mkkey初始化新的 OSD 并生成密钥。
sudo ceph auth add osd.<new_osd_id> osd 'allow *' mon 'allow profile osd' -i /var/lib/ceph/osd/ceph-<new_osd_id>/keyring将新创建的 OSD 密钥添加到 Ceph 集群。
sudo systemctl start ceph-osd@<new_osd_id>.service启动新的 OSD 服务。
sudo systemctl enable ceph-osd@<new_osd_id>.service启用新的 OSD 服务,使其在系统启动时自动启动。
删除现有的 OSDsudo systemctl stop ceph-osd@<osd_id>.service停止指定的 OSD 服务。
sudo systemctl disable ceph-osd@<osd_id>.service禁用指定的 OSD 服务,防止其在系统启动时自动启动。
ceph osd out <osd_id>将指定的 OSD 从集群中移出。
ceph osd crush remove osd.<osd_id>从 CRUSH 地图中删除指定的 OSD。
ceph auth del osd.<osd_id>删除指定的 OSD 的认证密钥。
ceph osd rm <osd_id>从集群中删除指定的 OSD。
sudo umount /var/lib/ceph/osd/ceph-<osd_id>卸载指定的 OSD 挂载目录。
sudo rm -rf /var/lib/ceph/osd/ceph-<osd_id>删除指定的 OSD 目录。
sudo ceph-deploy disk zap <hostname> /dev/<device>清除指定设备上的数据,使其成为干净的磁盘。
管理 OSD 状态ceph osd stat显示 OSD 的简要状态信息。
ceph osd tree显示 OSD 的树状结构,包括 OSD、主机和机架等层次关系。
ceph osd df显示 OSD 的使用情况。
ceph osd dump显示 OSD 的详细配置信息。
控制 OSD 服务ceph osd out <osd_id>将指定的 OSD 从集群中移出,使其不再参与数据的读写操作。
ceph osd in <osd_id>将指定的 OSD 重新加入集群。
ceph osd down <osd_id>标记指定的 OSD 为离线状态。
ceph osd up <osd_id>标记指定的 OSD 为在线状态。
管理 CRUSH 映射ceph osd crush add-bucket <bucket_name> <type>添加一个新的 CRUSH 桶。
ceph osd crush move <item> <path>移动 CRUSH 映射中的项。
ceph osd crush remove <item>从 CRUSH 映射中删除项。
ceph osd crush reweight <item> <weight>调整 CRUSH 映射中项的权重。
管理流量控制ceph osd set <flag>设置全局标志,控制 OSD 的行为。
ceph osd unset <flag>取消全局标志。
日志和调试ceph osd log <osd_id>查看指定 OSD 的日志。
ceph osd perf显示 OSD 的性能统计信息。
维护模式ceph osd maint enter <osd_id>将指定的 OSD 进入维护模式。
ceph osd maint exit <osd_id>将指定的 OSD 退出维护模式。

常用标志

  • noin: 阻止新的 OSD 加入集群。
  • noup: 阻止 OSD 状态从 down 到 up
  • norecover: 阻止数据恢复操作。
  • norebalance: 阻止数据再平衡操作。
  • nobackfill: 阻止数据回填操作。
  • pause: 暂停所有 OSD 操作。

Ceph OSD 流量控制命令总结

设置标志
# 阻止新 OSD 加入
ceph osd set noin# 阻止 OSD 状态变化
ceph osd set noup# 阻止数据恢复
ceph osd set norecover# 阻止数据再平衡
ceph osd set norebalance# 阻止数据回填
ceph osd set nobackfill# 暂停所有 OSD 操作
ceph osd set pause
取消标志
# 取消阻止新 OSD 加入
ceph osd unset noin# 取消阻止 OSD 状态变化
ceph osd unset noup# 取消阻止数据恢复
ceph osd unset norecover# 取消阻止数据再平衡
ceph osd unset norebalance# 取消阻止数据回填
ceph osd unset nobackfill# 取消暂停所有 OSD 操作
ceph osd unset pause
使用场景
  • 维护操作:在执行维护操作(如更换磁盘、升级软件等)时,设置这些标志可以防止不必要的数据迁移和恢复操作,确保维护过程的顺利进行。
  • 故障排除:在故障排除时,设置这些标志可以临时冻结集群的部分操作,以便更好地诊断问题。
  • 数据迁移:在进行大规模数据迁移时,设置这些标志可以控制数据迁移的速度和时机,避免对集群性能造成过大影响。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 用Go语言构建健壮的并发系统:深入理解错误传播与处理
  • oracle表的类型
  • 变量的作用域和生命周期
  • 定义可引用的 CI/CD 配置文件中的输入参数
  • JavaSE--集合总览02:单列集合Collection的体系之一:List
  • CLI示例(V2R8至V2R19C00版本):直连二层组网直接转发【AP+上层网络,增加AP下行口有线接入】
  • MyBatis 基本操作 - XML版
  • 尚品汇-秒杀成功下单接口、秒杀结束定时任务-清空缓存数据(五十四)
  • html文件指什么
  • 使用k8s搭建mariadb+nginx+wordpress
  • 【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第一篇-原理】
  • 【大模型教程】基于 InternLM 和 LangChain 搭建知识库助手
  • Java后端框架---Spring
  • R18 NES 之SSB-less SCell operation for inter-band CA
  • [ IDE ] SEGGER Embedded Studio for RISC-V
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 分享的文章《人生如棋》
  • 【React系列】如何构建React应用程序
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • express + mock 让前后台并行开发
  • If…else
  • JavaScript类型识别
  • Java多线程(4):使用线程池执行定时任务
  • Linux中的硬链接与软链接
  • Mysql5.6主从复制
  • rabbitmq延迟消息示例
  • uva 10370 Above Average
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 驱动程序原理
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 收藏好这篇,别再只说“数据劫持”了
  • 我的zsh配置, 2019最新方案
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 学习笔记:对象,原型和继承(1)
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #NOIP 2014# day.2 T2 寻找道路
  • #pragma pack(1)
  • $.proxy和$.extend
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (接口自动化)Python3操作MySQL数据库
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (学习总结16)C++模版2
  • (正则)提取页面里的img标签
  • (转)关于多人操作数据的处理策略
  • ***测试-HTTP方法