Spark集群優化配置指南

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…