Minio使用教程

Minio介绍

Minlo是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。 对于中小型企业,如果不选择存储上云,那么 MinIO 是个不错的选择,麻雀虽小,五脏俱全。当然 MinIO 除了直接作为对象存储使用,还可以作为云上对象存储服务的网关层,无缝对接到 Amazon S3 等。 优点:

  • 部署简单:一个single二进制文件即是一切,还可支持各种平台。

  • Minio支持海量存储,可按zone扩展(原zone不受任何影响),支持单个对象最大5TB;

  • 兼容Amazon S3接口,充分考虑开发人员的需求和体验;

  • 读写性能优异

Minio基础概念

概念名称对应含义解释
Object存储的基本对象;比如文件、图片等等
Bucket用于存储 Object 的逻辑空间;相互之间互相隔离;类似于系统中的顶层文件夹
Drive即存储数据的磁盘;所有的对象数据都会存储在 Drive 里面
Set即一组 Drive 的集合;分布式部署根据集群规模自动划分一个或多个 Set

Linux安装Minio

1.获取minio安装包

wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20241029160148.0.0-1.x86_64.rpm -O minio.rpm

2.安装minio

rpm -ivh minio.rpm


Minio配置

1.修改minio服务配置文件

注释Type、User、Group

修改后的文件如下:

[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
#Type=notify
WorkingDirectory=/usr/local
#User=minio-user
#Group=minio-user
ProtectProc=invisible
EnvironmentFile=-/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
LimitNOFILE=1048576
MemoryAccounting=no
TasksMax=infinity
TimeoutSec=infinity
SendSIGKILL=no
[Install]
WantedBy=multi-user.target

参数解释:

AssertFileIsExecutable:可以在此参数声明的配置文件中添加minio服务启动时所需一些参数

ExecStart:该参数用于配置Minio服务的启动命令,其中$MINIO_OPTS$MINIO_VOLUMES,均引用于EnvironmentFile中的变量。

Restart:设置服务在失败时自动重启,这里是always,意味着总是重启。

2.配置

1.编写EnvironmentFile中指定路径下的配置文件

vim /etc/default/minio

MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
MINIO_VOLUMES=/data
MINIO_OPTS="--console-address :9001"

解释:

  • MINIO_ROOT_USER:登录后台管理平台的用户名

  • MINIO_ROOT_PASSWORD:登录后台管理平台的密码

  • MINIO_VOLUMES:指定数据存储路径,需确保指定的路径是存在的

  • MINIO_OPTS:指定管理页面的地址的端口号

2.创建minio数据存储路径
mkdir /data
3.防火墙设置开放端口
#开放minio的9000和9001端口
firewall-cmd --zone=public --add-port=9000/tcp --add-port=9001/tcp --permanent
#重新加载防火墙规则
firewall-cmd --reload
#查看开放的端口
firewall-cmd --list-ports
4.启动minio服务
#设置minio服务自启动
systemctl enable minio
#启动minio服务
systemctl start minio
#查看minio服务状态
systemctl status minio

Minio后台管理系统使用

账号密码就是etc/default/minio文件里面配置的MINIO_ROOT_USERMINIO_ROOT_PASSWORD


介绍

存储桶管理界面介绍

Access Policy:访问策略

  • public:允许所有人对该存储桶进行读写操作

  • private:只允许所有者操作该存储桶,其他人不能读写该存储桶

  • custom:自定义存储桶的访问权限,如:只允许所有者写,但允许所有人读,自定义访问权限有格式要求,格式为JSON

Encryption:加密策略,可选值:Disabled、SSE-S3、SSE-KMS

Reported Usage:存储桶使用情况,即使用的内存大小

Quota:配置存储桶限制的数据量

Browse Bucket:浏览存储桶列表


存储桶列表界面介绍

Upload File:上传文件

Upload Folder:上传文件夹

Refresh:刷新

Download:下载文件

Share:共享图片(可以设置共享的连接的时效性)

Preview:查看图片

Delete:删除图片

Object Info:对象信息,包含了名称、大小、上次修改时间、内容类型等等信息


文件上传

创建
1.创建存储桶

创建时可选值

Bucket Name:存储桶名称

Versioning:允许在同一键下保留同一对象的多个版本。

Object Locking:确保一旦对象存储在特定的存储桶中,它们就不能被删除,这是为了满足数据保留和法律保留的要求。这种特性或策略只能在创建存储桶的时候设置,一旦存储桶被创建,就不能再对这个特性进行更改。

Quota:限制存储桶中的数据量。

2.上传图片

1.选择Upload File

2.选择要上传的文件

3.上传后可以看到界面的右上角有文件的上传进度


访问上传的图片

访问minio的存储桶的图片的url格式就是

http://主机ip:9000/存储桶/文件名

首先在存储桶浏览列表复制存储桶中文件的路径

然后再URL打上自己的Minio服务的主机IP加上端口号最后拼接上我们复制的文件地址

192.168.181.31:9000/test/房间-卧室-1.jpg

访问报错?

原因分析:因为我们的存储桶的访问权限为私有的所以我们访问不了这个存储桶中的图片\文件,所以我们要修改访问权限

步骤:

1.点击存储桶浏览列表右上角的设置

2.编辑存储桶的访问权限,我们选择自定义权限

再存储桶管理界面介绍中就介绍到了存储桶的访问权限,所以这里我们选择自定义,权限为:只允许所有者写,但允许所有人读,但是

自定义访问权限,需要使用一个规定格式的JSON字符串进行描述,具体格式可参考官方文档。

如:允许(Allow)所有人(*)读取(s3:GetObject)指定桶(test)的所有内容

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

按照上图片进行配置之后,再去访问图片,就可以正常访问了


Minio Java SDK使用

Minio提供了多种语言的SDK供开发者使用,具体内容可参考官方文档。

1. 在Spring Boot项目的pom中引入Minio依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
</dependencies>

创建一个类方法测试,然后执行查看是否上传成功

public class App {
    public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException {

        try {
            //构造MinIO Client
            MinioClient minioClient = MinioClient.builder()
                    .endpoint("http://192.168.10.101:9000")//填写你的地址
                    .credentials("minioadmin", "minioadmin")//填写你的账号、密码
                    .build();
    
            //创建hello-minio桶
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("hello-minio").build());
            if (!found) {
                //创建hello-minio桶
                minioClient.makeBucket(MakeBucketArgs.builder().bucket("hello-minio").build());
                //设置hello-minio桶的访问权限
                //JDK15之后的特性,三引号
                String policy = """
                        {
                          "Statement" : [ {
                            "Action" : "s3:GetObject",
                            "Effect" : "Allow",
                            "Principal" : "*",
                            "Resource" : "arn:aws:s3:::hello-minio/*"
                          } ],
                          "Version" : "2012-10-17"
                        }""";
                minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket("hello-minio").config(policy).build());
            } else {
                System.out.println("Bucket 'hello-minio' already exists.");
            }
    
            //上传图片
            minioClient.uploadObject(
                    UploadObjectArgs.builder()
                            .bucket("hello-minio")
                            .object("公寓-外观.jpg")
                            .filename("D:\\workspace\\hello-minio\\src\\main\\resources\\公寓-外观.jpg")
                			//这个文件填写你电脑要上传的图片的路径
                            .build());
            System.out.println("上传成功");
        } catch (MinioException e) {
            System.out.println("Error occurred: " + e);
        }
    }

}

如果使用的JDK版本不高与15的话可以用这一段代替

String policy = "{\n" +
                "  \"Statement\" : [ {\n" +
                "    \"Action\" : \"s3:GetObject\",\n" +
                "    \"Effect\" : \"Allow\",\n" +
                "    \"Principal\" : \"*\",\n" +
                "    \"Resource\" : \"arn:aws:s3:::hello-minio/*\"\n" +
                "  } ],\n" +
                "  \"Version\" : \"2012-10-17\"\n" +
                "}";

2. 在application.yml或properties中添加Minio配置参数

#项目名
server:
  servlet:
    context-path: /minioDemo
minio:
  endpoint: http://192.168.181.29:9000 #minio地址
  access-key: minioadmin #用户名
  secret-key: minioadmin #密码
  bucket-name: lease #存储的minio名称(自定义)

3. 创建Minio配置类和配置参数类

3.1. 创建配置类MinioConfiguration
@Configuration
@EnableConfigurationProperties(MinioProperties.class)//单个配置参数类扫描

//@ConfigurationPropertiesScan("com.waitforme.lease.common.minio")扫描一个路径下的所有配置参数类

//@EnableConfigurationProperties、@ConfigurationPropertiesScan两个注解的作用都是为了注册配置参数类,根据需要使用其一即可
public class MinioConfiguration {
    @Autowired
    private MinioProperties properties;

    @Bean
    public MinioClient minioClient() {
        return MinioClient
                .builder()
                .endpoint(properties.getEndpoint())
                .credentials(properties.getAccessKey(), properties.getSecretKey())
                .build();
    }
}
3.2. 创建一个配置参数类

因为配置类中需要用到之前第二步添加的Minio的配置参数,所以创建它

@ConfigurationProperties(prefix = "minio")
@Data
public class MinioProperties {

    private String endpoint;

    private String accessKey;

    private String secretKey;

    private String bucketName;
}

注意:如果出现了如图的错误提示,是因为你没有在配置类中注册配置参数类,所以要先进行注册,在MinioConfiguration类上加上@EnableConfigurationProperties@ConfigurationPropertiesScan注解进行注册

4.创建FileService接口及其实现,实现图片获取、上传、删除逻辑

service

public interface FileService {
  //图片上传
  String upload(MultipartFile file) throws Exception;
  //获取图片列表
  List<String> getListObjects() throws Exception;
  //删除单个图片
  Boolean deleteObject(String fileName) throws Exception;
}

serviceImpl

@Service("fileService")
public class FileServiceImpl implements FileService {
    @Autowired
    MinioClient minioClient;
    @Autowired
    MinioProperties properties;

    @Override
    public String upload(MultipartFile file) throws Exception {
        boolean bucketExists = minioClient.bucketExists(
                BucketExistsArgs.builder()
                        .bucket(properties.getBucketName()).build());
        if (!bucketExists) {
            //判断minio中是否存在我们配置的存储桶名称
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(properties.getBucketName()).build());
            //创建存储桶
            minioClient.setBucketPolicy(
                    SetBucketPolicyArgs.builder()
                            .bucket(properties.getBucketName())
                            .config(createBucketPolicyConfig(properties.getBucketName())).build());
            //为创建的存储桶设置访问权限
        }
        String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename();
        //上传的文件名
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(properties.getBucketName())
                //上传的存储桶名称
                .stream(file.getInputStream(), file.getSize(), -1)
                /*上传的文件,三个参数分别表示:
                1. 上传的文件io流
                2. 上传的文件大小
                3. -1表示我们确定了自己要上传的文件大小后,让minio自己自动去分配每次上传的大小,因为minio不是一次性删除而是分片上传*/
                .object(fileName)
                //上传后的文件名
                .contentType(file.getContentType())
                //上传文件类型,通过file.getContentType获取,因为不设置的话就是steam类型,访问的时候会下载图片,而不是预览图片
                .build());
        //上传文件
        return String.join("/", properties.getEndpoint(), properties.getBucketName(), fileName);
        //join方法用于通过指定一个分割符,将传入的的参数拼接成一串字符,可以传入多个参数
    }
	/**
   * 获取图片列表
   * @return 返回处理完的图片数组列表
   * @throws Exception 直接抛出最大的异常类
   */
  @Override
  public List<String> getListObjects() throws Exception {
    List<String> objectNames = new ArrayList<>();
    //创建一个数组用于存储获取到的图片
    Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder()
      .bucket(properties.getBucketName())
      .build());
    //获取指定存储桶中的图片列表
    for (Result<Item> result : results) {
      Item item = result.get();
      objectNames.add(String.join("/", properties.getEndpoint(), properties.getBucketName(), item.objectName()));
      //遍历得到的数组,并通过指定为:http://xxx.xxx.xxx.xx:9000/bucketName/fileName.jpg的格式到数组中
    }
    return objectNames;
  }

  /**
   * 删除存储桶中的单个图片
   * @param fileName 图片名称包括后缀
   * @return 直接返回ture
   * @throws Exception
   */
  @Override
  public Boolean deleteObject(String fileName) throws Exception {
    minioClient.removeObject(RemoveObjectArgs.builder()
      .bucket(properties.getBucketName())
      .object(fileName)
      .build());
    return true;
  }
    /**
     * @param bucketName 存储桶名称
     * @return 返回存储桶的访问权限JSON字符串
     * 返回值表示允许所以人读取该存储桶下的所有文件,没有设置写权限是因为默认创建人就是写权限拥有者
     * 其中resource中的%s表示占位符,.formatted中的就是占位符的值
     */
    private String createBucketPolicyConfig(String bucketName) {
        //三引号是jdk15添加的新功能
        return """
                {
                  "Statement" : [ {
                    "Action" : "s3:GetObject",
                    "Effect" : "Allow",
                    "Principal" : "*",
                    "Resource" : "arn:aws:s3:::%s/*"
                  } ],
                  "Version" : "2012-10-17"
                }
                """.formatted(bucketName);
    }
}

如果使用的JDK版本低于15可以用这段代替createBucketPolicyConfig方法里面的代码

private String createBucketPolicyConfig(String bucketName) {
    String policy = String.format(
            "{\n" +
                    "  \"Statement\" : [ {\n" +
                    "    \"Action\" : \"s3:GetObject\",\n" +
                    "    \"Effect\" : \"Allow\",\n" +
                    "    \"Principal\" : \"*\",\n" +
                    "    \"Resource\" : \"arn:aws:s3:::%s/*\"\n" +
                    "  } ],\n" +
                    "  \"Version\" : \"2012-10-17\"\n" +
                    "}", bucketName);
	return policy;
}

5.创建Controller

@Controller
public class MinioController {
  @Autowired
  MinioService minioService;

  @RequestMapping("/upload")
  public String upload(@RequestParam MultipartFile file, Model model) {
    try {
      String url = minioService.upload(file);
      model.addAttribute("url", url);
      model.addAttribute("msg", "上传成功");
    } catch (Exception e) {
      model.addAttribute("msg", "上传失败:" + e.getMessage());
    }
    return "redirect:/list";
  }

  @RequestMapping({"/list", ""})
  public String getListObjects(Model model) throws Exception {
    List<String> listObjects = minioService.getListObjects();
    model.addAttribute("listObjects", listObjects);
    model.addAttribute("msg", listObjects == null ? "获取图片失败或是没有图片" : "");
    return "index";
  }

  @RequestMapping("/remove")
  @ResponseBody
  public Object removeObject(@RequestParam String fileName) {
    Map map = null;
    try {
      Boolean flag = minioService.deleteObject(fileName);
      map = new HashMap();
      map.put("flag", flag);
      map.put("msg", "删除成功");
    } catch (Exception e) {
      map.put("msg", "删除失败:" + e.getMessage());
      return map;
    }
    return map;
  }
}

6.在templates中创建index.html页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style type="text/css">
    ul{
        list-style-type: none;
    }
    ul>li{
        margin: 20px;
    }
</style>
<body>
<div align="center">
    <h1>minio的增删改查示例</h1>
    <form th:action="@{/upload}" method="post" enctype="multipart/form-data">
        <input type="file" name="file" required>
        <button type="submit">上传图片</button>
    </form>
</div>
<div align="center">
    <h2 align="center">已上传的图片</h2>
    <ul>
        <li th:each="object : ${listObjects}">
            <img th:src="@{${object}}" alt="11" width="450px" height="230px">
            <a href="#" th:onclick="del(this,[[${object}]]);" style="padding-left: 100px">删除</a>
        </li>
    </ul>
    <p id="msg" style="color: red" align="center">[[${msg}]]</p>
</div>
</body>
<script th:src="@{/js/jquery-1.12.4.js}" type="text/javascript"></script>
<script type="text/javascript">
    function del(obj, url) {
        if (confirm("确认要删除吗?")) {
            var parts = url.split("/");
            var fileName = parts[parts.length - 1];
            $.getJSON("remove", "fileName=" + fileName, function (data) {
                if (data.flag) {
                    $(obj).parents("li").remove();
                }
                $("#msg").html(data.msg);
            })
        }
    }
</script>
</html>

然后,在static中创建js文件夹放入 jquery-1.12.4.js

页面效果


遇到的错误

获取图片信息报错?

报错原因:因为物理机的请求时间跟服务器的时间相差太大了,简单说就是要同步一下虚拟机的时间

解决步骤:

1.进入虚拟机,点击右上角序号1,然后点击root,再点击账号设置

2.在弹出的窗口中选择日期和时间,然后把自动设置日期和时间、自动设置时区打开,等待时间与物理机相同即可

注意:此方案需要有网络才能实现

a标签用th:onclick="|del(this,${object})|"报错500?

原因分析:应该是thymeleaf的版本问题

解决方案:替换th:onclick="|del(this,${object})|"th:onclick="del(this,[[${object}]]);"

<a href="#" th:onclick="del(this,[[${object}]]);" style="padding-left: 100px">删除</a>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新手前端开发入职公司全流程

作为一名前端开发新手&#xff0c;进入一家公司开启职业生涯是既兴奋又充满挑战的旅程。今天就来和大家分享一下这个过程中的各个环节。 一、入职准备 在收到心仪公司的offer后&#xff0c;可别只顾着高兴啦。首先要准备好入职资料&#xff0c;像身份证、学历证明这些是必不可…

那智机器人报警白屏

那智机器人内存太多白屏报警&#xff01;&#xff01;&#xff01;下面来说说如何消除该报警吧&#xff01;&#xff01;&#xff01; 白屏报警的处理办法 解决办法&#xff1a;&#xff08;外部内存清理&#xff09; 升级操作者权限 &#xff08;当我们在维修见面不能看见我…

rk3568之mpp开发笔记mpp移植到开发板

前言&#xff1a; 大家好&#xff0c;今天给大家介绍的内容是rk平台的mpp编解码这块的内容&#xff0c;在rk目前看到有三套框架涉及到编解码内容&#xff1a; 1、rkmedia 2、rockit 3、mpp 这三种不同形式的编解码方式&#xff0c;后面再做详细的框架对比&#xff0c;今天我…

【设计模式】结构型设计模式总结之代理模式、装饰模式、外观模式、享元模式

文章目录 代理模式示例结构分类动态代理 装饰模式示例结构使用场景与代理模式区别Context 外观模式结构示例使用场景Context 享元模式结构示例使用场景Message 代理模式 代理模式&#xff08;Proxy Pattern&#xff09; 是一种结构型设计模式&#xff0c;它提供了一个代理对象…

CSS一些小点 —— 12.7

1. box-sizing: border-box box-sizing 属性&#xff0c;默认值为 content-box box-sizing: border-box 使padding和border的值不会再影响元素的宽高&#xff1b;padding和border的值算在指定宽高的内部&#xff08;但是外边距依然算做外部&#xff09; 2. overflow: hidden …

【毕业设计选题】深度学习类毕业设计选题参考 开题指导

目录 前言 毕设选题 开题指导建议 更多精选选题 选题帮助 最后 前言 大家好,这里是海浪学长毕设专题! 大四是整个大学期间最忙碌的时光&#xff0c;一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整…

算法基础学习Day4(双指针)

文章目录 1.题目2.题目解答1.查找总价格为目标值的两个商品1.1题目及题目解析1.2算法学习暴力解法优化算法 1.3代码提交 2.三数之和2.1题目及题目解析2.2算法学习2.3代码提交 1.题目 LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09;15. 三数之…

哪里可以找到高质量的街道夜景短视频素材?夜景素材网站推荐

在短视频创作的浪潮中&#xff0c;街道夜景作为一种视觉效果独特、氛围浓郁的题材&#xff0c;深受创作者的青睐。不论是商业广告、创意短片还是个人Vlog&#xff0c;街道夜景的视频素材都能为你的作品增添不小的分量。那么&#xff0c;在哪里可以找到这些高质量的街道夜景短视…

实习冲刺第四十三天

25.K个一组翻转链表 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只是单…

[计算机网络] HTTP/HTTPS

一. HTTP/HTTPS简介 1.1 HTTP HTTP&#xff08;超文本传输协议&#xff0c;Hypertext Transfer Protocol&#xff09;是一种用于从网络传输超文本到本地浏览器的传输协议。它定义了客户端与服务器之间请求和响应的格式。HTTP 工作在 TCP/IP 模型之上&#xff0c;通常使用端口 …

微信创建小程序码 - 数量不受限制

获取小程序码&#xff1a;小程序码为圆图&#xff0c;且不受数量限制。 目录 文档 接口地址 请求方式 功能描述 注意事项 获取 scene 值 请求参数 返回参数 对接 请求方法 获取小程序码 调用获取小程序码 总结 文档 接口地址 https://api.weixin.qq.com/wxa/get…

在做题中学习(79):最小K个数

解法&#xff1a;快速选择算法 说明&#xff1a;堆排序也是经典解决问题的算法&#xff0c;但时间复杂度为&#xff1a;O(NlogK)&#xff0c;K为k个元素 而将要介绍的快速选择算法的时间复杂度为: O(N) 先看我的前两篇文章&#xff0c;分别学习&#xff1a;数组分三块&#…

第427场周赛: 转换数组、用点构造面积最大的矩形 Ⅰ、长度可被 K 整除的子数组的最大元素和、用点构造面积最大的矩形 Ⅱ

Q1、转换数组 1、题目描述 给你一个整数数组 nums&#xff0c;它表示一个循环数组。请你遵循以下规则创建一个大小 相同 的新数组 result &#xff1a; 对于每个下标 i&#xff08;其中 0 < i < nums.length&#xff09;&#xff0c;独立执行以下操作&#xff1a; 如…

【中间件开发】Redis基础命令详解及概念介绍

文章目录 前言一、Redis相关命令详解及原理1.1 string、set、zset、list、hash1.1.1 string1.1.2 list1.1.3 hash1.1.4 set1.1.5 zset 1.2 分布式锁的实现1.3 lua脚本解决ACID原子性1.4 Redis事务的ACID性质分析 二、Redis协议与异步方式2.1 Redis协议解析2.1.1 redis pipeline…

运输层4——TCP格式(重点!)

目录 一、TCP报文段格式 二、最大报文长度 MSS 一、TCP报文段格式 长度&#xff1a;前20个字节固定 后4n个字节&#xff08;报文段格式不固定&#xff09; 1、源端和目的端&#xff1a;各2个字节 作用&#xff1a;指明TCP链接的发送 2、序号 4字节 作用&#xff1…

「Mac玩转仓颉内测版46」小学奥数篇9 - 基础概率计算

本篇将通过 Python 和 Cangjie 双语实现基础概率的计算&#xff0c;帮助学生学习如何解决简单的概率问题&#xff0c;并培养逻辑推理和编程思维。 关键词 小学奥数Python Cangjie概率计算 一、题目描述 假设有一个袋子中有 5 个红球和 3 个蓝球&#xff0c;每次从袋子中随机…

从变更到通知:使用Python和MongoDB Change Streams实现即时事件监听

MongoDB提供了一种强大的功能&#xff0c;称为Change Streams&#xff0c;它允许应用程序监听数据库中的变更事件&#xff0c;并在数据发生变化时立即做出响应。这在mysql数据库是不具备没有这个功能的。又如&#xff1a;我们在支付环节想一直监听支付回调的状态&#xff0c;就…

决策树:ID3、C4.5和CART特征选择方式

1 前言 该文章主要目的是记录ID3、C4.5和CART特征选择方式&#xff0c;这里只对决策树进行简单介绍。 决策树&#xff08;Decision Tree&#xff09;算法是一种有监督学习算法&#xff0c;它利用分类的思想&#xff0c;根据数据的特征构建数学模型&#xff0c;从而达到数据的筛…

2023 年“泰迪杯”数据分析技能赛B 题企业财务数据分析与造假识别

2023 年“泰迪杯”数据分析技能赛B 题企业财务数据分析与造假识别 一、背景 财务数据是指企业经营活动和财务结果的数据记录&#xff0c;反映了企业的财务状况 与经营成果。对行业、企业的财务数据进行分析&#xff0c;就是要评价其过去的经营业绩、 衡量现在的财务状况、预测…

UE5.5 Geometry库平面切割原理分析

平面切割--FMeshPlaneCut 平面定义: 面上一个点 法线 算法流程如下 求几何体所有顶点和面的有向距离(Signs) Sign计算&#xff1a; float Sign (VertexPos - PlaneOrigin).Dot(PlaneNormal); 遍历所有几何体所有交叉边, 进行SplitEdge 对于位于切割面两侧的交叉边(Sign…