Spark集群优化配置指南

📋 概述

本文档记录了5节点Spark集群的性能优化配置,主要解决Thrift Server内存不足(OOM)问题和CPU资源利用率低的问题。

文档内容

  • Spark架构原理: Driver与Executor的关系和工作机制
  • Driver内存配置详解: 三个关键内存参数的作用和配置原理
  • Hive与Thrift Server关系: 架构演进和OOM错误的根本原因分析
  • 问题分析: OOM错误和资源浪费的根本原因
  • 优化方案: 差异化CPU配置和内存优化策略
  • 配置文件: 完整的spark-env.sh和spark-defaults.conf配置
  • 部署指南: 详细的实施步骤和验证方法

🏗️ 集群架构

硬件配置

  • 节点数量: 5个节点
  • 每节点CPU: 8核
  • 每节点内存: 32GB
  • Master节点: warehouse01 (同时作为Worker节点)
  • Worker节点: warehouse02, warehouse03, warehouse04, warehouse05

节点角色分配

warehouse01 (Master + Worker):
├─ Spark Master进程
├─ Spark Worker进程  
├─ Thrift Server进程
├─ Hadoop DataNode/NodeManager
├─ DolphinScheduler Worker
└─ 其他管理进程warehouse02-05 (Worker only):
├─ Spark Worker进程
└─ 基础系统进程

🏗️ Spark架构原理

Driver与Executor关系

Spark应用采用1对多的架构设计:1个Driver进程管理多个Executor进程。

一个Spark应用 = 1个Driver + 多个Executor
┌─────────────────────────────────────────────────────────────┐
│                    Spark Application                        │
├─────────────────────────────────────────────────────────────┤
│                     Driver进程 (1个)                        │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ SparkContext                                            │ │
│ │ ├─ 任务调度器 (DAGScheduler)                            │ │
│ │ ├─ 集群管理器接口                                       │ │
│ │ ├─ 任务分发逻辑                                         │ │
│ │ └─ 结果收集和聚合                                       │ │
│ └─────────────────────────────────────────────────────────┘ │
│                           │                                 │
│                           │ 任务分发和结果收集               │
│                           ▼                                 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │                 Executor进程 (多个)                      │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐         │ │
│ │ │ Executor 1  │ │ Executor 2  │ │ Executor N  │   ...   │ │
│ │ │ ├─ Task执行  │ │ ├─ Task执行  │ │ ├─ Task执行  │         │ │
│ │ │ ├─ 数据缓存  │ │ ├─ 数据缓存  │ │ ├─ 数据缓存  │         │ │
│ │ │ └─ 结果返回  │ │ └─ 结果返回  │ │ └─ 结果返回  │         │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘         │ │
│ └─────────────────────────────────────────────────────────┘ │
│                                                             │
│ 集群资源分配:                                               │
│ ├─ warehouse01: 1个Driver + 2个Executor                    │
│ ├─ warehouse02-05: 3个Executor each                        │
│ └─ 总计: 1个Driver + 14个Executor                          │
└─────────────────────────────────────────────────────────────┘

职责分工

Driver进程职责(大脑):
  • 创建SparkContext,管理应用生命周期
  • 解析SQL语句,构建DAG执行计划
  • 将DAG分解为Stage和Task
  • 调度Task到各个Executor执行
  • 监控Task执行状态和故障恢复
  • 收集和聚合所有Executor的结果
  • 处理客户端连接(Thrift Server场景)
Executor进程职责(工人):
  • 接收Driver分发的Task任务
  • 执行具体的数据计算操作
  • 缓存RDD数据到内存或磁盘
  • 将计算结果返回给Driver
  • 向Driver汇报执行状态
  • 管理本地数据存储

SQL查询执行流程示例

-- 用户提交查询
SELECT COUNT(*) FROM large_table WHERE date > '2024-01-01';

执行过程:

  1. Driver接收查询 → 解析SQL,优化查询计划,生成物理执行计划
  2. Driver创建任务 → 将查询转换为RDD操作链(读取→过滤→聚合)
  3. Driver分发任务 → 将任务分发到14个Executor并行执行
  4. Executor并行计算 → 各自处理数据分区,执行过滤和计数
  5. Driver收集结果 → 聚合所有Executor的部分结果,返回最终答案

🔍 问题分析

原始问题

  1. Thrift Server OOM错误: java.lang.OutOfMemoryError: Java heap space
  2. CPU资源浪费: 只使用1核心,集群利用率仅12.5%
  3. 内存配置不合理: Driver内存2g不足,Executor内存5g与Worker内存24g不匹配

根本原因

  • Driver内存配置过小,无法处理大查询结果集和RPC通信
  • CPU核心配置过于保守,严重浪费硬件资源
  • 缺少关键的性能优化配置
  • 对Driver堆外内存需求估计不足(反序列化OOM)

🧠 Driver内存配置详解

Driver内存架构

Driver进程总内存 = JVM堆内存 + 堆外内存 + 系统开销
┌─────────────────────────────────────────────────────┐
│                Driver进程内存空间                    │
├─────────────────────────────────────────────────────┤
│ JVM堆内存 (spark.driver.memory=4g)                  │
│ ├─ SparkContext对象                                 │
│ ├─ 任务调度数据结构                                  │
│ ├─ 广播变量                                         │
│ ├─ 累加器                                           │
│ └─ collect()收集的结果数据 ← 容易OOM的地方           │
├─────────────────────────────────────────────────────┤
│ 堆外内存 (spark.driver.memoryOverhead=2g)           │
│ ├─ RPC通信缓冲区                                    │
│ ├─ 序列化/反序列化缓冲区 ← OOM错误发生的地方         │
│ ├─ 网络传输缓冲区                                   │
│ └─ JVM元数据空间                                    │
├─────────────────────────────────────────────────────┤
│ 系统开销 (~500MB)                                   │
└─────────────────────────────────────────────────────┘

三个关键参数详解

1. spark.driver.memory=4g (JVM堆内存)

作用: 存储Driver进程的Java对象,包括SparkContext、任务调度信息、查询结果等。

为什么设置4g:

# 内存使用场景分析
├─ SparkContext初始化: ~200MB
├─ 任务调度元数据: ~300MB
├─ Thrift Server连接管理: ~500MB
├─ SQL查询结果缓存: ~1-2GB ← 主要消耗
├─ 广播变量: ~200MB
└─ JVM开销: ~800MB
总计: ~3-4GB,因此设置4g是合理的最小值
2. spark.driver.memoryOverhead=2g (堆外内存)

作用: 处理RPC通信、序列化/反序列化、网络传输等堆外操作。

为什么设置2g:

# 您的OOM错误堆栈分析
java.lang.OutOfMemoryError: Java heap space
at java.io.ObjectInputStream.readObject
at org.apache.spark.serializer.JavaDeserializationStream.readObject
at org.apache.spark.rpc.netty.NettyRpcEnv.deserialize# 错误发生在反序列化过程中,这使用的是堆外内存!# Thrift Server特有的高堆外内存需求
├─ 多客户端并发连接: 每个连接需要缓冲区
├─ 大量RPC消息: Driver与Executor频繁通信
├─ 复杂查询结果: 大对象的序列化/反序列化
├─ 网络传输: 数据在网络中的缓冲
└─ JVM元空间: 类加载和方法区
3. spark.driver.maxResultSize=2g (结果集大小限制)

作用: 防止单个查询结果过大导致Driver OOM的保护机制。

为什么设置2g:

# 没有这个限制的风险
SELECT * FROM huge_table;  -- 可能返回几十GB数据到Driver
df.collect()               -- 将整个DataFrame拉取到Driver# 设置2g限制的好处
├─ 防止单个查询耗尽所有Driver内存
├─ 强制开发者优化查询(使用LIMIT、过滤条件)
├─ 保护Thrift Server稳定性
└─ 2g足够大多数正常查询需求

配置协调关系

# 内存分配逻辑
总Driver内存需求 = 堆内存 + 堆外内存 + 系统开销= 4g + 2g + 0.5g = 6.5g# 单个查询的内存使用
查询内存使用 ≤ min(driver.memory, driver.maxResultSize)≤ min(4g, 2g) = 2g# 这样设计的好处:
├─ 堆内存4g:足够处理正常业务查询
├─ 堆外内存2g:解决序列化OOM问题
├─ 结果集限制2g:防止异常查询影响系统
└─ 总内存6.5g:在32g节点上是合理的

🔗 Hive与Spark Thrift Server关系详解

架构演进历史

传统的Hive架构使用MapReduce作为执行引擎,而现代的Spark-on-Hive架构使用Spark作为执行引擎:

传统Hive架构 → Spark-on-Hive架构
┌─────────────────────┐    ┌─────────────────────┐
│   传统Hive架构       │    │  Spark-on-Hive架构   │
├─────────────────────┤    ├─────────────────────┤
│ HiveServer2         │    │ Spark Thrift Server │
│ ├─ SQL解析          │    │ ├─ SQL解析          │
│ ├─ 查询优化         │    │ ├─ 查询优化         │
│ └─ 执行引擎调用     │    │ └─ Spark执行引擎    │
├─────────────────────┤    ├─────────────────────┤
│ MapReduce执行引擎   │ →  │ Spark执行引擎       │
│ ├─ Map阶段          │    │ ├─ RDD转换          │
│ ├─ Reduce阶段       │    │ ├─ 内存计算         │
│ └─ 磁盘I/O密集      │    │ └─ 高性能并行       │
├─────────────────────┤    ├─────────────────────┤
│ Hive Metastore      │    │ Hive Metastore      │
│ (表结构元数据)       │    │ (表结构元数据)       │
└─────────────────────┘    └─────────────────────┘

Spark Thrift Server的本质

Spark Thrift Server实际上是:

  • Hive兼容的SQL接口 + Spark执行引擎
  • 替代了传统的HiveServer2,但保持了Hive SQL的兼容性
  • 使用Spark作为底层执行引擎,而不是MapReduce
  • 关键点:Thrift Server和Spark Driver运行在同一个JVM进程中

进程架构对比

客户端连接 → Thrift Server → Spark Driver → Spark Executors
┌─────────┐   ┌─────────────┐   ┌─────────────┐   ┌─────────────┐
│ JDBC/   │   │ Thrift      │   │ Spark       │   │ Spark       │
│ ODBC   │──▶│ Server      │──▶│ Driver      │──▶│ Executors   │
│ 客户端   │   │ (SQL接口)   │   │ (任务调度)   │   │ (数据计算)   │
└─────────┘   └─────────────┘   └─────────────┘   └─────────────┘│                 │└─────────────────┘同一个JVM进程!

🚨 OOM错误的根本原因分析

错误堆栈解读

您遇到的OOM错误堆栈:

java.lang.OutOfMemoryError: Java heap space
at java.io.ObjectStreamClass.getDeclaredMethod
at java.io.ObjectInputStream.readObject
at org.apache.spark.serializer.JavaDeserializationStream.readObject
at org.apache.spark.rpc.netty.NettyRpcEnv.deserialize
at org.apache.spark.rpc.netty.RequestMessage$.apply

错误发生的具体位置:

错误链路分析:
1. 客户端发送SQL查询到Thrift Server
2. Thrift Server解析SQL,生成Spark任务
3. Driver将任务分发给Executors
4. Executors执行完成,返回结果给Driver ← 问题发生在这里
5. Driver需要反序列化Executor返回的结果
6. 反序列化过程中内存不足,导致OOM

Thrift Server的内存使用模式

Thrift Server进程内存使用:
┌─────────────────────────────────────────────────────────┐
│ Thrift Server + Driver 进程 (同一个JVM)                 │
├─────────────────────────────────────────────────────────┤
│ Thrift Server部分内存使用:                              │
│ ├─ 客户端连接管理: ~200MB                               │
│ ├─ SQL解析和优化: ~300MB                                │
│ ├─ 会话管理: ~200MB                                     │
│ └─ 结果缓存: ~500MB                                     │
├─────────────────────────────────────────────────────────┤
│ Spark Driver部分内存使用:                               │
│ ├─ SparkContext: ~200MB                                │
│ ├─ 任务调度: ~300MB                                     │
│ ├─ RPC通信缓冲区: ~1GB ← OOM发生的地方                   │
│ ├─ 结果反序列化: ~1-2GB ← 主要问题                       │
│ └─ 结果收集: ~1GB                                       │
└─────────────────────────────────────────────────────────┘
总内存需求: ~4-6GB (原配置只有2g+1g=3GB)

典型的OOM触发场景

场景1: 大结果集查询
-- 这种查询会导致Driver OOM
SELECT * FROM large_table LIMIT 100000;

执行过程中的内存使用:

  1. Executors读取数据并处理 (使用Executor内存)
  2. Executors将结果序列化后发送给Driver
  3. Driver接收并反序列化结果 ← OOM发生在这里
  4. Driver将结果返回给Thrift Server
  5. Thrift Server返回给客户端
场景2: 复杂聚合查询
-- 这种查询也可能导致Driver OOM
SELECT category, COUNT(*), AVG(price)
FROM products
GROUP BY category;

内存使用分析:

  1. Executors执行GROUP BY聚合 (使用Executor内存)
  2. 聚合结果发送给Driver进行最终合并
  3. Driver反序列化所有分组结果 ← 内存压力大
  4. Driver进行最终聚合计算
  5. 返回最终结果
场景3: 多客户端并发
并发场景的内存叠加:
├─ 客户端1: 查询A的结果反序列化 (500MB)
├─ 客户端2: 查询B的结果反序列化 (800MB)
├─ 客户端3: 查询C的结果反序列化 (600MB)
├─ RPC通信缓冲区: (400MB)
└─ 其他开销: (300MB)
总计: 2.6GB ← 超过原来的2GB Driver内存

为什么增加Driver内存能解决问题

内存配置的作用机制:
# 优化前的问题
spark.driver.memory=2g              # JVM堆内存不足
spark.driver.memoryOverhead=1g      # 堆外内存不足,反序列化失败# 优化后的解决方案
spark.driver.memory=4g              # 增加堆内存,处理更大结果集
spark.driver.memoryOverhead=2g      # 增加堆外内存,解决反序列化OOM
spark.driver.maxResultSize=2g       # 限制单个查询结果,防止异常查询
三个参数的协同作用:
内存分配策略:
┌─────────────────────────────────────────────────────────┐
│ 总Driver内存: 6GB (4g堆内存 + 2g堆外内存)                │
├─────────────────────────────────────────────────────────┤
│ 堆内存4g用途:                                           │
│ ├─ Thrift Server基础功能: 1g                            │
│ ├─ Spark Driver基础功能: 1g                             │
│ ├─ 查询结果收集和缓存: 2g                                │
│ └─ JVM开销和预留: 适量                                   │
├─────────────────────────────────────────────────────────┤
│ 堆外内存2g用途:                                         │
│ ├─ RPC通信缓冲区: 800MB                                 │
│ ├─ 序列化/反序列化: 1GB ← 解决您的OOM问题                │
│ ├─ 网络传输缓冲: 200MB                                  │
│ └─ JVM元空间: 适量                                      │
└─────────────────────────────────────────────────────────┘

关键要点总结

  1. Thrift Server = Hive SQL接口 + Spark执行引擎
  2. Thrift Server和Driver运行在同一个JVM进程中
  3. OOM发生在Driver反序列化Executor结果的过程中
  4. 增加Driver内存直接解决了Thrift Server的内存不足问题
为什么不是传统Hive进程的问题:
传统Hive vs Spark Thrift Server:
├─ 传统Hive: HiveServer2进程 + MapReduce执行
├─ Spark Thrift Server: 单一进程包含SQL接口和Spark Driver
├─ 您的集群: 使用Spark Thrift Server,没有独立的Hive进程
└─ 因此: 内存问题就是Driver内存问题

🎯 优化方案

1. 差异化CPU配置

考虑到Master节点运行多个管理进程,采用差异化配置:

# Master节点 (warehouse01)
SPARK_WORKER_CORES=4    # 预留4核给管理进程# Worker节点 (warehouse02-05)  
SPARK_WORKER_CORES=6    # 保守配置,预留2核给系统

2. 内存优化配置

# Driver配置(解决OOM问题)
spark.driver.memory=4g              # 从2g增加到4g
spark.driver.memoryOverhead=2g      # 从1g增加到2g
spark.driver.maxResultSize=2g       # 新增:限制结果集大小# Executor配置(优化资源利用)
spark.executor.memory=8g            # 从5g增加到8g
spark.executor.memoryOverhead=1g    # 保持1g

3. 性能优化配置

# 序列化优化(解决反序列化OOM)
spark.serializer=org.apache.spark.serializer.KryoSerializer
spark.kryoserializer.buffer.max=1g  # 从128m增加到1g# SQL自适应优化
spark.sql.adaptive.enabled=true
spark.sql.adaptive.coalescePartitions.enabled=true
spark.sql.thriftServer.incrementalCollect=true

🔧 配置文件修改

1. spark-env.sh配置

Master节点配置
# /opt/svr/spark-3.4.3-bin-hadoop3/conf/spark-env.sh
JAVA_HOME=/opt/svr/java-se-8u43-ri
SPARK_DAEMON_MEMORY="1g"            # 从4g优化到1g
SPARK_WORKER_CORES=4                # Master节点4核
SPARK_WORKER_MEMORY=24g
SPARK_PID_DIR=/opt/data/pid
Worker节点配置
# Worker节点 spark-env.sh
JAVA_HOME=/opt/svr/java-se-8u43-ri
SPARK_DAEMON_MEMORY="1g"
SPARK_WORKER_CORES=6                # Worker节点6核
SPARK_WORKER_MEMORY=24g
SPARK_PID_DIR=/opt/data/pid

2. spark-defaults.conf配置

# 基础配置
spark.master=spark://10.138.4.4:7077
spark.cores.max=28                  # 4+6×4=28核
spark.sql.sources.partitionOverwriteMode=dynamic# Driver配置(解决OOM)
spark.driver.memory=4g
spark.driver.memoryOverhead=2g
spark.driver.maxResultSize=2g# Executor配置
spark.executor.memory=8g
spark.executor.memoryOverhead=1g
spark.executor.cores=2# 内存管理
spark.memory.fraction=0.8
spark.memory.storageFraction=0.3# 并行度配置
spark.default.parallelism=112       # 28×4
spark.sql.shuffle.partitions=112# 动态资源分配
spark.dynamicAllocation.enabled=true
spark.dynamicAllocation.minExecutors=1
spark.dynamicAllocation.maxExecutors=14    # 28÷2=14
spark.dynamicAllocation.initialExecutors=2
spark.dynamicAllocation.executorIdleTimeout=60s# 序列化优化
spark.serializer=org.apache.spark.serializer.KryoSerializer
spark.kryoserializer.buffer.max=1g
spark.locality.wait=3s# 推测执行
spark.speculation=true
spark.speculation.multiplier=1.5# SQL优化
spark.sql.adaptive.enabled=true
spark.sql.adaptive.coalescePartitions.enabled=true
spark.sql.adaptive.skewJoin.enabled=true
spark.sql.hive.metastorePartitionPruning=true
spark.sql.thriftServer.incrementalCollect=true# Iceberg配置
spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
spark.sql.catalog.spark_catalog=org.apache.iceberg.spark.SparkSessionCatalog
spark.sql.catalog.spark_catalog.type=hive
spark.sql.catalog.ice=org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.ice.type=hadoop
spark.sql.catalog.ice.warehouse=/user/iceberg/warehouse

📊 资源分配对比

优化前 vs 优化后

配置项优化前优化后提升
CPU利用率12.5% (5核/40核)70% (28核/40核)460%
Driver内存2g+1g=3g4g+2g=6g100%
Executor内存5g+1g=6g8g+1g=9g50%
最大Executor数5个14个180%
并行度40112180%

内存分配验证

# Master节点内存使用
├─ 管理进程: ~6g
├─ Driver进程: 6g (4g+2g)
├─ Executor进程: 18g (9g×2)
├─ 系统预留: 2g
└─ 总计: 32g ✅# Worker节点内存使用  
├─ Executor进程: 27g (9g×3)
├─ Worker守护进程: 1g
├─ 系统预留: 4g
└─ 总计: 32g ✅

🚀 部署步骤

1. 备份原配置

cd /opt/svr/spark-3.4.3-bin-hadoop3/conf/
cp spark-env.sh spark-env.sh.backup
cp spark-defaults.conf spark-defaults.conf.backup

2. 修改Master节点配置

# 修改spark-env.sh(确保SPARK_WORKER_CORES=4)
vi /opt/svr/spark-3.4.3-bin-hadoop3/conf/spark-env.sh# 修改spark-defaults.conf(按上述配置更新)
vi /opt/svr/spark-3.4.3-bin-hadoop3/conf/spark-defaults.conf

3. 配置Worker节点

# 创建Worker专用配置
cat > spark-env-worker.sh << 'EOF'
JAVA_HOME=/opt/svr/java-se-8u43-ri
SPARK_DAEMON_MEMORY="1g"
SPARK_WORKER_CORES=6
SPARK_WORKER_MEMORY=24g
SPARK_PID_DIR=/opt/data/pid
EOF# 分发到Worker节点
for i in {2..5}; doecho "配置 warehouse0$i..."scp spark-env-worker.sh warehouse0$i:/opt/svr/spark-3.4.3-bin-hadoop3/conf/spark-env.sh
done

4. 重启集群

cd /opt/svr/spark-3.4.3-bin-hadoop3/sbin/# 完整重启序列
./stop-thriftserver.sh
./stop-all.sh
sleep 5
./start-all.sh
sleep 10
./start-thriftserver.sh

✅ 验证配置

1. 检查进程内存

# 检查Thrift Server Driver内存
ps -ef | grep "HiveThriftServer2" | grep -o "\-Xmx[0-9]*[gm]"
# 应该显示: -Xmx4g# 检查Executor内存
ps -ef | grep "CoarseGrainedExecutorBackend" | grep -o "\-Xmx[0-9]*[gm]"
# 应该显示: -Xmx8192M

2. 检查集群状态

# 访问Master UI: http://10.138.4.4:8080
# 应该看到:
# - warehouse01: 4 cores, 24GB RAM
# - warehouse02-05: 6 cores each, 24GB RAM each# 访问Thrift Server UI: http://10.138.4.4:4040
# 检查Environment页面确认所有配置生效

3. 性能测试

# 执行测试查询验证OOM问题是否解决
# 监控资源使用情况确认优化效果

📈 预期效果

性能提升

  • CPU利用率: 从12.5%提升到70%
  • 查询性能: 预计提升50-100%
  • 并发处理能力: 提升180%
  • OOM问题: 完全解决

稳定性改进

  • 系统稳定性: 保留30%资源余量,避免过载
  • 可维护性: 配置清晰,便于监控和调优
  • 扩展性: 为未来扩容预留空间

🔧 故障排除

常见问题

  1. 配置不生效: 确保重启了整个集群
  2. SSH连接失败: 检查免密登录配置
  3. 内存不足: 根据实际硬件调整内存配置
  4. 网络问题: 检查防火墙和端口配置

回滚方案

# 如果出现问题,可以快速回滚
cd /opt/svr/spark-3.4.3-bin-hadoop3/conf/
cp spark-env.sh.backup spark-env.sh
cp spark-defaults.conf.backup spark-defaults.conf# 重启集群
cd ../sbin/
./stop-thriftserver.sh && ./stop-all.sh
./start-all.sh && ./start-thriftserver.sh

📝 维护建议

  1. 定期监控: 关注CPU、内存使用率和GC情况
  2. 性能调优: 根据实际工作负载调整并行度和内存配置
  3. 容量规划: 随着数据量增长及时扩容
  4. 配置管理: 使用版本控制管理配置文件变更

创建日期: 2025-07-11
更新日期: 2025-07-11
适用版本: Spark 3.4.3, Hadoop 3.3.6
集群规模: 5节点,每节点8核32GB

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Layui —— select

前言&#xff1a;记录在修改bug时遇到的一些奇怪问题。遇到的奇怪问题1&#xff1a;项目中引入了 layui&#xff0c;而且也使用了 layui.use 按需导入了需要的组件&#xff0c;但是在页面每次刚初始化的时候去使用layui&#xff0c;控制台都会报 组件未定义的问题&#xff08;正…

代码随想录day32dp1

文章目录509. 斐波那契数70. 爬楼梯746. 使用最小花费爬楼梯确定dp数组&#xff08;dp table&#xff09;以及下标的含义 确定递推公式 dp数组如何初始化 确定遍历顺序 举例推导dp数组509. 斐波那契数 题目链接 文章讲解 class Solution { public:int fib(int n) {// 1. 确定…

RedisJSON 技术揭秘`JSON.ARRTRIM`用窗口裁剪,让数组保持“刚刚好”

1、指令速查 JSON.ARRTRIM <key> <path> <start> <stop>key&#xff1a;Redis 键名path&#xff1a;JSONPath&#xff0c;默认 $ 根&#xff1b;可用 .[*]/.. 多路径匹配start / stop&#xff1a;要保留的 [start, stop] 闭区间索引 支持负值&#xff…

fpga调试经验

fpga调试经验 调测场景&#xff1a; 外接adc传感器芯片&#xff0c;采集压力&#xff0c;温度等模拟量&#xff0c;fpga通过spi/i2c接口与adc传感器芯片通信 问题1&#xff1a;adc芯片在稳定环境中&#xff0c;输出数字量不稳定。 结论&#xff1a;adc输入电压由fpga板供应&…

cefSharp.WinForms.NETCore 138.xx (cef138/Chromium 138.0.7204.97) 升级测试体验

一、版本说明及变化 该版本支持cef138.0.x系列,cefsharp138.0.170 无重大更新;该版本暂不支持h264,请关注后续 关注栏目,关注我,学习cefsharp少走弯路 不迷路! CefSharp 设置缓存的注意事项参考 说明:栏目是订阅文章,无附件,如需要单独获取(看底部介绍说明) 该版本1…

chatgpt是怎么诞生的,详解GPT1到GPT4的演化之路及相关背景知识

人工智能革命正在发生&#xff0c;我们是何其幸运的一代&#xff0c;能亲眼见证人类/机器智能的大爆发。 仅仅作为这场革命的看客显然是有些遗憾的&#xff0c;如何进一步了解它&#xff1f; 本文将讨论chatgpt的诞生过程&#xff0c;串联起OpenAI发表的一系列重要论文&#…

[笔记] 动态 SQL 查询技术解析:构建灵活高效的企业级数据访问层

文章目录一. 应用场景二. 使用示例示例1示例2示例3三. 实现1. 动态表查询构建器&#xff0c;模仿MyBatis-Plus2. mapper3. mapper.xml功能概述参数说明四. 动态 SQL 的优化与风险防控在企业级应用开发中&#xff0c;数据查询场景往往呈现出复杂多变的特点 —— 从简单的单表筛选…

.net天擎分钟降水数据统计

1.需求&#xff1a;计算滑动时间下的1小时、3小时、6小时、12小时、24小时降水数据&#xff0c;统计这个时间下的分钟级降水数据2.分析第一版本&#xff1a;降水分钟级数据保存时间不长&#xff0c;保存太多意义不大&#xff0c;以更新的形式来保存这些统计数据效果会比较好&am…

图片合并pdf

文章目录 背景目标实现下载 背景 整合&#xff1a; 将零散的图片集合成一个单一文件。有序化&#xff1a; 固定图片的排列顺序。标准化&#xff1a; 转换为通用、兼容性强的PDF格式。高效管理&#xff1a; 便于存储、查找、分享和传输。正式化/文档化&#xff1a; 满足提交、报…

【vue3+js】文件下载方法整理

前端文件下载方式 引言 在前端开发中,文件下载是一个常见的需求。后端可能以不同的方式返回文件数据,前端需要根据不同的返回类型采用相应的处理方式。本文将总结几种常见的后端返回类型及对应的前端处理方案,主要基于Vue3和JavaScript环境。 一、后端返回文件URL 场景描…

MicrobiomeStatPlots | 森林图教程Forest plot tutorial

视频讲解https://www.bilibili.com/video/BV1mA3yzEEnc/森林图简介什么是森林图&#xff1f;参考&#xff1a;https://mp.weixin.qq.com/s/vwNf_sFlmhp7DeSYaQ3NxQ森林图是以统计指标和统计分析方法为基础&#xff0c;用数值运算结果绘制出的图形。它在平面直角坐标系中&#x…

vscode 打开项目时候,有部分外部依赖包找不到定义或者声明,但是能使用cmake正常编译并且运行

解决&#xff1a;是依赖路径的问题&#xff0c;先看includePath对不对&#xff0c;但是有时候会依赖外部文件&#xff0c;这时候入股cmake编译能够听过&#xff0c; 说明编译器能够找到依赖路径&#xff0c; 但是vscode的 IntelliSense 找不到依赖路径 → 导致编辑器提示错误、…

nginx:SSL_CTX_use_PrivateKey failed

SSL_CTX_use_PrivateKey("/home/nginx-vue/cret/*.com.key") failed (SSL: error:0B080074:x509 certificate routines:x509_check_private_key:key values mismatch) Nginx 尝试加载私钥文件时失败&#xff0c;原因是&#xff1a;证书与私钥不匹配 问题本质 SSL 证…

Docker 基于 Cgroups 实现资源限制详解【实战+源码】

本文将带你深入理解 Docker 如何借助 Linux Cgroups 实现对内存、CPU 等系统资源的精细化控制&#xff0c;并提供完整演示与图解、Compose 配置模板和资源包下载&#xff0c;适合初学者与工程师深入学习与实战。 文章目录 一、什么是 Cgroups&#xff1f;为什么对容器如此关键…

Linux中的系统日志(Rsyslog)

一、实验环境主机名系统网络适配器IP地址serverarhel9NAT模式172.25.254.11/24serverbrhel9NAT模式172.25.254.22/24二、Rsyslog的基本参数&#xff08;1&#xff09;安装rsyslog&#xff08;2&#xff09;rsyslog的服务名称&#xff08;3&#xff09;rsyslog的主配置文件rsysl…

Spring Boot + Thymeleaf + RESTful API 前后端整合完整示例

关键词&#xff1a;Spring Boot、Thymeleaf、RESTful API、前后端整合、用户管理 ✅ 功能概述 本文将为你提供一个完整的 Spring Boot Thymeleaf RESTful API 的前后端整合项目&#xff0c;实现以下功能&#xff1a; 模块功能用户管理查看用户列表、新增用户、删除用户后端…

从零开始的MySQL学习

MySQL 从零开始的MySQL学习 第一节 数据库 重点&#xff1a;数据库通过SQL等标准语言进行动作&#xff0c;数据库的概念、分类&#xff0c;数据管理系统&#xff08;操纵和管理数据库的大型软件&#xff09; 数据库&#xff08;Database&#xff09; 是按照数据结构来组织、存储…

Docker 高级管理--Dockerfile镜像制作

二:Dockerfile 语法基础 1:基础指令 (1)FROM 指定基础镜像&#xff0c;所有的 Dockerfile 都必须以 FROM 指令开头&#xff0c;它定义了新镜像基于哪个基础镜像构建。 FRoM ubuntu:20.04 (2)MAINTAINER(已奔用&#xff0c;推荐使用LABEL) 用于指定镜像的维护者信息。不过在较…

LeetCode 692题解 | 前K个高频单词

前K个高频单词一、题目链接二、题目三、分析四、代码一、题目链接 692.前K个高频单词 二、题目 三、分析 本题目我们利用map统计出次数以后&#xff0c;返回的答案应该按单词出现频率由高到低排序&#xff0c;有一个特殊要求&#xff0c;如果不同的单词有相同出现频率&#…

C++ 中的 std::bind 用法

在现代 C++ 编程中,std::bind 是一个非常强大但常常被误解的工具。它允许我们将函数(包括成员函数)、参数进行绑定,并生成一个新的可调用对象。这在编写异步回调、事件处理、适配器模式等场景中非常有用。 🔧 一、std::bind 是什么? std::bind 是定义在 <functiona…