Kafka核心概念、数据存储设计及Partition数据文件 生产者负载均衡策略、批量发送技巧、消息压缩手段、消费者设计

news2024/11/17 15:36:32

关注公众号,发送 “面试题” 即可免费领取一份超全的面试题PDF文件!!!!

1、kafka的概念

Kafka 是一个开源的分布式流处理平台,最初由LinkedIn开发,后来成为Apache软件基金会的一个顶级项目。它被设计为高吞吐量、可扩展、持久化的分布式发布-订阅消息系统。以下是 Kafka 的一些关键概念:

  1. 消息(Message): Kafka 是一个消息系统,数据以消息的形式进行传递。消息可以是任何形式的数据,通常包含键值对,以及其他元数据。

  2. 主题(Topic): 消息按照主题进行分类,主题是消息的逻辑容器。生产者发布消息到特定主题,而消费者则从感兴趣的主题订阅消息。

  3. 分区(Partition): 主题可以被划分为多个分区,每个分区是一个有序、不可变的消息序列。分区允许 Kafka 在水平方向上扩展,提高并行性和吞吐量。

  4. 生产者(Producer): 生产者是负责将消息发布到 Kafka 主题的应用程序。生产者将消息发送到指定的主题,并可以选择指定消息发送的分区。

  5. 消费者(Consumer): 消费者是从 Kafka 主题订阅消息的应用程序。消费者可以以不同的方式处理消息,例如存储、转发、实时处理等。

  6. 偏移量(Offset): 每个分区中的每条消息都有一个唯一的偏移量,用于标识消息在分区中的位置。消费者使用偏移量来追踪已经消费的消息位置。

  7. 代理或服务器(Broker): Kafka 集群由多个 Broker 组成,每个 Broker 是一个独立的 Kafka 服务器。Brokers 负责存储消息,处理生产者和消费者的请求,并协调集群中的分区。

  8. 复制(Replication): 为了提供高可用性和容错性,Kafka 支持将每个分区的消息复制到多个 Broker 上。每个分区有一个 Leader 和零个或多个 Followers。

  9. Zookeeper: Kafka 依赖 Zookeeper 来进行集群协调、元数据管理、Leader 选举等任务。

  10. 水平扩展: Kafka 具有良好的水平扩展性,通过增加 Broker、分区等方式来适应更大规模的数据和负载。

  11. 消费者组(Consumer Group): 消费者可以组成一个消费者组,共同消费一个主题的消息。每个分区只能被一个消费者组内的一个消费者消费。

  12. 日志(Log): Kafka 将消息以日志的形式存储,每个分区对应一个日志文件。这种存储方式保证了消息的顺序性和持久性。

Kafka 的这些概念共同构建了一个高效、可靠的分布式消息系统,广泛用于构建实时数据流处理和日志收集等场景。

当我们谈论 Kafka 时,可以将其想象成一个先进的邮局系统,其中有一些重要的角色和概念:
邮件(消息):
在 Kafka 里,我们发送和接收的是消息,就像我们在邮局中发送和收到邮件一样。这些消息可以包含任何你想要传递的信息,比如文本、数据等。
邮箱(主题):
消息按照主题进行分类,就好比我们的邮局有不同的邮箱,每个邮箱对应一个主题。发送者把消息放入指定的邮箱(主题),而接收者从感兴趣的邮箱中取出消息。
信箱的分隔(分区):
为了更好地处理大量的消息,每个邮箱(主题)都被分成了若干个小的部分,每个部分叫做分区。这样,处理消息的时候就可以更灵活、更高效。
寄件人(生产者):
寄件人就是消息的发送者,我们称之为生产者。生产者将消息投递到指定的邮箱(主题),并选择把消息放入哪个分区。
收件人(消费者):
收件人是消息的接收者,我们称之为消费者。消费者从感兴趣的邮箱(主题)中取出消息,处理或者存储这些消息。
信件的位置标记(偏移量):
每个消息都有一个唯一的标记,就像邮件上的邮戳一样,我们称之为偏移量。消费者通过偏移量追踪已经处理过的消息,确保不会漏掉或者重复处理。
邮局(Broker):
邮局就是整个 Kafka 系统,由多个邮局(Broker)组成。每个邮局都有自己的邮箱(主题)和信箱的分隔(分区),处理消息的任务由这些邮局共同协调完成。
邮局的副本(复制):
为了确保消息的安全性,每个邮箱(主题)的消息会被复制到多个邮局(Broker)。每个邮箱有一个主要的邮局(Leader),其他的邮局是备用(Followers)。
邮局管理员(Zookeeper):
邮局管理员就像是整个邮局系统的管理者,负责协调各个邮局的工作、管理邮箱的信息和处理一些系统级别的任务。
邮局的扩展(水平扩展):
如果我们的邮局负载过大,我们可以通过增加更多的邮局(Broker)或者分隔更多的邮箱(主题)来提高处理能力,就像扩建邮局一样。

2、Kafka数据存储设计

Kafka的数据存储设计采用了日志文件的方式,主要设计特点如下:

  1. 日志文件(Log): Kafka将消息按照日志文件的形式存储,每个主题的每个分区都对应一个日志文件。这种日志文件的设计使得消息以追加的方式存储,确保了消息的有序性和持久性。

  2. 分区(Partition): 主题可以被划分为多个分区,每个分区对应一个日志文件。引入分区的设计允许Kafka在水平方向上进行扩展,提高了并行性和吞吐量。

  3. 分段存储(Segment): 日志文件被划分为多个分段,每个分段对应一个时间范围或者大小限制。这种分段存储的方式允许Kafka的日志文件逐渐增长而不会无限制地变大,便于管理和维护。

  4. 索引文件(Index): 为了加速消息的查找,每个分段都有一个相应的索引文件。索引文件包含了偏移量范围和消息key的信息,以便快速定位到某个偏移量对应的消息。

  5. 顺序读写: 每个分段内部的消息是按照顺序进行读写的,保证了消息在分段文件中的物理存储顺序与逻辑上的Offset顺序一致。这对于顺序性的消息处理非常重要。

  6. 分段索引和稀疏存储: 为每个分段的数据文件建立了索引文件,采用了稀疏存储的方式。这意味着并不为每条消息都建立索引,而是通过间隔一定字节数建立一条索引。这样的设计在一定程度上节省了索引文件的空间占用。

  7. 复制(Replication): 为了提供高可用性和容错性,每个分区的消息都会被复制到多个Broker上。Leader-Follower模型确保了复制的一致性和容错性。

2.1 partition 的数据文件( offset,MessageSize,data )

假设有一个 Kafka 主题(Topic)叫做 "example_topic",该主题有两个分区(Partition),分别为 Partition 0 和 Partition 1。

Offset(偏移量):

对于 Partition 0,数据文件记录的消息如下:

Offset: 0, MessageSize: 50, Data: "Hello, Kafka!"
Offset: 1, MessageSize: 45, Data: "This is a message."

对于 Partition 1,数据文件记录的消息如下:

Offset: 0, MessageSize: 60, Data: "Another message for Partition 1."

MessageSize(消息大小):

假设消息的大小是以字节为单位计算的,上述示例中的 MessageSize 属性表示了每条消息的存储空间占用。

Data(消息内容):

Data 属性存储了实际的消息内容。例如,对于 Offset 0 的消息,Data 包含了 "Hello, Kafka!" 这段文本。

这些属性的具体使用场景:

消息追加: 当新消息到达时,例如有一条新消息 "New message arrived!",它会以追加的方式写入数据文件,附上适当的Offset和MessageSize。

消息读取: 当需要读取消息时,通过索引等机制能够快速定位到特定Offset的消息。比如,可以快速读取 Partition 0 的 Offset 1 处的消息内容。

存储管理: MessageSize 属性可用于估算存储空间的需求。管理员可以通过监测消息的大小来优化存储分配。

消息索引: Offset等属性构成了消息的逻辑标识,用于建立索引和支持快速的消息查找操作。在实际应用中,Kafka会建立索引以支持快速的读取和查找操作。

2.2 数据文件分段 segment

数据文件的分段设计是 Kafka 中保证高效、有序存储消息的重要组成部分。以下是关于数据文件分段(Segment)的一些详细说明:

顺序读写:

每个数据文件内部的消息是按照顺序进行读写的。新的消息以追加的方式写入文件的末尾,这保证了消息在文件中的物理存储顺序与逻辑上的 Offset 顺序一致。顺序读写有助于提高读写性能,并且支持Kafka作为有序消息系统的核心特性。

分段命名:

数据文件被切分成多个段(Segment),每个段对应一个时间范围或者大小限制。每个段都有一个唯一的标识,通常采用该段中最小的 Offset 来命名,以确保唯一性。这种分段的设计使得文件能够逐渐增长而不会无限制地变大,便于管理和维护。

二分查找:

由于每个分段内部的消息是有序的,Kafka可以通过二分查找的方式在段内快速定位到目标 Offset 所对应的消息位置。这种查找方式在读取消息时提供了较高的效率,特别是当分段文件较大时。

这样的设计使得Kafka在处理大规模数据流时能够高效地进行顺序读写和查找操作。新消息追加到新的分段,而旧的分段保持不变,确保了数据文件的分段存储,进而提高了Kafka系统的整体性能和可维护性。

让我们通过一个简单的示例来说明数据文件分段的概念:

假设有一个 Kafka 主题(Topic)叫做 "log_messages",该主题有一个分区(Partition),分区的数据文件按照分段设计,每个分段对应一个时间范围。初始时,有两个分段,分别为 Segment-1 和 Segment-2。

顺序读写:

当有新消息到达时,它们会按照顺序被追加到当前活跃的分段。例如,新消息 "Message 1" 和 "Message 2" 被依次追加到 Segment-1 的末尾。

Segment-1:
Offset: 0, Message: "Message 1"
Offset: 1, Message: "Message 2"

随着时间的推移,当 Segment-1 达到一定的大小或时间限制时,Kafka 将关闭当前的 Segment-1,并创建一个新的分段 Segment-3。

分段命名和切换:

新创建的 Segment-3 将成为新的活跃分段,用于接收后续的消息。此时,系统中的分段变为 Segment-2 和 Segment-3。

Segment-2:
Offset: 2, Message: "Message 3"
Offset: 3, Message: "Message 4"

Segment-3: (新的活跃分段)

随着消息的不断追加,Segment-3 会逐渐积累消息。

二分查找:

当需要读取某个特定 Offset 的消息时,Kafka 可以利用二分查找在活跃分段中快速定位到目标消息。例如,如果需要读取 Offset 1 的消息,系统会执行二分查找并定位到 Segment-1 中的相应位置。

3、生产者设计

3.1 生产者如何做负载均衡

Kafka 生产者的负载均衡主要是通过以下两个方面来实现的:

1.分区选择策略: 生产者在发送消息时需要选择将消息发送到哪个分区。Kafka 提供了多种分区选择策略,生产者可以根据业务需求选择合适的策略。

分区选择策略和负载均衡:

  • 由于消息的 Topic 由多个 Partition 组成,而这些 Partition 会均衡分布到不同的 Broker 上,为了充分利用整个 Broker 集群的性能,提高消息的吞吐量,生产者可以采用灵活的分区选择策略,实现负载均衡。

  • 随机分区选择: 生产者可以选择随机将消息发送到不同的分区,确保消息在各个分区之间均匀分布,以达到负载均衡的效果。

  • 哈希分区选择: 另一种常见的方式是通过消息的关键信息进行哈希计算,将相同哈希值的消息发送到同一个分区。这种方式适用于要求相关消息存储在同一分区的业务场景。

  • 这样的设计确保了生产者在发送消息时能够充分利用 Broker 集群的各个 Partition,提高整体系统的性能和并行性。

常见的分区选择策略包括:

  • 轮询策略: 生产者按照轮询的方式选择分区,确保消息均匀地分布在各个分区中。

  • 哈希策略: 使用消息的关键信息进行哈希计算,将相同哈希值的消息发送到同一个分区,适用于要求相关消息存储在同一分区的场景。

  • 随机策略: 生产者随机选择一个分区,适用于无特定需求的负载均衡。

2.Producer 实例多线程: 生产者实例是线程安全的,因此可以通过创建多个生产者实例,并在每个实例上运行多个线程的方式来提高并行性。每个线程负责发送消息到不同的分区,这样可以实现消息的并行发送,提高整体吞吐量。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

public class KafkaProducerExample {
    public static void main(String[] args) {
        // 配置 Kafka 生产者
        // ...

        // 创建 Kafka 生产者实例
        Producer<String, String> producer = new KafkaProducer<>(/* 配置参数 */);

        // 启动多个线程并创建多个生产者实例
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                // 创建生产者实例
                Producer<String, String> threadProducer = new KafkaProducer<>(/* 配置参数 */);

                // 在每个线程中发送消息到指定分区
                for (int j = 0; j < 100; j++) {
                    String message = "Message-" + j;
                    // 选择分区或使用默认分区选择策略
                    ProducerRecord<String, String> record = new ProducerRecord<>("example_topic", message);
                    // 发送消息
                    threadProducer.send(record);
                }

                // 关闭生产者实例
                threadProducer.close();
            }).start();
        }

        // 关闭主线程中的生产者实例
        producer.close();
    }
}

3.2 生产者 如何做到批量发送

生产者在 Kafka 中通过批量发送消息可以提高吞吐量,减少网络开销。这通常是通过两个主要的配置参数来实现的:batch.size 和 linger.ms。

batch.size 参数:

batch.size 参数指定了一个批次中消息的大小上限。当生产者积累了足够多的消息达到或超过这个大小时,批量发送消息。较大的 batch.size 值通常能够提高吞吐量,但会增加延迟,因为需要等待足够的消息填充一个批次。 示例配置:

producer.batch.size=16384

linger.ms 参数:

linger.ms 参数指定了生产者在发送批次之前等待的时间上限。即使批次未达到 batch.size,当等待时间超过 linger.ms 时,生产者也会发送当前积累的消息。通过设置较小的 linger.ms 值,可以降低延迟,但可能会影响吞吐量。

示例配置:

producer.linger.ms=5

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties properties = new Properties();
        // 配置其他 Kafka 生产者参数...

        // 设置批量发送的大小和等待时间
        properties.put("batch.size", 16384);
        properties.put("linger.ms", 5);

        // 创建 Kafka 生产者实例
        Producer<String, String> producer = new KafkaProducer<>(properties);

        // 发送批量消息
        for (int i = 0; i < 100; i++) {
            String message = "Message-" + i;
            ProducerRecord<String, String> record = new ProducerRecord<>("example_topic", message);
            // 发送消息到 Kafka
            producer.send(record);
        }

        // 关闭生产者实例
        producer.close();
    }
}


在上述示例中,通过设置 batch.sizelinger.ms 参数,生产者将会在满足批量大小或等待时间的条件下批量发送消息,从而提高了整体的吞吐量。具体的参数值可以根据实际需求和性能测试进行调整。

生产者的消息压缩

Kafka 生产者提供了消息压缩的功能,通过压缩消息可以有效减少网络传输的数据量,降低网络带宽的使用,提高整体的性能。在 Kafka 中,压缩是通过配置 compression.type 参数实现的。

compression.type 参数:

  • compression.type 参数用于设置消息的压缩算法。常见的压缩算法包括:

  • none: 不使用压缩,消息以原始形式发送。

  • gzip: 使用 Gzip 压缩算法。

  • snappy: 使用 Snappy 压缩算法。

  • lz4: 使用 LZ4 压缩算法。

示例配置:

producer.compression.type=gzip

压缩级别(可选):

  • 对于 Gzip 压缩算法,可以通过配置 compression.level 参数设置压缩级别,数值越大表示压缩比越高,但同时也会增加 CPU 消耗。

示例配置:

producer.compression.level=3

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties properties = new Properties();
        // 配置其他 Kafka 生产者参数...

        // 设置压缩算法
        properties.put("compression.type", "gzip");

        // 创建 Kafka 生产者实例
        Producer<String, String> producer = new KafkaProducer<>(properties);

        // 发送压缩消息
        for (int i = 0; i < 100; i++) {
            String message = "Message-" + i;
            ProducerRecord<String, String> record = new ProducerRecord<>("example_topic", message);
            // 发送消息到 Kafka
            producer.send(record);
        }

        // 关闭生产者实例
        producer.close();
    }
}

在上述示例中,通过设置 compression.type 参数,生产者将使用 Gzip 压缩算法对消息进行压缩。压缩算法的选择通常取决于对性能和网络带宽的平衡,不同的场景可能选择不同的压缩算法。

4.消费者设计

消费者在 Kafka 中负责从主题(Topic)订阅消息,并进行相应的处理。以下是 Kafka 消费者设计的关键方面:

  1. 消费者组:

    • 消费者可以组成一个消费者组,每个消费者组可以有多个消费者。Kafka 通过消费者组来实现消息的负载均衡和水平扩展。每个分区只能由同一个消费者组中的一个消费者来消费,但一个消费者组可以同时消费多个分区。

  2. 订阅主题:

    • 消费者通过调用 subscribe 方法订阅一个或多个主题。可以使用正则表达式进行模式匹配,实现对多个相关主题的订阅。

    示例代码(Java):

    consumer.subscribe(Arrays.asList("example_topic"));
    
  3. 消息拉取和轮询:

    • 消费者通过轮询(poll)机制从 Kafka 服务器拉取消息。在每次轮询中,消费者可以一次性拉取多条消息,并在本地进行处理。轮询的频率由配置参数 max.poll.interval.ms 控制。

    示例代码(Java):

    ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
    for (ConsumerRecord<String, String> record : records) {
        // 处理每条消息
        System.out.printf("Consumed record with key %s and value %s%n", record.key(), record.value());
    }
    
  4. 消息处理和业务逻辑:

    • 消费者需要实现消息的具体处理逻辑。这包括对消息的解析、业务逻辑的执行、数据存储等操作。处理逻辑的复杂性和实现方式取决于具体的应用场景。

    示例代码(Java):

    for (ConsumerRecord<String, String> record : records) {
        // 处理每条消息的业务逻辑
        String message = record.value();
        processMessage(message);
    }
    
  5. 消息提交和偏移量管理:

    • 消费者需要负责管理偏移量(offset)以跟踪已消费的消息。偏移量表示消费者在分区中的位置。Kafka 提供了自动和手动两种提交偏移量的方式。自动提交由 Kafka 客户端负责,而手动提交则由应用程序控制。

    示例代码(Java):

    // 手动提交偏移量
    consumer.commitSync();
    
  6. 异常处理和重平衡:

    • 消费者需要处理可能发生的异常,例如网络故障、Kafka 集群的重启等情况。此外,当消费者组的成员发生变化时(如有新的消费者加入或有消费者退出),可能触发消费者的重平衡。在重平衡期间,Kafka 会重新分配分区给消费者,确保每个分区只被一个消费者消费。

    示例代码(Java):

    try {
        while (true) {
            ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
            // 处理消息...
        }
    } catch (WakeupException e) {
        // 处理消费者被唤醒的异常
    } finally {
        consumer.close();
    }
    
  7. 性能调优:

    • 消费者的性能也可以通过配置进行调优。例如,可以设置 max.poll.records 控制每次轮询拉取的最大消息数量,以影响消费者的吞吐量。

    示例代码(Java):

    properties.put("max.poll.records", 500);
    

Kafka 消费者的设计需要考虑到消息处理的逻辑、偏移量管理、异常处理以及重平衡等方面,以确保消费者能够稳定、高效地消费消息。

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

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

相关文章

【解决】Unity 工程无法正常打开而崩溃问题

开发平台&#xff1a;Unity 2022.3.17f1c1 一、问题描述 访问 Unity 工程等待 Open Projet&#xff08;busy for 时间&#xff09;&#xff0c;出现崩溃、闪退等情况&#xff0c;导致无法正常进入Unity编辑页面。 二、问题分析 笔者在 URP 渲染管线下处理 Obi Fluid 流体插件 D…

detectron2的read_image方法

在看代码的时候&#xff0c;看到一行注释&#xff1a;use PIL, to be consistent with evaluation 说是用PIL方法加载&#xff0c;却又看见了BGR这种表述&#xff0c;后面的调用也都是cv2格式&#xff1a; 那我就要看下这里面是怎么实现的了&#xff0c;找到了read_image函数&…

知识点积累系列(一)golang语言篇【持续更新】

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 知识点积累 系列文章的第一篇&#xff0c;记录golang语言相关的知识点 1.结构体的mapstructure是什么 mapstructure:"default" mapstructure是一个Go语言的库&#xff0c;用于将一个map中的值映射到…

通过手写简易版RPC理解RPC原理

RPC是什么 所谓的RPC其实是为了不同主机的两个进程间通信而产生的&#xff0c;通常不同的主机之间的进程通信&#xff0c;程序编写需要考虑到网络通信的功能&#xff0c;这样程序的编写将会变得复杂。RPC就来解决这一问题的&#xff0c;一台主机上的进程对另外一台主机的进程发…

【2024程序员必看】鸿蒙应用开发行业分析

鸿蒙操作系统沉浸四年&#xff0c;这次终于迎来了破局的机会&#xff0c;自从2023年华为秋季发布会上宣布鸿蒙 Next操作系统不在兼容Android后&#xff0c;就有不少大厂开始陆续与华为达成了鸿蒙原生应用的开发合作&#xff0c;据1月18日华为官方宣布110多天的产业合力“突进”…

log4j2 无垃圾稳态日志 Garbage-free Steady State Logging

无垃圾稳态日志 垃圾收集暂停是导致延迟峰值的常见原因&#xff0c;对于许多系统来说&#xff0c;需要花费大量精力来控制这些暂停。 许多日志库&#xff0c;包括以前版本的Log4j&#xff0c;在稳态日志记录期间分配临时对象&#xff0c;如日志事件对象、字符串、char数组、字…

RocksDB是如何实现存算分离的

核心参考文献&#xff1a; Dong, S., P, S. S., Pan, S., Ananthabhotla, A., Ekambaram, D., Sharma, A., Dayal, S., Parikh, N. V., Jin, Y., Kim, A., Patil, S., Zhuang, J., Dunster, S., Mahajan, A., Chelluri, A., Datye, C., Santana, L. V., Garg, N., & Gawde,…

基于YOLOv7算法的高精度实时安全帽和背心目标检测系统(PyTorch+Pyside6+YOLOv7)

摘要&#xff1a;基于YOLOv7算法的高精度实时安全帽和背心目标检测系统可用于日常生活中检测与定位安全帽和安全背心&#xff0c;此系统可完成对输入图片、视频、文件夹以及摄像头方式的目标检测与识别&#xff0c;同时本系统还支持检测结果可视化与导出。本系统采用YOLOv7目标…

B样条基函数

​定义&#xff1a;令U{u0,u1,…,um}是一个单调不减的实数序列&#xff0c;即ui≤ui1&#xff0c;i0&#xff0c;1&#xff0c;…&#xff0c;m-1。其中&#xff0c;ui称为节点&#xff0c;U称为节点矢量&#xff0c;用Ni,p(u)表示第i个p次&#xff08;p1阶&#xff09;B样条基…

短视频界的变革者:上海 AI lab 发布 Vlogger,几句话生成分钟级视频

现如今&#xff0c;vlog 已经成为我们日常生活的重要组成部分。无论是看视频学习休闲、记录珍贵瞬间还是分享生活见闻&#xff0c;视频已经成为人们表达创意和观点的独特媒介。 然而&#xff0c;与几秒钟的短视频不同&#xff0c;要创作出引人入胜、生动有趣的长视频&#xff…

十分钟学会用springboot制作微信小程序富文本编辑器

1.1 富文本模型设计 在构建富文本编辑器系统时&#xff0c;首先需要设计一个合适的富文本模型。 CREATE TABLE IF NOT EXISTS rich_texts (id INT PRIMARY KEY AUTO_INCREMENT,title VARCHAR(255),content TEXT,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );这个表包括…

一键转换MOV至MP3:轻松删除原视频,释放存储空间!

你是否曾经有一个MOV格式的视频文件&#xff0c;想要提取其中的音频却苦于没有合适的工具&#xff1f;现在&#xff0c;有了我们的全新视频剪辑工具&#xff0c;这个烦恼全部消失&#xff01;我们为你提供一键式解决方案&#xff0c;将MOV视频文件快速转换为MP3音频格式。 首先…

PyNest 一个可以搭建微服务的 Python 包

PyNest 在构建 Python API 和微服务方面崭露头角&#xff0c;解决了 FastAPI 中存在的关键问题&#xff0c;因此成为卓越的框架。凭借其模块化的架构和先进的特性&#xff0c;PyNest 在 2024 年及以后有望成为 Python 开发者的首选选择。 随着 Python 生态系统的不断成熟&…

YAYI-UIE: 一个用于通用信息提取的聊天增强的指令微调框架

1、写作动机&#xff1a; 最近的研究提出了基于大型语言模型的方法&#xff0c;以统一地建模不同的信息提取任务。然而&#xff0c;这些现有方法在处理英语以外的中文语言的信息提取能力方面存在不足。 2、主要贡献&#xff1a; 提出了YAYI-UIE&#xff0c;一个端到端的聊天…

Prometheus+grafana配置监控系统

使用docker compose安装 方便拓展, 配置信息都放在在 /docker/prometheus 目录下 1.目录结构如下 . ├── conf │ └── prometheus.yml ├── grafana_data ├── prometheus_data └── prometheus_grafana.yaml2.创建目录文件 mkdir /docker/prometheus &&am…

Java面试题之 IO(四)

Java面试题之 IO&#xff08;四&#xff09; 文章目录 Java面试题之 IO&#xff08;四&#xff09;随机访问流 文章来自Java Guide 用于学习如有侵权&#xff0c;立即删除 随机访问流 这里要介绍的随机访问流指的是支持随意跳转到文件的任意位置进行读写的 RandomAccessFile 。…

C# Onnx yolov8 仪表指针检测

目录 效果 模型信息 项目 代码 训练数据 下载 C# Onnx yolov8 仪表指针检测 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-01-31T11:19:38.828556 author&#xff1a;Ultralytics task&#xff1a;detect license&#xff1a;AGPL-…

C++ 哈希 开放定址法

哈希算法 哈希&#xff0c;是一种算法思想吗&#xff0c;它的核心是映射&#xff0c;哈希方法中使用的转换函数称为哈希(散列)函数&#xff0c;构造出来的结构称为哈希表(Hash Table)(或者称散列表) 在STL 中&#xff0c;提供了两个使用哈希底层实现的容器 unordered_set 和 …

西瓜书读书笔记整理(十二) —— 第十二章 计算学习理论(下)

第十二章 计算学习理论&#xff08;下&#xff09; 12.4 VC 维&#xff08;Vapnik-Chervonenkis dimension&#xff09;12.4.1 什么是 VC 维12.4.2 增长函数&#xff08;growth function&#xff09;、对分&#xff08;dichotomy&#xff09;和打散&#xff08;shattering&…

Python算法题集_合并区间

本文为Python算法题集之一的代码示例 题目56&#xff1a;合并区间 说明&#xff1a;以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需…