工业领域的Hadoop架构学习~系列文章05:Kafka消息队列 - 工业数据流传输

第5期:Kafka消息队列 - 工业数据流传输的可靠保证机制

导言:任何不理解Kafka消息语义和ISR机制的工程师无法设计可靠的工业数据采集系统。本期我们将深入Kafka的核心设计,从分布式日志的数学本质出发,阐明ISR机制如何保证数据持久性;解析Exactly-Once语义的实现原理;以及工业场景的高吞吐、低延迟配置优化策略。


5.1 Kafka的核心设计:分布式日志的数学本质

5.1.1 Append-Only日志的数学性质

Kafka的本质是一个分布式、持久化、顺序写的日志系统:

复制代码
Kafka日志的数学模型:

Topic T 由 P 个 Partition 组成:T = {P₁, P₂, ..., Pₚ}

每个 Partition P 是一个有序的只追加(append-only)日志:
P = [m₀, m₁, m₂, ..., mₙ]

其中:
- mᵢ 表示第i条消息
- offset(mᵢ) = i,表示消息的全局唯一位置
- ∀i < j: timestamp(mᵢ) < timestamp(mⱼ)

追加操作的数学表示:
P.append(m) = P ∪ {m},其中 offset(m) = |P|

读操作的数学表示:
P.read(offset) = {m | offset(m) = offset}
P.read_range(start, end) = {m | start ≤ offset(m) < end}

消费者模型:
Consumer Group G = {c₁, c₂, ..., cₖ}
每个 Partition 只能被 G 中的一个 Consumer 消费:
|{p | assigned(p, c)}| = 1 for each c ∈ G

5.1.2 Kafka架构的数学流程

#mermaid-svg-EhSIZs7JQqPLg1Vt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-EhSIZs7JQqPLg1Vt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-EhSIZs7JQqPLg1Vt .error-icon{fill:#552222;}#mermaid-svg-EhSIZs7JQqPLg1Vt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EhSIZs7JQqPLg1Vt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EhSIZs7JQqPLg1Vt .marker.cross{stroke:#333333;}#mermaid-svg-EhSIZs7JQqPLg1Vt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EhSIZs7JQqPLg1Vt p{margin:0;}#mermaid-svg-EhSIZs7JQqPLg1Vt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EhSIZs7JQqPLg1Vt .cluster-label text{fill:#333;}#mermaid-svg-EhSIZs7JQqPLg1Vt .cluster-label span{color:#333;}#mermaid-svg-EhSIZs7JQqPLg1Vt .cluster-label span p{background-color:transparent;}#mermaid-svg-EhSIZs7JQqPLg1Vt .label text,#mermaid-svg-EhSIZs7JQqPLg1Vt span{fill:#333;color:#333;}#mermaid-svg-EhSIZs7JQqPLg1Vt .node rect,#mermaid-svg-EhSIZs7JQqPLg1Vt .node circle,#mermaid-svg-EhSIZs7JQqPLg1Vt .node ellipse,#mermaid-svg-EhSIZs7JQqPLg1Vt .node polygon,#mermaid-svg-EhSIZs7JQqPLg1Vt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EhSIZs7JQqPLg1Vt .rough-node .label text,#mermaid-svg-EhSIZs7JQqPLg1Vt .node .label text,#mermaid-svg-EhSIZs7JQqPLg1Vt .image-shape .label,#mermaid-svg-EhSIZs7JQqPLg1Vt .icon-shape .label{text-anchor:middle;}#mermaid-svg-EhSIZs7JQqPLg1Vt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-EhSIZs7JQqPLg1Vt .rough-node .label,#mermaid-svg-EhSIZs7JQqPLg1Vt .node .label,#mermaid-svg-EhSIZs7JQqPLg1Vt .image-shape .label,#mermaid-svg-EhSIZs7JQqPLg1Vt .icon-shape .label{text-align:center;}#mermaid-svg-EhSIZs7JQqPLg1Vt .node.clickable{cursor:pointer;}#mermaid-svg-EhSIZs7JQqPLg1Vt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-EhSIZs7JQqPLg1Vt .arrowheadPath{fill:#333333;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EhSIZs7JQqPLg1Vt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EhSIZs7JQqPLg1Vt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-EhSIZs7JQqPLg1Vt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EhSIZs7JQqPLg1Vt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-EhSIZs7JQqPLg1Vt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EhSIZs7JQqPLg1Vt .cluster text{fill:#333;}#mermaid-svg-EhSIZs7JQqPLg1Vt .cluster span{color:#333;}#mermaid-svg-EhSIZs7JQqPLg1Vt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EhSIZs7JQqPLg1Vt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-EhSIZs7JQqPLg1Vt rect.text{fill:none;stroke-width:0;}#mermaid-svg-EhSIZs7JQqPLg1Vt .icon-shape,#mermaid-svg-EhSIZs7JQqPLg1Vt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EhSIZs7JQqPLg1Vt .icon-shape p,#mermaid-svg-EhSIZs7JQqPLg1Vt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-EhSIZs7JQqPLg1Vt .icon-shape .label rect,#mermaid-svg-EhSIZs7JQqPLg1Vt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EhSIZs7JQqPLg1Vt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-EhSIZs7JQqPLg1Vt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-EhSIZs7JQqPLg1Vt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ZooKeeper
消费者
Broker集群
生产者
消息流
复制
复制
消费
消费
元数据
元数据
元数据
Producer

分区策略
Broker-1

Leader
Broker-2

Follower
Broker-3

Follower
Consumer-1
Consumer-2
Controller选举

元数据管理


5.2 ISR机制:数据持久性的数学保证

5.2.1 In-Sync Replicas的数学定义

复制代码
Kafka数据持久性保证的核心是ISR机制:

定义1:同步副本集 ISR(t)
ISR(t) = {r | lag(r, t) ≤ maxLag}

其中:
- r 是副本节点
- lag(r, t) 是副本r相对于Leader的延迟
- maxLag 是配置的同步阈值

定义2:写入成功条件
写入操作成功 ⟺ |ISR| ≥ minISR

其中 minISR = max(1, ⌊N/2⌋ + 1),N为副本总数

数学证明:
当 |ISR| ≥ minISR 时:
- 至少 minISR 个节点确认写入
- 即使 minISR - 1 个节点故障,数据仍然存在
- 数据不会丢失

例如:
- 3副本集群:minISR = 2,允许1节点故障
- 5副本集群:minISR = 3,允许2节点故障

5.2.2 ISR机制的工业级实现

java 复制代码
/**
 * Kafka ISR机制的工业级实现
 */
public class IndustrialISRManager {
    
    private final int replicationFactor;
    private final int minISR;
    private final long maxLagBytes;
    private final long maxLagMs;
    
    /**
     * 计算当前ISR集合
     * 
     * ISR判定条件:
     * 1. 副本与Leader的字节延迟 ≤ maxLagBytes
     * 2. 副本与Leader的时间延迟 ≤ maxLagMs
     * 3. 副本状态必须为Running
     */
    public Set<BrokerId> calculateISR(Partition partition) {
        Set<BrokerId> isr = new HashSet<>();
        LeaderAndIsrRequest.PartitionState partitionState = 
            partition.getPartitionState();
        
        BrokerId leader = partitionState.leader;
        long leaderEpoch = partitionState.leaderEpoch;
        long leaderHighWatermark = partitionState.highWatermark;
        
        // Leader自身始终在ISR中
        isr.add(leader);
        
        // 检查所有Follower
        for (Replica replica : partition.getReplicas()) {
            if (replica.brokerId().equals(leader)) continue;
            
            // 计算延迟
            long replicaEndOffset = replica.logEndOffset();
            long lagBytes = leaderHighWatermark - replicaEndOffset;
            long lagMs = System.currentTimeMillis() - 
                replica.lastCaughtUpTimeMs();
            
            // 判断是否满足同步条件
            if (lagBytes <= maxLagBytes && lagMs <= maxLagMs) {
                isr.add(replica.brokerId());
            }
        }
        
        return isr;
    }
    
    /**
     * 生产者acks配置与ISR的关系
     */
    public enum AckLevel {
        ACKS_0(0, "fire-and-forget", "Leader接收即可"),
        ACKS_1(1, "Leader写入", "Leader写入成功"),
        ACKS_ALL(-1, "ISR全部确认", "ISR全部确认");
        
        private final int ackValue;
        private final String description;
        private final String requirement;
        
        AckLevel(int ackValue, String description, String requirement) {
            this.ackValue = ackValue;
            this.description = description;
            this.requirement = requirement;
        }
    }
    
    /**
     * 工业场景推荐的acks配置
     */
    public static AckLevel getRecommendedAckLevel(
            String scenario,
            int replicationFactor
    ) {
        switch (scenario) {
            case "日志采集":
                // 允许少量数据丢失,追求高吞吐
                return AckLevel.ACKS_0;
                
            case "业务数据":
                // 必须保证数据不丢失
                return AckLevel.ACKS_ALL;
                
            case "金融交易":
                // 必须所有副本确认
                return AckLevel.ACKS_ALL;
                
            case "监控指标":
                // 允许少量丢失,追求低延迟
                return AckLevel.ACKS_1;
                
            default:
                return AckLevel.ACKS_1;
        }
    }
}

5.3 Exactly-Once语义:端到端的数学保证

5.3.1 三种消息语义的数学定义

复制代码
Kafka消息语义的三元组:

┌─────────────────────────────────────────────────────────────┐
│  At-Least-Once (acks=1 或 acks=all)                       │
│  ─────────────────────────────────────────────────────────│
│  定义:∀消息m, 最多发送一次,允许多次成功                   │
│  数学:Send(m) ∈ {0, 1} 次成功                             │
│  特点:可能产生重复消息                                     │
│  应用:日志采集、监控指标                                   │
├─────────────────────────────────────────────────────────────┤
│  At-Most-Once (acks=0)                                     │
│  ─────────────────────────────────────────────────────────│
│  定义:∀消息m, 最多发送一次,允许多次失败                   │
│  数学:Send(m) ∈ {0, 1} 次调用                            │
│  特点:可能丢失消息                                        │
│  应用:非关键数据丢弃无影响                                 │
├─────────────────────────────────────────────────────────────┤
│  Exactly-Once (幂等生产者 + 事务)                           │
│  ─────────────────────────────────────────────────────────│
│  定义:∀消息m, 恰好发送一次                               │
│  数学:Send(m) = 1 次成功                                 │
│  特点:端到端精确一次                                      │
│  应用:金融交易、订单处理                                   │
└─────────────────────────────────────────────────────────────┘

5.3.2 Exactly-Once的工业级实现

java 复制代码
/**
 * Kafka Exactly-Once语义工业级实现
 */
public class ExactlyOnceProducer {
    
    private KafkaProducer<String, String> producer;
    private final boolean enableIdempotent;
    private final boolean enableTransactions;
    
    public ExactlyOnceProducer(Properties props) {
        // 幂等生产者配置
        props.put("enable.idempotence", "true");
        // 精确一次事务配置
        props.put("transactional.id", generateTransactionalId());
        props.put("transaction.timeout.ms", "10000");
        
        this.enableIdempotent = true;
        this.enableTransactions = true;
        this.producer = new KafkaProducer<>(props);
    }
    
    /**
     * 幂等生产者核心逻辑
     * 
     * 每个Producer有一个ProducerId
     * 每个Batch有一个SequenceNumber
     * 重复的SequenceNumber会被Broker识别并丢弃
     */
    public Future<RecordMetadata> sendIdempotent(
            String topic, 
            String key, 
            String value
    ) {
        ProducerRecord<String, String> record = 
            new ProducerRecord<>(topic, key, value);
        
        return producer.send(record, (metadata, exception) -> {
            if (exception != null) {
                System.err.println("发送失败: " + exception.getMessage());
            }
        });
    }
    
    /**
     * 事务生产者:跨Topic的Exactly-Once
     * 
     * 应用场景:
     * 1. 从Kafka Topic A消费数据
     * 2. 处理数据
     * 3. 将结果写入Topic B
     * 4. 使用事务保证原子性
     */
    public void sendWithTransaction(
            KafkaConsumer<String, String> consumer,
            String inputTopic,
            String outputTopic
    ) {
        producer.initTransactions();
        
        while (true) {
            ConsumerRecords<String, String> records = 
                consumer.poll(Duration.ofMillis(100));
            
            if (records.isEmpty()) continue;
            
            try {
                producer.beginTransaction();
                
                Map<TopicPartition, Offset> offsetsToCommit = 
                    new HashMap<>();
                
                for (ConsumerRecord<String, String> record : records) {
                    // 处理数据
                    String processedValue = processRecord(record);
                    
                    // 写入结果Topic
                    ProducerRecord<String, String> output = 
                        new ProducerRecord<>(
                            outputTopic, 
                            record.key(), 
                            processedValue
                        );
                    producer.send(output);
                    
                    // 记录消费位置用于提交
                    offsetsToCommit.put(
                        new TopicPartition(record.topic(), record.partition()),
                        new OffsetAndMetadata(record.offset() + 1)
                    );
                }
                
                // 提交消费位置
                producer.sendOffsetsToTransaction(
                    offsetsToCommit, 
                    consumer.groupMetadata()
                );
                
                producer.commitTransaction();
                
            } catch (Exception e) {
                producer.abortTransaction();
                System.err.println("事务回滚: " + e.getMessage());
            }
        }
    }
    
    /**
     * 生成事务ID
     */
    private String generateTransactionalId() {
        // 格式: {pod_name}-{producer_id}-{epoch}
        String podName = System.getenv("HOSTNAME");
        long producerId = new Random().nextLong();
        return podName + "-" + producerId;
    }
}

5.4 工业场景Kafka高吞吐配置

5.4.1 生产者配置参数矩阵

python 复制代码
"""
Kafka生产者工业级配置计算器
"""

class KafkaProducerConfig:
    """Kafka生产者配置优化"""
    
    @staticmethod
    def calculate_optimal_batch_size(
        network_bandwidth_mbps: float,
        target_latency_ms: float,
        compression_ratio: float = 0.3
    ) -> int:
        """
        计算最优批次大小
        
        目标:
        - 批处理延迟 < target_latency_ms
        - 充分利用网络带宽
        
        公式:
        BatchSize = min(
            bandwidth × latency × compression_ratio,
            max_batch_size
        )
        """
        bandwidth_bytes = network_bandwidth_mbps * 1024 * 1024 / 8
        latency_seconds = target_latency_ms / 1000
        
        optimal = bandwidth_bytes * latency_seconds * compression_ratio
        
        # Kafka批次最大16384KB
        return min(int(optimal), 16384)
    
    @staticmethod
    def calculate_linger_ms(
        throughput_mb_per_sec: float,
        batch_size_kb: int
    ) -> float:
        """
        计算linger.ms
        
        linger.ms控制等待填充批次的时间
        权衡延迟和吞吐量
        """
        batch_bytes = batch_size_kb * 1024
        target_throughput = throughput_mb_per_sec * 1024 * 1024
        
        # 达到目标吞吐量需要的等待时间
        if target_throughput > 0:
            linger_ms = (batch_bytes / target_throughput) * 1000
            return min(linger_ms, 100)  # 最大100ms
        return 5  # 默认5ms
    
    @staticmethod
    def calculate_buffer_memory(
        max_in_flight_requests: int,
        batch_size_kb: int,
        queue_depth: int
    ) -> int:
        """
        计算buffer.memory
        
        公式:
        Memory = max_in_flight × batch_size × queue_depth
        """
        memory = max_in_flight_requests * batch_size_kb * queue_depth
        return max(memory, 32 * 1024)  # 最小32MB
    
    @staticmethod
    def get_industrial_config(
        scenario: str,
        network_mbps: float = 1000
    ) -> dict:
        """
        工业场景推荐配置
        """
        configs = {
            "high_throughput": {
                # 高吞吐场景:批量处理
                "bootstrap.servers": "kafka-1:9092,kafka-2:9092,kafka-3:9092",
                "acks": "1",  # 工业场景用acks=1平衡可靠性和性能
                "compression.type": "lz4",
                "batch.size": 262144,  # 256KB
                "linger.ms": 20,
                "buffer.memory": 134217728,  # 128MB
                "max.in.flight.requests.per.connection": 10,
                "retries": 3,
            },
            "low_latency": {
                # 低延迟场景:实时监控
                "bootstrap.servers": "kafka-1:9092,kafka-2:9092,kafka-3:9092",
                "acks": "1",
                "compression.type": "lz4",
                "batch.size": 32768,  # 32KB
                "linger.ms": 5,
                "buffer.memory": 67108864,  # 64MB
                "max.in.flight.requests.per.connection": 5,
                "retries": 1,
            },
            "exactly_once": {
                # 精确一次场景
                "bootstrap.servers": "kafka-1:9092,kafka-2:9092,kafka-3:9092",
                "acks": "all",
                "compression.type": "lz4",
                "enable.idempotence": "true",
                "transactional.id": "auto",  # 自动生成
                "max.in.flight.requests.per.connection": 5,  # 必须≤5
                "retries": 0,  # 事务模式下禁用重试
            }
        }
        
        return configs.get(scenario, configs["high_throughput"])

# 工业场景配置实例
if __name__ == '__main__':
    config = KafkaProducerConfig()
    
    # 计算最优配置
    batch_size = config.calculate_optimal_batch_size(
        network_bandwidth_mbps=1000,
        target_latency_ms=50
    )
    
    linger_ms = config.calculate_linger_ms(
        throughput_mb_per_sec=100,
        batch_size_kb=batch_size // 1024
    )
    
    buffer_memory = config.calculate_buffer_memory(
        max_in_flight_requests=10,
        batch_size_kb=batch_size // 1024,
        queue_depth=50
    )
    
    print(f"""
    ╔═══════════════════════════════════════════════════════════╗
    ║              Kafka生产者推荐配置                            ║
    ╠═══════════════════════════════════════════════════════════╣
    ║  最优批次大小: {batch_size} bytes ({batch_size/1024:.0f} KB)              ║
    ║  建议linger.ms: {linger_ms:.1f} ms                                ║
    ║  建议buffer.memory: {buffer_memory/1024/1024:.0f} MB                          ║
    ╚═══════════════════════════════════════════════════════════╝
    """)

5.4.2 消费者配置参数矩阵

参数 默认值 高吞吐推荐 低延迟推荐 精确一次推荐
fetch.min.bytes 1 1048576 1 1024
fetch.max.wait.ms 500 500 100 200
max.poll.records 500 1000 100 500
enable.auto.commit true false true false
auto.offset.reset latest earliest earliest earliest
session.timeout.ms 10000 30000 10000 45000

5.5 本期小结

复制代码
┌─────────────────────────────────────────────────────────────┐
│                Kafka消息队列知识体系                         │
├─────────────────────────────────────────────────────────────┤
│  第1层:理论基础层                                          │
│  ├── Append-Only日志:P = [m₀, m₁, ..., mₙ]               │
│  ├── 消息位置:offset(mᵢ) = i                            │
│  └── 消费者组:每个Partition只能被一个Consumer消费          │
├─────────────────────────────────────────────────────────────┤
│  第2层:持久性保证层                                        │
│  ├── ISR定义:ISR(t) = {r | lag(r,t) ≤ maxLag}           │
│  ├── 写入条件:|ISR| ≥ minISR                             │
│  └── minISR计算:max(1, ⌊N/2⌋ + 1)                        │
├─────────────────────────────────────────────────────────────┤
│  第3层:消息语义层                                          │
│  ├── At-Least-Once:幂等生产者                             │
│  ├── At-Most-Once:fire-and-forget                       │
│  └── Exactly-Once:幂等+事务                               │
├─────────────────────────────────────────────────────────────┤
│  第4层:性能优化层                                          │
│  ├── batch.size:256KB工业推荐                             │
│  ├── linger.ms:5-20ms平衡延迟吞吐                        │
│  └── compression.type:lz4平衡速度和压缩率                 │
└─────────────────────────────────────────────────────────────┘

下期预告第6期:Hive数据仓库 - 工业数据的SQL化查询引擎------深度解析Hive的查询优化器、执行引擎、以及如何通过LLAP实现亚秒级查询响应。


作者:高炉炼铁智能化技术研究者,专注钢铁冶金与人工智能 交叉领域。

👍 如果觉得有帮助,请点赞、收藏、转发!

版权归作者所有,未经许可请勿抄袭,套用,商用(或其它具有利益性行为)

🔔 关注专栏,不错过后续精彩内容!

相关推荐
零陵上将军_xdr1 小时前
后端转全栈学习-Day3-JavaScript 基础-1
开发语言·javascript·学习
zcg19421 小时前
如何在CV中使用transformer
人工智能·深度学习·transformer
xiaobangsky1 小时前
AI 时代来临,我该何去何从
人工智能
是烨笙啊1 小时前
PromptMaster:支持变量插入、内置生成功能的提示词管理插件
人工智能·edge浏览器·提示词·浏览器插件
前端不太难1 小时前
具身智能:AI从“理解世界”到“改造世界”的关键一步
人工智能·状态模式
SuperHeroWu71 小时前
【MindSpore】MindSpore 开源深度学习框架
人工智能·深度学习·开源·框架·mindspore
人工智能培训1 小时前
数字孪生赋能建筑行业 解锁工程全周期智慧管理
大数据·人工智能·机器学习·prompt·agent
承渊政道1 小时前
Linux系统学习【进程控制:进程创建、终止与等待、进程程序替换、自主shell命令行解释器详解】
linux·服务器·c++·学习·ubuntu·bash·远程工作
zhangfeng11331 小时前
华为昇腾910A NPU 的模型加密方案 ASCEND-CC
开发语言·人工智能·神经网络·transformer