【weaviate】分布式數據寫入之LSM樹深度解析:讀寫放大的權衡

文章目錄

  • 一、LSM樹的設計哲學:寫優化的根本動機
    • 1、 傳統B+樹存儲的性能瓶頸
    • 2、 LSM樹的根本性創新
  • 二、寫入路徑的深度技術分析
    • 1、 WAL機制的精密設計
    • 2、 MemTable的數據結構
    • 3、 刷盤(Flush)過程的技術細節
  • 三、Compaction策略:LSM樹性能優化的核心機制
    • 1、為什么LSM樹必須要Compaction?LSM樹設計帶來的必然問題
    • 2、Compaction理論
      • 2.1、Compaction概念
      • 2.2、寫放大的產生機制
      • 2.3、分層架構的設計智慧
    • 3、Size-Tiered與Leveled:兩種哲學的對比
      • 3.1 Size-Tiered的簡潔哲學
      • 3.2 策略選擇的智慧
    • 4、Compaction的本質與價值
  • 四、 LSM樹讀取路徑:從簡單寫入到復雜查詢
    • 1. 為什么LSM樹的讀取比寫入復雜?
    • 2. Bloom Filter:LSM樹讀取優化的核心武器
  • 五、LSM樹性能特性:三個核心權衡
    • 1、寫放大、讀放大、空間放大的本質
    • 2、不同存儲介質的性能影響
  • 六、LSM樹的工程實踐:監控與恢復的核心機制
    • 1、為什么LSM樹需要特殊的監控策略?
    • 2、WAL:LSM樹可靠性的保險機制

LSM樹(Log-Structured Merge Tree)作為現代分布式數據庫的核心存儲引擎,其設計哲學體現了對寫入密集型工作負載的深度優化。從Cassandra到RocksDB,從HBase到TiKV,LSM樹已成為大規模分布式系統的標準選擇。本文將深入剖析LSM樹的技術內核,探討其設計權衡與工程實踐。

一、LSM樹的設計哲學:寫優化的根本動機

1、 傳統B+樹存儲的性能瓶頸

傳統的B+樹存儲結構在寫入密集型場景下面臨根本性挑戰。B+樹的 就地更新(In-Place Update) 特性要求寫入操作直接修改磁盤上的數據頁,這導致了幾個嚴重問題:

  1. 隨機I/O的性能陷阱:
    B+樹的寫入往往涉及隨機磁盤訪問。當插入新數據時,需要找到對應的葉子節點,可能觸發節點分裂,進而影響父節點。這些操作在磁盤上通常是不連續的,導致大量隨機I/O
    機械硬盤的隨機I/O性能通常只有100-200 IOPS,而順序I/O可以達到100MB/s以上。即使在SSD上,隨機I/O的性能也遠低于順序I/O。這種性能差異在高并發寫入場景下被放大,成為系統瓶頸。

  2. 寫放大問題的累積效應:
    B+樹的修改經常需要 重寫整個數據頁,即使只修改其中的一條記錄 。更嚴重的是,如果修改導致頁分裂,可能需要更新多個頁面。這種**寫放大(Write Amplification)**現象在SSD上尤其有害,會顯著降低SSD的使用壽命。

  3. 并發控制的復雜性:
    就地更新要求復雜的鎖機制來保證并發安全。多個寫入操作可能需要鎖定相同的頁面,導致鎖競爭和等待。這種競爭在高并發場景下會嚴重影響系統吞吐量。

?

2、 LSM樹的根本性創新

LSM樹通過追加寫入(Append-Only) 的設計哲學從根本上解決了上述問題:

  1. 順序I/O的性能優勢:
    所有寫入操作都轉換為順序追加,無論是WAL的寫入還是SSTable的生成,都充分利用了磁盤的順序I/O性能。這種設計使得LSM樹在機械硬盤上也能獲得優異的寫入性能。

  2. 寫放大的控制:
    雖然LSM樹在Compaction過程中也存在寫放大,但這種放大是可控制和可預測的。通過調整Compaction策略,可以在寫放大和讀性能之間找到最佳平衡點。

  3. 無鎖并發的簡化:
    追加寫入的特性使得LSM樹可以采用更簡單的并發控制機制。內存中的MemTable可以使用高效的無鎖數據結構,磁盤上的SSTable是不可變的,天然支持并發讀取。

?

二、寫入路徑的深度技術分析

1、 WAL機制的精密設計

WAL(Write-Ahead Log)不僅僅是簡單的日志文件,其設計涉及多個精密的技術考量:

a. 日志格式的優化:

WAL的日志格式需要在空間效率和解析速度之間平衡。典型的WAL記錄包含:記錄類型、時間戳、鍵值對、校驗和等信息。通過緊湊的二進制格式和高效的編碼算法,可以最小化WAL的存儲開銷。

?

b. 批量寫入的聚合策略:

單條記錄的WAL寫入效率很低,因為每次寫入都需要系統調用。現代LSM實現通常采用批量寫入聚合策略:將多個寫入操作的WAL記錄合并到一個批次中,減少系統調用次數。

但批量大小的選擇需要權衡:更大的批量可以提高吞吐量,但會增加延遲和內存使用。通常采用動態調整策略,根據當前的寫入負載自動調整批量大小

?

c. 同步策略的選擇:

WAL的持久化同步策略直接影響性能和可靠性:

  • 每次同步(sync on every write):最高可靠性,但性能較低
  • 定時同步(periodic sync):在可靠性和性能之間平衡
  • 異步同步(async sync):最高性能,但存在數據丟失風險

大多數系統提供可配置的同步策略,允許用戶根據業務需求選擇。

?

d. 日志回收的復雜性:

WAL文件會隨著寫入不斷增長,需要及時回收以避免磁盤空間耗盡。但日志回收必須確保安全性:只有當對應的MemTable已經成功刷盤后,才能刪除相應的WAL段。

這需要精確的元數據管理來跟蹤每個WAL段對應的MemTable狀態。在系統故障恢復時,需要確保所有未刷盤的WAL段都能被正確replay。

?

2、 MemTable的數據結構

MemTable是LSM樹的內存寫入緩沖區,將隨機寫入轉換為有序存儲,然后批量刷盤。

寫入流程

階段狀態作用
Active可寫接收新寫入,支持查詢
Immutable只讀停止寫入,準備刷盤
Flushed回收數據已寫入磁盤,釋放內存

數據結構選擇:跳表。為什么選擇跳表?

  • 并發友好:支持無鎖操作,避免鎖競爭
  • 有序性:天然維護鍵值有序,便于刷盤和范圍查詢
  • 實現簡單:相比紅黑樹等復雜結構,更容易實現和調試

優缺點分析

優勢說明
高寫入性能內存操作,延遲極低
有序存儲為后續磁盤寫入提供有序數據
并發友好支持高并發讀寫操作
劣勢說明
內存限制受內存大小約束,需及時刷盤
數據丟失風險系統崩潰時內存數據丟失(需WAL保護)
查詢復雜性讀取時需同時查詢多個MemTable

核心價值:通過內存緩沖將隨機寫入轉換為順序寫入,是LSM樹高寫入性能的關鍵組件。

?

3、 刷盤(Flush)過程的技術細節

從MemTable到SSTable的刷盤過程看似簡單,實際上涉及復雜的技術考量:

刷盤時機的精確控制:

刷盤時機的選擇需要綜合考慮多個因素:

  • 內存壓力:MemTable占用內存過多時需要及時刷盤
  • WAL大小:WAL文件過大會影響恢復時間
  • 查詢性能:過多的SSTable文件會影響讀取性能
  • 系統負載:在低負載時進行刷盤可以減少對前臺操作的影響

?

刷盤過程的原子性保證:

刷盤過程必須保證原子性:要么完全成功,要么完全失敗。這通常通過以下步驟實現:

  1. 先寫入臨時文件
  2. 寫入完成后原子性地重命名文件
  3. 更新元數據
  4. 刪除對應的WAL段

如果任何步驟失敗,都可以安全地重試或回滾。

?

壓縮和編碼的應用:

SSTable文件通常會應用壓縮算法來減少存儲空間。常用的壓縮算法包括Snappy、LZ4、ZSTD等。壓縮算法的選擇需要在壓縮率和CPU開銷之間平衡。

除了通用壓縮算法,還可以應用專門的編碼技術,如Delta編碼(存儲鍵之間的差值而不是完整鍵)、前綴壓縮(對具有相同前綴的鍵進行壓縮)等。

?

三、Compaction策略:LSM樹性能優化的核心機制

1、為什么LSM樹必須要Compaction?LSM樹設計帶來的必然問題

LSM樹通過"先寫內存、再刷磁盤"的設計實現了出色的寫入性能,但這種設計方式不可避免地引發了一系列問題。隨著系統持續運行,磁盤上會不斷積累大量小而分散的SSTable文件,這些文件的存在直接威脅到系統的長期性能。

  1. 讀取性能的逐步惡化是最直觀的問題。每次MemTable刷盤都會在磁盤上產生一個新的SSTable文件,而查詢操作需要在這些不斷增加的文件中逐一搜索目標數據。想象一下,如果系統運行一年后磁盤上有上千個SSTable文件,那么每次查詢都可能變成一場"大海撈針"的過程。

  2. 存儲空間的持續膨脹則是另一個嚴重問題。在LSM樹中,刪除操作并不會立即清除數據,而是簡單地寫入一個刪除標記(Tombstone)。同時,對同一個key的多次更新會在不同的文件中產生多個版本。如果沒有適當的清理機制,這些"垃圾數據"會讓磁盤空間不斷膨脹,最終可能消耗數倍于實際有效數據的存儲空間。

  3. 系統緩存效率的下降也隨之而來。當數據分散在大量小文件中時,操作系統的頁緩存很難發揮作用,因為熱數據和冷數據混雜在一起,緩存命中率會顯著降低。

?

2、Compaction理論

2.1、Compaction概念

Compaction就是LSM樹的"數據整理員",它的工作是定期將磁盤上散亂的小文件合并成更大、更有序的文件

(這里就涉及到了寫放大,比如100M的數據觸發了Compaction,此時有500M的文件需要合并,這就是5倍寫放大:由100M的數據觸發了500M的Compaction)

基本工作流程:

  1. 選擇多個需要合并的SSTable文件
  2. 讀取這些文件中的所有數據
  3. 進行排序合并,清理重復數據和刪除標記
  4. 寫出新的合并文件,刪除舊文件

?

2.2、寫放大的產生機制

寫放大的本質:數據被重復寫入磁盤。

舉個具體例子:

用戶寫入100MB新數據(產生新的SSTable文件)。觸發Compaction時,系統發現需要與4個舊文件(共400MB)合并,所以在Compaction過程中會:讀取500MB數據 → 排序合并 → 寫入500MB新文件。這里就涉及到了寫放大: 寫放大 = 實際寫入(500MB) / 用戶寫入(100MB) = 5倍

為什么必須重寫舊數據? 因為SSTable文件是不可變的,要實現全局有序和數據清理,只能通過重新生成文件來完成。就像重新整理書架,必須把所有書都重新擺放一遍。

?

2.3、分層架構的設計智慧

Leveled Compaction將數據組織成金字塔結構:

  • Level 0:10個文件(直接來自MemTable,允許重疊)
  • Level 1:100MB(文件間不重疊)
  • Level 2:1GB(每層容量10倍增長)
  • Level 3:10GB
  • 依此類推…

分層架構決定了當數據達到每層的限制后,會觸發Compaction操作,控制了寫放大(被整理的數據不會也來越大),也保證了數據的定期整理。如下是具體分析:

  1. 分層的核心價值:控制寫放大。 由于每層容量呈指數增長,任何一條數據在整個生命周期中最多只會被重寫log(N)次。比如100GB的數據庫,單條數據最多重寫4-5次,而不是無限次。

  2. Layer 0的特殊性: Level 0允許文件重疊是因為它們直接來自MemTable刷盤,反映的是寫入時間順序。從Level 1開始,所有層級都嚴格保持文件間無重疊,這樣查詢時每層最多只需檢查一個文件。

  3. 分層合并策略: 當某層容量超限時,選擇其中一個文件與下一層合并。這種"逐級下沉"的方式既保證了數據的定期整理,又將Compaction的開銷分散到時間軸上,避免了突發的性能沖擊。

  4. 核心權衡: Compaction通過增加寫入成本(寫放大)來換取讀取性能和存儲效率的提升。分層架構則巧妙地將這種成本控制在可預測的范圍內,這正是LSM樹設計的精髓所在。

?

3、Size-Tiered與Leveled:兩種哲學的對比

3.1 Size-Tiered的簡潔哲學

與Leveled Compaction的復雜精巧相比,Size-Tiered Compaction體現了另一種設計哲學:簡潔而直接。它的策略很簡單——將大小相似的文件合并在一起,形成更大的文件,如此反復,最終形成金字塔式的大小分布。

這種策略的最大優勢是寫入友好。由于每個數據項被重寫的次數相對較少,系統可以維持很高的寫入吞吐量。對于那些以寫入為主、讀取相對較少的應用場景,Size-Tiered策略往往是更好的選擇。

3.2 策略選擇的智慧

然而,Size-Tiered策略也有其代價:讀取性能相對較差,因為查詢時可能需要檢查多個大文件;空間回收效率也不如Leveled策略,刪除的數據需要更長時間才能被清理。

這就引出了一個重要的工程問題:如何根據具體的應用場景選擇合適的策略?

對于日志收集、監控指標等寫密集型場景,Size-Tiered策略的高寫入性能和低寫放大特性使其成為理想選擇。而對于用戶數據、交易記錄等需要頻繁查詢的場景,Leveled策略的優秀讀取性能和空間效率則更有優勢。

?

4、Compaction的本質與價值

從更深層的角度來看,Compaction策略的選擇實際上反映了系統設計中一個永恒的主題:如何在相互沖突的需求之間找到最佳平衡點

LSM樹通過Compaction機制,將寫入時的簡單快速和讀取時的復雜優化分離開來,這種"延遲優化"的思想在很多系統設計中都有體現。它告訴我們,并不是所有的性能優化都需要在第一時間完成,有時候將復雜性延后處理反而能獲得更好的整體效果。

無論選擇哪種Compaction策略,核心都在于深入理解應用的特點和需求。沒有完美的策略,只有最適合的選擇。這正是LSM樹設計哲學的精髓所在:通過靈活的策略配置,讓同一套基礎架構適應不同的應用場景,這種適應性正是現代分布式系統成功的關鍵因素之一。

?

四、 LSM樹讀取路徑:從簡單寫入到復雜查詢

1. 為什么LSM樹的讀取比寫入復雜?

寫入很簡單: 數據只需要寫入一個地方——當前的MemTable,速度極快。

讀取很復雜: 由于LSM樹的設計特點,一個key的最新數據可能存在于多個地方,查詢時必須按優先級搜索所有可能的位置:

  1. MemTable(最新數據)
  2. Immutable MemTable(準備刷盤的數據)
  3. Level 0 SSTable文件(最近刷盤的數據)
  4. Level 1, 2, 3…文件(較老的數據)

核心問題: 查詢一個key,最壞情況下可能需要檢查幾十個甚至上百個文件!這就是所謂的"讀放大"問題。

為什么不能像B+樹那樣直接定位? 因為LSM樹為了優化寫入性能,將數據分散存儲在多個時間層次中,犧牲了讀取的直接性。

?

2. Bloom Filter:LSM樹讀取優化的核心武器

問題的嚴重性: 如果每次查詢都要打開幾十個文件進行搜索,性能會極其糟糕。

Bloom Filter的解決思路: 在不實際打開文件的情況下,快速判斷"這個key絕對不在這個文件中"。

工作原理簡單說明:

  • 每個SSTable文件都配備一個Bloom Filter(一個小的內存數據結構)
  • 查詢時先問Bloom Filter:“key X可能在這個文件里嗎?”
  • 如果答案是"絕對不在",直接跳過這個文件;如果答案是"可能在",才實際打開文件搜索

效果: 通過Bloom Filter,大部分文件可以被快速排除,實際需要打開的文件數量從幾十個降低到幾個。

關鍵參數權衡: Bloom Filter的假陽性率越低(誤判率越低),需要的內存越多。典型配置是1%的假陽性率,這意味著100次查詢中可能有1次會誤判需要打開不必要的文件,但這個代價是可以接受的。

核心價值: Bloom Filter將LSM樹的讀取復雜度從"必須搜索N個文件"優化為"大概率只需搜索1-2個文件",這是LSM樹能夠在讀寫混合負載下保持合理性能的關鍵技術。

?

五、LSM樹性能特性:三個核心權衡

1、寫放大、讀放大、空間放大的本質

LSM樹的性能特性可以歸結為三個核心權衡,這些權衡決定了LSM樹適用的場景和優化方向。

寫放大:為了長期性能犧牲短期成本

寫放大的本質是"數據被重復寫入"。想象一下整理房間:你不能只把新物品放進去,還要定期重新整理所有物品來保持房間的有序性。LSM樹也是如此——Compaction過程會重新寫入已存在的數據來維持整體結構。

典型的Leveled Compaction寫放大在10-30倍之間。這看起來很高,但關鍵在于它是攤銷的:不是每次寫入都有30倍開銷,而是在長期運行中平均每字節數據會被寫入10-30次。單次寫入依然很快,只是后臺會有持續的整理成本。

?

讀放大:分散存儲帶來的查詢復雜性

讀放大源于LSM樹的核心設計:數據分散在多個文件中。最壞情況下,一次查詢可能需要檢查1個MemTable + 1個Immutable MemTable + 10個Level 0文件 + 每層1個文件。如果有6層,就是18個數據源。

Bloom Filter是解決這個問題的關鍵武器。它就像圖書館的索引卡片,告訴你"這本書絕對不在這個書架上",讓你避免無謂的搜索。通過Bloom Filter,實際需要搜索的文件數量從十幾個降低到1-2個。

?
空間放大:延遲清理的代價

空間放大主要來自兩個原因:刪除標記(Tombstone)和版本重疊。刪除操作不會立即釋放空間,而是寫入刪除標記;同一個key的多個版本可能同時存在于不同文件中。只有通過Compaction才能真正清理這些"垃圾數據"。

典型的空間放大在1.1-2倍之間,這意味著存儲1GB有效數據可能需要1.1-2GB的磁盤空間。

?

2、不同存儲介質的性能影響

機械硬盤:LSM樹的天然優勢

LSM樹在機械硬盤上表現出色,因為它將隨機I/O轉換為順序I/O。機械硬盤的隨機I/O性能只有100-200 IOPS,但順序I/O可以達到100MB/s以上。LSM樹的順序寫入特性完美契合了機械硬盤的性能特點。

在機械硬盤上,讀取性能本身就受限于尋道時間,所以可以采用更激進的Size-Tiered Compaction策略,用更高的讀放大換取更低的寫放大,因為讀取瓶頸主要在磁盤尋道而不是文件數量。

?

SSD:新的挑戰與機遇

SSD改變了LSM樹的性能平衡。SSD的隨機I/O性能大幅提升,但引入了新的考慮因素:寫入壽命限制。SSD的每個存儲單元只能承受有限次數的寫入,LSM樹的寫放大會加速SSD的磨損。

但SSD也帶來了新的優化機會:高度并行的I/O能力。現代SSD可以同時處理多個I/O請求,LSM樹可以通過并發Compaction、并行讀取等方式充分利用這種并行性,獲得比機械硬盤更好的整體性能。

核心啟示:LSM樹的性能特性不是固定的,而是與底層存儲介質密切相關。理解這些權衡關系是優化LSM樹性能的關鍵。在機械硬盤上優化寫入,在SSD上平衡寫入壽命與性能,在NVMe上充分利用超高IOPS——不同的存儲介質需要不同的優化策略。

?

六、LSM樹的工程實踐:監控與恢復的核心機制

1、為什么LSM樹需要特殊的監控策略?

傳統數據庫的監控相對簡單,因為數據結構穩定,性能瓶頸容易定位。但LSM樹的性能是動態變化的——Compaction的進行會影響讀寫性能,緩存的命中率會隨數據分布變化,這種動態性要求更精密的監控策略。

最關鍵的三個監控指標:

寫放大系數 是LSM樹健康狀況的核心指標。正常情況下應該在10-30倍之間,如果突然飆升到50倍以上,通常意味著Compaction跟不上寫入速度,系統正在"積壓工作"。這就像工廠的生產線——如果裝配速度跟不上零件供應,庫存就會堆積。

Compaction隊列長度 反映了系統的"消化能力"。隊列長度持續增長表明后臺整理工作已經超負荷,這會逐步影響讀取性能。正常情況下隊列應該保持在較低水平,偶爾的峰值是正常的,但持續的高隊列長度需要調整Compaction策略。

緩存命中率 直接決定了讀取性能。LSM樹對緩存的依賴比B+樹更強,因為數據分散在多個文件中。如果緩存命中率從95%下降到85%,讀取延遲可能增加數倍。這就像圖書館的常用書架——如果經常找的書不在手邊,每次都要跑到倉庫去取。

?

性能問題的簡單診斷邏輯:

  • 寫入變慢?檢查Compaction隊列是否積壓
  • 讀取變慢?檢查緩存命中率和文件數量
  • 空間暴增?檢查刪除數據的清理頻率

?

2、WAL:LSM樹可靠性的保險機制

LSM樹的數據首先寫入內存(MemTable),在刷盤之前數據是易失的。WAL(Write-Ahead Log)就是這種設計的"保險絲"——確保即使系統崩潰,也能恢復所有已確認的寫入操作。

WAL的工作原理很簡單: 每次寫入數據前,先將操作記錄寫入磁盤上的日志文件。這個日志記錄包含了重建數據所需的所有信息:key、value、操作類型、時間戳等。由于WAL是順序寫入,速度很快,不會成為性能瓶頸。

崩潰恢復的過程: 系統重啟時,會讀取WAL文件,按順序重放所有操作,重建內存中的MemTable狀態。這個過程就像重放錄像帶——按照時間順序重新執行所有操作,最終達到崩潰前的狀態。

WAL的生命周期管理: WAL文件不能無限增長,當對應的MemTable成功刷盤后,相關的WAL段就可以刪除了。這需要精確的元數據管理來跟蹤哪些WAL段還有用,哪些可以安全刪除。

為什么WAL機制對LSM樹特別重要? 因為LSM樹的設計將寫入操作分成了兩個階段:快速寫入內存和延遲寫入磁盤。WAL填補了這兩個階段之間的可靠性空隙,確保"寫入成功"的承諾能夠兌現。

核心價值: 通過精確的監控和可靠的恢復機制,LSM樹在保持高性能的同時確保了數據的安全性。這種監控-恢復體系是LSM樹在生產環境中穩定運行的基礎保障。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/910443.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/910443.shtml
英文地址,請注明出處:http://en.pswp.cn/news/910443.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Pygame 大魚吃小魚

【Pygame 大魚吃小魚】是一款基于Python編程語言和Pygame庫開發的趣味游戲。Pygame是Python中一個廣泛用于開發2D游戲的開源模塊集合,它提供了豐富的功能,如窗口管理器、事件處理、圖形繪制等,使得初學者也能快速上手創建游戲。 這段 Python …

【為什么在觸發的事件中修改控件屬性需要使用`Invoke`】

在C#中,特別是在使用Windows Forms或WPF等GUI框架時,控件的屬性和狀態通常只能在創建它們的線程(即UI線程,即主線程或用戶界面線程)中直接修改。這是由于這些框架的設計基于單線程模型,其中所有與用戶界面&…

Android 當apk是系統應用時,無法使用webView的解決方案

最近在做項目時,遇到了一個無法使用webView的問題,apk是系統應用,點擊加載webView時應用就是崩潰,原因是系統應用時,Android會覺得webView不安全,不避讓加載。 解決的思路就是使用映射,把原生的…

ArcGIS Pro無插件加載(無偏移)天地圖!一次添加長久使用

以前我們介紹過:ArcGIS無插件加載(無偏移)天地圖。這次我們來介紹ArcGIS Pro中如何添加天地圖。 我們將通過從天地圖官網自己添加服務鏈接并添加至收藏的方式以及應急的方法來做本次的介紹。天地圖的數據主要包括影像、電子地圖、地形圖等。我…

Go堆內存管理

# Go堆內存管理 1. Go內存模型層級結構 Golang內存管理模型與TCMalloc的設計極其相似。基本輪廓和概念也幾乎相同,只是一些規則和流程存在差異。 2. Go內存管理的基本概念 Go內存管理的許多概念在TCMalloc中已經有了,含義是相同的,只是名字…

零售 EDI:Chewy EDI 項目注意事項

在此前的文章《供應商對接Chewy的EDI需求》中,介紹了Chewy的EDI需求,本文主要為大家分享Chewy對于各個業務單據的細節性需求,了解這些細節性注意事項將幫助企業快速基于知行軟件提供的EDI服務與Chewy建立EDI對接。 基于知行之橋EDI系統能夠通…

Android錄制視頻自帶鋪滿多行水印

文章目錄 引言環境要求代碼實現總結 引言 之前做過幾種水印需求,這篇文章是關于使用Android原生庫開發錄制視頻自帶滿幀文字水印。 環境要求 Android 7.0以上Android Studio ,官方開發者官網視頻錄制功能參考開源庫PictureSelector的camerax庫 //用到的…

觀遠ChatBI:加速零售消費企業數據驅動的敏捷決策

近年來,隨著國產大模型(如DeepSeek)的快速發展,企業對智能化數據分析工具的需求日益增長。觀遠數據推出的ChatBI,基于大語言模型(LLM)打造,旨在通過自然語言交互降低數據分析門檻&am…

鴻蒙NEXT-鴻蒙三層架構搭建,嵌入HMRouter,實現便捷跳轉,新手攻略。(1/3)

接下來,我將手把手帶領大家去完善,搭建一個鴻蒙的三層架構,另實現HMRouter的嵌入。完成后,大家可任意跳轉頁面,在三層架構中,書寫屬于自己的篇章。 第0步,項目與AGC華為控制臺關聯起來 首先AG…

鴻蒙ArkTs仿網易云音樂項目:架構剖析與功能展示

鴻蒙ArkTs仿網易云音樂項目:架構剖析與功能展示 一、引言 在移動應用開發的浪潮中,音樂類應用始終占據著重要的一席之地。網易云音樂憑借其豐富的音樂資源、個性化的推薦算法和獨特的社交互動功能,深受廣大用戶的喜愛。本文將詳細介紹一個基…

【web 安全】從 HTTP 無狀態到現代身份驗證機制

文章目錄 Web 安全與系統設計Web存在的問題:Web 是無狀態的解決方案一、早期解決方案:Session Cookie 的誕生二、第二階段:Token 的出現(前后端分離 移動端的解決方案)三、分析總結:1.早期版本&#xff1…

FlutterUnit TolyUI | 布局游樂場

FlutterUnit 基于 TolyUI 大大簡化了界面構建的代碼復雜程度,因此之前想要實現的一些小功能,就可以輕松支持。布局游樂場是通過交互的方式來 直觀體驗 組件的布局特性,從而更易學和掌握。目前 FlutterUnit 已在 知識集錄模塊新增了 布局寶庫&…

【數據分析一:Data Collection】信息檢索

本節內容含有各典型數據集的推薦,以及其網址,大家根據需要自取 一、檢索 最簡單、最靈活的數據獲取方式就是依靠檢索: Google:更適合搜索英文信息 Google Dataset Search(Google 數據集搜索) 網址&…

23.ssr和csr的對比?如何依賴node.js實現

1.為什么說ssr 的node中間層請求速度快。相當于內網? 那vue.js加載怎么沒有ssr和csr的說法啊 第一問:為什么說 SSR 的 Node 中間層請求速度快?是不是相當于內網? ? 是的,本質上就是「內網請求」,所以更快…

力扣刷題(第六十四天)

靈感來源 - 保持更新,努力學習 - python腳本學習 第一個錯誤的版本 解題思路 初始化左右邊界:左邊界 left 1,右邊界 right n。二分查找循環: 計算中間版本號 mid。若 mid 是錯誤版本,說明第一個錯誤版本在 [le…

【圖像處理入門】11. 深度學習初探:從CNN到GAN的視覺智能之旅

摘要 深度學習為圖像處理注入了革命性動力。本文將系統講解卷積神經網絡(CNN)的核心原理,通過PyTorch實現圖像分類實戰;深入解析遷移學習的高效應用策略,利用預訓練模型提升自定義任務性能;最后揭開生成對抗網絡(GAN)的神秘面紗,展示圖像生成與增強的前沿技術。結合代…

C++法則4: 如果一個構造函數的第一個參數是自身類類型的引用,且任何額外參數都有默認值,則此構造函數是拷貝構造函數。

C法則4: 如果一個構造函數的第一個參數是自身類類型的引用,且任何額外參數都有默認值,則此構造函數是拷貝構造函數。 拷貝構造函數的定義: 第一個參數是自身類類型的引用: 必須是引用(通常為const引用&…

從頭搭建環境安裝k8s遇到的問題

基本信息 master節點IP: 172.31.0.3 node01節點IP:172.31.0.4 node02節點IP:172.31.0.5 子網掩碼:255.255.0.0 網關:172.31.0.2 DNS:114.114.114.114 安裝前要檢查的信息 檢查三臺主機的mac地址是否重復&#xff1a…

Flask入門指南:從零構建Python微服務

1. Flask 是什么? Flask 是一個 微框架(Microframework),特點包括: 輕量靈活:核心僅包含路由和模板引擎,其他功能通過擴展實現易于學習:代碼直觀,適合快速開發小型應用…

【LINUX網絡】網絡socet接口的基本使用以及實現簡易UDP通信

根據本系列上兩篇關于網絡的初識介紹,現在我們開始實現一個UDP接口,以加強對該接口的理解。 1 . 服務器端 在本篇中,主要按照下面內容來實現: 創建并封裝服務端:了解創建服務端的基本步驟 創建并封裝客戶端&#xff0…