ceph对象存储使用总结

news2024/12/26 22:52:55

ceph对象存储使用总结

大纲

  • 基础概念
  • 安装对象存储网关RADOS网关
  • 配置对象存储网关RADOS网关
  • 修改RADOS网关端口
  • 修改支持https访问RADOS网关
  • 使用s3cmd操作对象存储
  • Ceph dashboard管理RADOS网关
  • 使用java程序操作对象存储

基础准备

  • 操作系统 ubuntu~18.04
  • ceph版本 Octopus v15.2.17
  • ceph-deploy 2.0.1
  • ceph集群搭建见 《ceph安装搭建总结.md》

基础概念

对象存储以对象方式管理数据 。 每一个对象存储如下内容:1数据、2元数据、 3唯一的标识符 。 对象存储不能直接被操作系统当成本地或者远程文件系统访问 (注意 这里与块存储不同 《ceph块使用总结.md》) 。只能在应用程序级别通过API访问 (例如 S3或Swift ,Ceph admin api)

整个对象存储架构如下图
在这里插入图片描述

这里假设已经搭建好一个ceph集群。(ceph集群搭建见 《ceph安装搭建总结.md》)。接下来的步骤就是创建RADOS网关

RADOS网关(RGW接口)

RADOS网关的作用就是提供对象存储接口,主要使用了librgw 与 librados库,并且兼容S3 SwiftAPI接口,允许应用程序操作Ceph对象存储

生产环境部署:

建议使用专用的服务器上配置RGW ,如果对象存储工作负载不大,可以使用任意一台MON作为RGW节点

安装RADOS网关

将使用搭建集群时安装ceph-deploy的机器ceph1作为跳板机去到rgw机器上安装 RADOS网关

主机ceph1 上 ceph-deploy 版本2.01

 ceph-deploy --version

在这里插入图片描述

主机rgw 上未安装任何ceph相关软件

在这里插入图片描述

step1 配置网络和ssh免密登录

配置网络

修改主机ceph-controller host文件 添加

vi /etc/hosts
192.168.0.73 ceph-rgw

在这里插入图片描述

网络已经ping通

ssh免密登录

因为在创建集群的时候已经生成了ssh 公私钥所以可以不再执行ssh-keygen命令

直接使用ssh-copy-id命令复制秘钥

ssh root@rgw

在这里插入图片描述

到此基础网络与ssh配置完成

step2 安装ceph相关软件

ceph-deploy install ceph-rgw

注意 ceph-rgw主机可能需要安装python (apt install python)

在这里插入图片描述

安装完成后会自动安装radosgw,登录到ceph-rgw主机可以看到

radosgw -v
dpkg -l |grep radosgw

在这里插入图片描述

到此rgw主机上搭建RADOS网关的相关软件已经安装完成

step3 部署RADOS网关服务

在ceph-controller主机上执行

格式 ceph-deploy rgw create 【主机名称】
ceph-deploy --overwrite-conf rgw create ceph-rgw

–overwrite-conf 参数含义:
以当前主机ceph-deploy的ceph.conf配置为准,替换掉ceph-rgw节点上的/etc/ceph.conf (如果没有就新建)

在这里插入图片描述

可以看到rgw对应的服务

systemctl start ceph-radosgw@rgw.ceph-rgw
systemctl enable ceph.target

浏览器上访问 http://192.168.0.73:7480/ 可以看到信息
在这里插入图片描述

到此RADOS网关服务安装成功

RADOS网关服务服务部署成功后可以看到生成对应的osd池

在这里插入图片描述

default.rgw.control        #控制器信息
default.rgw.meta           #记录元数据
default.rgw.log            #日志信息
default.rgw.buckets.index  #为rgw的bucket信息
default.rqw.buckets.data   #是实际存储的数据信息

RADOS网关服务配置

RADOS网关守护进程内部就由Civeweb实现,通过对Civeweb的配置可以完成对RADOS网关的基本管理

服务的格式为: ceph-radosgw@rgw.<rgw服务器主机名称>

例如刚才创建的RADOS网关服务器主机名称为rgw 所以服务名称为 ceph-radosgw@rgw.ceph-rgw
查看服务状态
systemctl status ceph-radosgw@rgw.ceph-rgw

在这里插入图片描述

journalctl -fu ceph-radosgw@rgw.ceph-rgw 

修改配置有两种方法

  • 1 在跳板机ceph-controller 上执行ceph-deploy config push
  • 2 在RADOS网关机器上修改 /etc/ceph/{cluster}.conf文件

端口配置

这里使用在跳板机ceph-controller 上执行ceph-deploy config push 方法

ceph-deploy config push命令操作的是当前文件夹下的ceph.conf文件

修改ceph.conf文件加入

[client.rgw.ceph-rgw]
rgw_host = ceph-rgw
rgw_frontends = "civetweb port=8080 num_threads=500 request_timeout_ms=60000"

配置说明

  • rgw_host:对应的RRADOS网关名称或者IP地址

  • rgw_frontends:配置一些选项信息

    num_threads:最大并发连接数,默认为50,根据需求调整,通常在生产集群环境中此值应该更大。
    request_timeout_ms:发送与接收超时时长,以ms为单位,默认为30000。
    access_log_file:访问日志路径,默认为空。
    error_log_file:错误日志路径,默认为空。

在ceph.conf文件所在文件夹执行push命令把配置推送到对应的ceph-rgw主机上

ceph-deploy --overwrite-conf config push ceph-rgw
注意使用--overwrite-conf 参数覆盖已存在的配置

在这里插入图片描述

进入ceph-rgw主机上查看配置文件,已经被修改

在这里插入图片描述

重启ceph-radosgw@rgw.ceph-rgw 服务

systemctl restart ceph-radosgw@rgw.ceph-rgw

浏览器访问端口已经改变

在这里插入图片描述

https配置

这里使用在RADOS网关机器上修改 /etc/ceph/{cluster}.conf文件方法

直接使用已经存在的证书与私钥,将证书与私钥合并成pem文件

cat medcrab.com.key medcrab.com.crt > medcrab.pem

在这里插入图片描述

修改/etc/ceph/ceph.conf 文件

[client.rgw.ceph-rgw]
rgw_host = ceph-rgw
rgw_frontends = "civetweb port=8080+443s ssl_certificate=/etc/ceph/PKI/medcrab.pem num_threads=500 request_timeout_ms=60000"
rgw_dns_name = oss.medcrab.com

配置说明:

  • port:如果是https端口,需要在端口后面加一个s 这里使用+号表示同时开启http8080端口 和https 443端口
  • ssl_certificate:指定证书的路径。
  • rgw_dns_name:证书配置了域名 这里使用证书对应的域名

重启ceph-radosgw@rgw.ceph-rgw 服务

systemctl restart ceph-radosgw@rgw.ceph-rgw

在这里插入图片描述

使用Switchhost修改自己电脑的host映射,将oss.medcrab.com域名映射到192.168.0.73IP

在这里插入图片描述

浏览器访问发现已经可以支持https了

在这里插入图片描述

http8080端口也可以继续访问
在这里插入图片描述

使用s3cmd操作对象存储

使用ceph对象存储,不能直接被操作系统当成本地或者远程文件系统访问,只能在应用程序级别通过API访问

ceph RADOS网关兼容AmazonS3 所以可以使用s3cmd来操作ceph对象存储

https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/Welcome.html

step1 创建radosgw用户

使用 radosgw-admin命令创建radosgw用户 (在ceph1跳板机上)

radosgw-admin user create --uid="oss-user-1" --display-name="oss-user1"

创建后可以 access_key 与 secret_key (注意access_key 与 secret_key 后续的s3cmd配置时需要使用

 "keys": [
    {
        "user": "oss-user-1",
        "access_key": "2ANNU4UIHQ7HHOPC3MEM",
        "secret_key": "UAVJ5gtzGrOZu4jGtU23WBWDYZYb1Am2sE8wY2BS"
    }
],

在这里插入图片描述

可以使用 radosgw-admin user --uid=“oss-user-1” info 查看用户信息

step2 安装s3cmd

apt install s3cmd

在这里插入图片描述

安装完成后首先使用 s3cmd --configure 配置s3cmd

s3cmd --configure 

在这里插入图片描述

在这里插入图片描述

到此 s3cmd安装配置完成

step3 使用s3cmd

s3cmd 常用的使用命令

创建Buckets(桶)桶的格式是s3://【桶的名称】
s3cmd mb s3://oss-bucket1

列出所有Buckets(桶)
s3cmd ls

保存数据到指定的桶
s3cmd put 1.txt s3://oss-bucket1  单个文件上传
s3cmd put *zip s3://oss-bucket1  批量匹配上传

列出桶中的数据
s3cmd ls s3://oss-bucket1

下载数据
s3cmd get s3://oss-bucket1/1.txt 1.txt  单个文件下载
s3cmd get s3://oss-bucket1//* ./  批量文件下载

查看桶的空间
s3cmd du -H s3://oss-bucket1

删除文件
s3cmd del s3://oss-bucket1/1.txt

在这里插入图片描述

匿名访问数据

目前匿名方式还无法访问文件

浏览器匿名访问数据的请求格式为 http://rgw服务器IP:端口/Buckets(桶)名称/文件名称

例如访问 
https://oss.medcrab.com/oss-bucket1/1.txt

在这里插入图片描述

使用s3cmd setpolicy 修改s3://oss-bucket1 的访问权限

s3cmd setpolicy oss-policy.json s3://oss-bucket1

oss-policy.json内容如下

{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Effect": "Allow",
          "Principal": "*",
          "Action": "s3:GetObject",
          "Resource": ["arn:aws:s3:::oss-bucket1/*"]														            
       }
    ]
}


Resources:指定对应的Buckets。必填
Actions:要授予的动作,CreateBucket、DeleteObject、GetObject、PubObject。必填
Effect:要授予的操作效果是允许(allow)还是拒绝(deny),默认为拒绝访问所有的资源,必填。
Principal: 要授权的目的账号,必填 可以使用* 代表所有

https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/example-bucket-policies.html

在这里插入图片描述

再次访问 https://oss.medcrab.com/oss-bucket1/1.txt

在这里插入图片描述

Ceph dashboard管理RADOS网关

Ceph dashboard 的安装搭建参考 ceph安装搭建总结

点击Object Gateway菜单还暂时无法操作

在这里插入图片描述

需要创建一个用户,并配置Ceph dashboard 指定RRADOS网关

step1 创建用户

radosgw-admin user create --uid=rgw --display-name=rgw --system

在这里插入图片描述

准备 access_key ,secret_key两个文件,内容就是创建用户时access_key 与secret_key的内容
在这里插入图片描述

step2 配置Ceph dashboard

#指定access_key
ceph dashboard set-rgw-api-access-key -i access_key
#指定secret_key
ceph dashboard set-rgw-api-secret-key -i secret_key
# 关闭https
ceph dashboard set-rgw-api-ssl-verify False
# 指定rgw-api-host
ceph dashboard set-rgw-api-host 192.168.0.72
# 指定rgw-api-端口
ceph dashboard set-rgw-api-port 8080
# 使用http
ceph dashboard set-rgw-api-scheme http
# 指定用户
ceph dashboard set-rgw-api-user-id rgw

在这里插入图片描述

刷新 Object Gateway菜单可以看到内容

在这里插入图片描述

使用java程序操作对象存储

项目pom.xml文件中添加依赖

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-core</artifactId>
    <version>1.12.381</version>
</dependency>

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-s3</artifactId>
    <version>1.12.381</version>
</dependency>

java代码

package com.my.study.th3.ceph.aws;

import java.io.File;
import java.util.List;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.BucketPolicy;
import com.amazonaws.services.s3.model.S3Object;
import com.my.study.utils.DateUtil;
/**
 * 此代码对应 《ceph使用总结.md》
 * @author liuyijiang
 *
 */
public class TestCephByAwsS3 {

	/** * 【你的 access_key】 */
	private static final String AWS_ACCESS_KEY = "6W4L0AZJZY92ZZO93MMT";
	
	/** * 【你的 aws_secret_key】 */
	private static final String AWS_SECRET_KEY = "gJslyAsEtYHYtlwUV6pcvrlGsQl9OI2aeQB7WBBK";
	
	/** * 【你的 endpoint】 */
	private static final String ENDPOINT = "http://192.168.0.124:7480";
	
	
	public void test1() {
		System.out.println("===============");
//     已经作废的创建	AmazonS3 客户端方法	
//		AWSCredentials awsCredentials = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);
//	    ClientConfiguration clientConfig = new ClientConfiguration();
//	    clientConfig.setProtocol(Protocol.HTTP);
//	    AmazonS3 conn = new AmazonS3Client(awsCredentials, clientConfig);
//	    conn.setEndpoint(ENDPOINT);
		
		
		AmazonS3ClientBuilder clientBuilder = AmazonS3ClientBuilder.standard();
        ClientConfiguration config = new ClientConfiguration();
        config.setProtocol(com.amazonaws.Protocol.HTTP);
        config.setConnectionTimeout(10000);
        config.setSignerOverride("S3SignerType");
        config.setRequestTimeout(10000);
        
        //配置账号密码
        AWSCredentials acre = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);
        AWSCredentialsProvider acrep = new AWSStaticCredentialsProvider(acre);
        AwsClientBuilder.EndpointConfiguration econfig = new AwsClientBuilder.EndpointConfiguration(ENDPOINT, null);

        clientBuilder.setClientConfiguration(config);
        clientBuilder.setCredentials(acrep);
        clientBuilder.setEndpointConfiguration(econfig);
        AmazonS3 client = clientBuilder.build();
		
        
        boolean needCreate = true;
        
	    /**
	     * 查看access_key对应用户创建的 所有的bucket
	     * 
	     * 对应命令  s3cmd ls
	     */
	    List<Bucket> buckets = client.listBuckets();
	    for (Bucket bucket : buckets) { 
	        System.out.println("名称:" + bucket.getName() + "  所属人:" + bucket.getOwner()  + "  创建时间:" + DateUtil.dateToString(bucket.getCreationDate())); //  StringUtils.fromDate(bucket.getCreationDate())
	        if(bucket.getName().equals("static-prod")) {
	        	needCreate = false;
	        }
	        //获取策略 
	        BucketPolicy policy =  client.getBucketPolicy(bucket.getName());
	        System.out.println(policy.getPolicyText());
	    }
	    
	    /**
	     * 创建buckets
	     * 
	     * 对应命令  s3cmd mb s3://static-prod
	     */
	    String bucketName = "static-prod";
	    if(needCreate) {
	 	    client.createBucket(bucketName);
	 	   System.out.println("===创建成功===");
	 	    
	 	   //设置buckets策略
	 	   //注意 Version 各式2012-10-17
	 	    String policyText = "{\r\n"
	 	    		+ "  \"Version\": \"2012-10-17\",\r\n"
	 	    		+ "  \"Statement\": [\r\n"
	 	    		+ "      {\r\n"
	 	    		+ "          \"Effect\": \"Allow\",\r\n"
	 	    		+ "          \"Principal\": \"*\",\r\n"
	 	    		+ "          \"Action\": \"s3:GetObject\",\r\n"
	 	    		+ "           \"Resource\": [\"arn:aws:s3:::static-prod/*\"]  }]\r\n"
	 	    		+ "}";
	 	    
		    client.setBucketPolicy(bucketName, policyText); // 创建策略测试失败
	 	    System.out.println("===策略更新完成===");
	 	    
		    //可指定分区 适合亚马逊的对象存储  操作ceph不需要
//		    String region = "";
//		    CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName,region);
//		    client.createBucket(createBucketRequest);
	 	    
	    }
	    
	    
	    
	    
	    /**
	     * 删除buckets
	     * 
	     * s3cmd rb  s3://static-prod
	     */
	    //client.deleteBucket(bucketName);
	    String key = "p1.png";
	    boolean hasObj = false;
	    try {
	    	/**
	    	 * 注意 这里如果没有数据会404会抛异常
	    	 * 
	    	 * http://192.168.0.124:7480/static-prod/p1.png
	    	 */
	    	S3Object obj = client.getObject(bucketName, key);
	    	System.out.println(obj.getKey() + " TaggingCount" + obj.getTaggingCount()  + "  Location:" + obj.getRedirectLocation());
	    	hasObj = true;
	    } catch(Exception e) {
	    	
	    }
	    if(!hasObj) {
	    	 File file = new File("D:\\giteecode\\my-study-demo\\src\\main\\java\\com\\my\\study\\th3\\ceph\\aws\\p1.png");
	 	    client.putObject(bucketName, key, file);
	    	System.out.println("保存文件 p1.png");
	    }
	    
	}
	
	public static void main(String[] args) {
		TestCephByAwsS3 t = new TestCephByAwsS3();
		t.test1();
	}
	
}

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

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

相关文章

适用于 3DS Max 和 Cinema 4D 的 Chaos Corona 10重磅推出!

Chaos 发布了 Corona 10&#xff0c;适用于3DS Max和Cinema 4D 的渲染器的最新版本 &#xff01;Corona 10 对软件的多项现有功能进行了更新&#xff0c;包括贴花、体积渲染、景深和程序云。 目前渲云云渲染已支持Corona 10&#xff0c;支持批量渲染&#xff0c;批量出结果&am…

chatgpt赋能python:介绍Python语言

介绍Python语言 Python是一门易学易用的编程语言&#xff0c;它被广泛应用于各种领域&#xff0c;包括数据科学、机器学习、人工智能、Web开发等。自1991年首次推出以来&#xff0c;Python不断演进和发展&#xff0c;如今已经成为行业内一种不可或缺的编程语言。它在可读性和语…

chatgpt赋能python:Python词汇量为什么很重要?

Python词汇量为什么很重要&#xff1f; 作为一个有10年Python编程经验的工程师&#xff0c;我有着非常深刻的体会&#xff0c;词汇量对于掌握这门编程语言来说是非常重要的。在这篇文章中&#xff0c;我将重点讨论Python词汇量为什么很重要&#xff0c;以及如何提升你的Python…

STM32的五个时钟源

①HSI是高速内部时钟&#xff0c;RC振荡器&#xff0c;频率为8MHz。 ②HSE是高速外部时钟&#xff0c;可接石英/陶瓷谐振器&#xff0c;或者接外部时钟源&#xff0c;频率范围为4MHz~16MHz。 ③LSI是低速内部时钟&#xff0c;RC振荡器&#xff0c;频率为40kHz。 ④LSE是低速外…

2核4G服务器_4M带宽_CPU性能测评_60G系统盘

阿里云2核4G服务器297元一年、4M公网带宽、60G系统盘&#xff0c;阿里云轻量应用服务器2核4G4M带宽配置一年297.98元&#xff0c;2核2G3M带宽轻量服务器一年108元12个月&#xff0c;如下图&#xff1a; 目录 阿里云2核4G4M轻量应用服务器 2核4G服务器限制条件 轻量服务器介…

使用Spring Boot、MyBatis Plus和Elasticsearch的简单示例

下面是一个使用Spring Boot、MyBatis Plus和Elasticsearch的简单示例&#xff1a; 首先&#xff0c;在pom.xml文件中添加以下依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elast…

《Pytorch深度学习和图神经网络(卷 1)》学习笔记——第五章

全连接神经网络 隐藏层的节点数决定了模型拟合能力&#xff0c;如果在单隐藏层设置足够多的节点&#xff0c;理论上可以拟合世界上各种维度的数据进行任意规则的分类&#xff0c;但会过拟合。 隐藏层的数量决定了其泛化能力&#xff0c;层数越多&#xff0c;推理的能力越强&am…

【前端工具】使用Echats生成关系图谱,可展开折叠

目录 一、需求背景与效果 二、echarts源码 一、需求背景与效果 根据服务关系制作关系图谱&#xff0c;echarts官方关系图没有想要的案例&#xff0c;网上也没有好的效果&#xff0c;故参考网上已有的部分案例&#xff0c;自行写了一个&#xff0c;效果还不错。 当前echarts…

Centos7单机安装Redis

安装Redis依赖 Redis是基于C语言&#xff0c;因此首先需要安装Redis所需要的gcc依赖&#xff1a; yum install -y gcc tcl ​ 上传安装包并解压 上传安装包redis-6.2.12至/home目录下 ​ # 解压 tar -xzf redis-6.2.12.tar.gz # 安装 cd redis-6.2.12 make && mak…

react ant table设置动态scroll,且某些列的长度固定

设置scroll x的值为列的个数*100 1.代码 const columns [ {title: 料号描述,dataIndex: itemDesc,align:left,width: 200,ellipsis: true,} ]<EditableProTableclassName"details-table"columns{columns}loading{loading}rowKey"id"value{dataSource}…

C++笔记之自引用结构体

C笔记之自引用结构体 code review! 文章目录 C笔记之自引用结构体1.在结构体中引用相同类型的结构体&#xff0c;并且可以使用指针或引用来实现。2.自引用结构体构建链表3.自引用结构体构建二叉树附:代码随想录——链表定义附:代码随想录——二叉树定义 1.在结构体中引用相同…

分布式幂等问题解决方案

目录 一 背景 二 什么是幂等 三 解决方案三部曲 第一部曲&#xff1a;识别相同请求 第二部曲&#xff1a;列出并减少副作用的分析维度 第三部曲&#xff1a;识别细粒度副作用&#xff0c;针对性设计解决方案 四 总结 一 背景 分布式系统由众多微服务组成&#xff0c;微…

从0到1搭建Springboot整合Quartz定时任务框架(保姆级教学+Gitee源码)

前言&#xff1a;最近学习了目前主流的若依框架&#xff0c;这是一个非常优秀的开源项目&#xff0c;故此我这边把它的源码全部剖析了一遍&#xff0c;简化了它的框架&#xff0c;我会通过这篇博客详细讲解我是如何进行推敲和从0到1搭建这个项目的流程。 目录 一、Quartz简介 …

Java并发(十二)----线程应用之多线程解决烧水泡茶问题

1、背景 统筹方法&#xff0c;是一种安排工作进程的数学方法。它的实用范围极广泛&#xff0c;在企业管理和基本建设中&#xff0c;以及关系复杂的科研项目的组织与管理中&#xff0c;都可以应用。 怎样应用呢&#xff1f;主要是把工序安排好。 比如&#xff0c;想泡壶茶喝。…

【前后端分离开发及项目部署流程】

文章目录 前后端分离开发技术1 前后端分离开发1.1 介绍1.2 开发流程1.3 前端技术栈&#xff08;了解&#xff09; 2 Yapi&#xff08;定义API接口&#xff09;2.1 介绍2.2 使用 3 Swagger3.1 介绍3.2 使用方式3.3 常用注解 4 项目部署4.1 部署架构4.2 部署环境说明4.3 部署前端…

chatgpt赋能python:如何使用Python访问共享目录——让共享变得简单易行

如何使用Python访问共享目录 —— 让共享变得简单易行 作为一种高效而强大的编程语言&#xff0c;Python拥有各种各样的应用。其中一个非常重要的应用场景就是对共享目录的访问和操作。无论是在家庭网络&#xff0c;企业内网或者云存储平台&#xff0c;共享目录的重要性毋庸置…

两个链表的入环节点(java)

两个链表的入环节点 两个链表的入环节点解题思路代码演示 链表相关的题 两个链表的入环节点 给定两个可能有环也可能无环的单链表&#xff0c;头节点head1和head2 请实现一个函数&#xff0c;如果两个链表相交&#xff0c;请返回相交的第一个节点。如果不相交返回null 要求如果…

ATTCK(一)之为什么要学习ATTCK

ATT&CK 简介 本系列旨在介绍网络红蓝对抗领域最好的ATT&CK矩阵模型&#xff0c;以期帮助有意愿深耕在红蓝对抗领域的人员能系统性的掌握红蓝对抗领域的知识和经验。本系列将详细ATT&CK的起源、发展历史&#xff0c;ATT&CK矩阵相对其他High-Level红蓝对抗模型…

Redis7【② Key通用命令 十大数据类型】

1 Key的通用命令 redis命令不区分大小写&#xff0c;但是key是区分大小写的。没有返回值的命令执行成功会返回1&#xff0c;失败返回0。 1. KEYS 查看所有的key&#xff0c;返回值是一个数组 2. EXISTS EXISTS key [key ...]&#xff1a;返回给定的key中已存在的个数&#xf…

前端Vue自定义验证码密码登录切换tabs选项卡标签栏标题栏 验证码登录模版 密码登录模版

前端Vue自定义验证码密码登录切换tabs选项卡标签栏标题栏 验证码登录模版 密码登录模版&#xff0c; 请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13221 效果图如下&#xff1a; 实现代码如下&#xff1a; # cc-selectBox #### 使用方法 使…