GaussDB技術解讀丨高級壓縮

来源:https://www.cnblogs.com/huaweiyun/archive/2023/07/19/17565571.html
-Advertisement-
Play Games

對於GaussDB來說,在今天引入數據壓縮,究竟能夠給客戶帶來什麼不一樣的價值,是過去一段時間我們一直在思考的問題。 ...


本文作者|華為雲資料庫GaussDB首席架構師 馮柯

【背景介紹】

數據壓縮與關係資料庫的結合,早已不是一個新鮮的話題,當前我們已經看到了各種各樣資料庫壓縮的產品和解決方案。對於GaussDB來說,在今天引入數據壓縮,究竟能夠給客戶帶來什麼不一樣的價值,是過去一段時間我們一直在思考的問題。

為了回答這個問題,我們首先對各種通用壓縮演算法進行了廣泛的測試,從性能最好的LZ4/Snappy,到性能與壓縮率均衡的Zstd/Zlib,再到強調壓縮率的LZMA/BZip。我們發現:即使是性能最好的壓縮演算法,仍然無法做到對一個線上資料庫的性能不產生顯著影響。我們也調研了資料庫領域的各種編碼方法,包括近幾年學術界發佈的一些基於預測和線性擬合的編碼方法,從研究發佈的測試結果及實測來看,資料庫編碼用於解決特定數值分佈的可壓縮性問題,與壓縮演算法的成熟度相比,當前並沒有一種通用的資料庫編碼方法,能夠在大多數真實數據集中的場景下提供穩定的壓縮率。

這是我們對於資料庫壓縮這個領域的一個基本技術判斷。過去的產品實踐也驗證了這一點,我們看到很多商業資料庫和開源資料庫都提供了對於壓縮的支持,絕大多數時候,留給客戶的選擇就是決定要不要在特定的表上開啟壓縮。開啟壓縮意味著空間節省,但同時意味著性能下降,這個看似簡單的選擇恰恰是客戶最難做的。這也是為什麼有了這麼多資料庫壓縮的產品,我們卻很少能看到數據壓縮真正廣泛應用在資料庫線上業務中的根本原因。

這給了我們更多的啟示。我們相信,真正可被應用的資料庫壓縮技術,能夠去兼顧壓縮率與業務影響的平衡,應該是選擇性的。即我們能夠基於技術去判定數據的溫度,並基於這樣的判定,去選擇性地壓縮業務中相對較冷的數據,而不去碰那些相對較熱的數據。

這樣的技術選擇意味著我們無法去滿足所有業務場景,我們要求業務的數據溫度分佈,必須滿足80-20分佈規則。即我們去壓縮那些占用80%存儲需求、但只占用20%計算需求的冷數據,而不去碰那些只占用20%存儲需求、但卻占用80%計算需求的熱數據。幸運的是,我們發現絕大多數對於容量控制有需求的業務,都具備這樣的特征。

【場景及目標選擇】

通過對大量業務場景的分析,我們發現業務對於資料庫壓縮技術的需求是多元化的,有線上交易業務(OLTP)存儲壓縮的場景,有分析業務(OLAP)存儲壓縮的場景,有歷史業務存儲壓縮的場景,也有容災業務傳輸壓縮的場景。不同的場景,對於壓縮技術的訴求,如果從壓縮性能、壓縮率、解壓性能的三維指標去看,從對業務侵入的容忍度去看,是完全不同的。

這意味著如果我們想要打造一個全場景的GaussDB高級壓縮特性,它應該是多個技術的組合,包括不同的壓縮演算法、不同的冷熱判定模型及方法、不同的數據存儲組織等,通過不同的技術組合及應用去滿足不同的場景需求。

這同時意味著我們在不同壓縮適用場景的支持上需要有個優先順序的取捨。我們的答案是選擇去優先支持OLTP存儲壓縮場景,這是我們認為資料庫壓縮技術最有價值的業務領域,當然也是技術挑戰最大的領域。

確定場景之後,接下來是確定技術目標,我們面向這個場景,究竟要打造什麼樣的核心競爭力,這取決於我們對於典型客戶場景的分析。我們識別了兩類典型客戶場景:

場景A:客戶業務來自於IBM小機,單庫容量50TB,遷移到開放平臺後,面臨容量過大和運維視窗過長問題。選擇拆庫意味著分散式改造,對於一個已經穩定運行許多年的存量關鍵業務來說,這種技術選擇風險過高。選擇壓縮可以顯著降低容量風險,但業務最初的設計並沒有考慮冷熱分離(比如基於時間維度建立分區),需要一種零侵入的壓縮技術支持,同時對業務性能影響足夠低。

場景B:客戶業務基於分散式集群部署,單集群容量已經超過1PB,並且仍在快速增長,需要定期擴容。選擇壓縮可以降低擴容頻率,顯著降低業務的軟硬體成本,並減少變更風險。但業務的數據分佈設計是面向擴展性的(比如基於用戶維度建立分區),沒有考慮冷熱分離,因此同樣的,業務需要一種零侵入的壓縮技術支持,同時對性能影響足夠低。

通過對客戶典型場景的需求梳理,我們確定了GaussDB OLTP存儲壓縮的基本設計目標:1)冷熱判定對業務應該是零侵入的,不應對業務的已有數據分佈、邏輯模型有任何依賴;2)對業務影響必須足夠低,我們定義目標低於10%,並挑戰5%;3)提供合理的壓縮率,我們定義目標不低於2:1。基本設計目標的定義,使得我們能夠將後續每個具體場景中的技術選擇都變成一個確定性問題。

【冷熱判定】

確定設計目標後,我們開始進行工程落地。有三個問題需要解決:1)如何實現對數據的冷熱判定;2)如何實現壓縮後數據的存儲組織;3)如何實現有競爭力的壓縮演算法。

對於冷熱判定,首先要確定判定的粒度。數據的冷熱判定可以基於不同粒度實現,行級、塊級或表/分區級,粒度越粗,實現的複雜度越低,但對業務的侵入也越大。基於設計目標,很自然的,我們選擇行級的冷熱判定,這是對業務數據分佈依賴最小的方案,我們需要解決的,是如何控制引入冷熱判定的代價。

我們利用GaussDB存儲引擎已有的機制巧妙地解決了這一問題。具體來說,GaussDB存儲引擎在每行數據的元數據Meta中記錄了最近一次修改該行的事務ID(XID),該信息被用來支持事務的可見性判定,從而實現多版本併發控制(MVCC)。對於特定行來說,如果其XID足夠“老”,老到它對所有當前已經活躍的事務都可見,那麼這時候我們實際上已經不關註XID的具體值,我們可以通過引入一個特定的標誌位(FLG)來記錄這一點,而原來XID中填充的值可以被一個物理時間來代替,這個物理時間就表徵了其所屬行最後一次修改時間的上限(LMT,Last Modified Time)。很顯然,LMT可以用來支持冷熱判定(具體見圖1):

cke_114.png

圖1:行級冷熱判定

上述方案的好處是引入LMT並沒有增加額外開銷,對業務的邏輯模型也沒有任何依賴,在大多數時候,如果不是特別嚴格要求,業務可以定義一個簡單的規則來實現冷熱判定,比如:

AFTER 3 MONTHS OF NO MODIFICATION

此時系統會掃描目標表,對於所有滿足當前時間減去LMT超過3個月的行進行壓縮。

註意在上述方案中,我們實際上只識別了行的寫熱點,但並沒有識別行的讀熱點,我們只知道滿足條件的行3個月內未發生任何更新,但我們無法確認這些行在3個月內是否被頻繁讀取。維護行的讀熱點,目前從技術上沒有低成本的解決方案。對於像訂單明細這樣的流水類業務,這個方案可以很好地工作,因為數據的讀和寫呈現出相同的溫度特征,其訪問頻率隨著未修改時間的增加不斷衰減。但對於像手機相冊這樣的收藏類業務,僅識別寫可能是不夠的,因為一個很早建立的收藏關係仍然可能被頻繁訪問。

這意味著,即使系統進行了冷熱判定,我們仍然需要去優化業務可能訪問壓縮數據的場景,我們把這個問題留給了存儲組織和壓縮演算法,對於壓縮演算法來說,我們更關註其解壓性能。

另一個問題是在某些場景下,使用預設的冷熱判定可能是不夠的,比如對於某些類型的交易而言,其產生的訂單明細可能在3個月內確實不會被修改,但會在達到一個特定的觸發條件後被更新(比如解凍擔保交易)。這種場景在實際業務中並不常見,但如果業務確實關註性能,那麼我們支持在預設的冷熱判定規則以外,允許業務自定義規則,比如:

AFTER 3 MONTHS OF NO MODIFICATION ON (order_status = "finished")

此時系統會僅壓縮3個月未修改、且訂單狀態已經完結的數據。

當前我們支持的自定義規則,是任意合法的行表達式,業務可以寫任意複雜的表達式來表徵數據的冷熱判定規則,但表達式中所引用的任何欄位,只能是目標表上的合法欄位。通過這種預設和自定義規則的組合使用,我們提供了業務足夠低的使用門檻和更好的靈活性。

【存儲組織】

當滿足冷熱判定條件的行被壓縮時,我們需要決定如何存儲這些壓縮後的數據,基於設計目標,我們選擇了對業務侵入最小的存儲組織實現——塊內壓縮。

我們知道關係資料庫的存儲組織都是基於固定長度的分塊的,在GaussDB資料庫中,典型的數據塊大小為8KB,選擇更大的數據塊顯然有利於壓縮,但對業務性能會造成更大的影響。所謂塊內壓縮,是指:1)單個塊內所有滿足冷熱判定條件的行,會作為一個整體進行壓縮;2)壓縮後形成的數據就存放在當前的數據塊中,存放區域稱為BCA(Block Compressed Area),它通常位於塊的尾部。

塊內壓縮的設計意味著解壓任何數據只依賴於當前塊,而不需要訪問其它的數據塊,從壓縮率的視角看,這樣的設計並不是最友好的,但它非常有利於控制業務影響。註意在我們前面的討論中,即使業務定義了冷熱判定條件,仍然存在一定的概率會訪問壓縮數據,我們希望這個訪問代價能夠有一個確定性的上限。

圖2給出了塊內壓縮的詳細流程:首先,當壓縮被觸發時,系統掃描數據塊中的所有行,根據指定的冷熱判定條件,識別出R1和R3是冷數據(圖2(a));接著,系統將R1和R3作為一個整體進行壓縮,將壓縮後的數據就存放在該數據塊的BCA中(圖2(b));如果業務後續需要更新R1,那麼系統會為更新後的數據生成一個新的拷貝R4,並標識BCA中的R1已經被刪除(如圖2(c));最後,當系統在該數據塊上需要更多空間時,可以回收BCA中屬於R1的空間(圖2(d))。

cke_115.png

圖2:塊內壓縮

在整個設計中有兩點需要註意:1)我們實際上只壓縮了用戶數據Data,並沒有壓縮相應的元數據Meta,後者通常用來支持事務的可見性;2)我們支持將冷數據重新變為熱數據,以消除因為冷熱誤判而帶來的影響。同樣地,從壓縮率的視角,這樣的設計並不是最友好的,但它極大地減少了對業務的侵入。簡單來說,業務對於壓縮數據的訪問,與正常數據完全相同,在功能上沒有任何限制,在事務語義上也沒有任何差別。這是非常重要的原則:我們的OLTP存儲壓縮對於業務是完全透明的,這是當前這個特性,以及後續GaussDB高級壓縮系列所有特性都將遵循的基本原則。

【壓縮演算法】

基於設計目標,如果從壓縮率、壓縮性能、解壓性能的三維指標來看,我們實際上需要的是一個能夠提供合理的壓縮率、合理的壓縮性能、但是極致的解壓性能的壓縮演算法,這是我們壓縮演算法設計的基礎。

我們首先測試了直接使用LZ4進行壓縮,LZ4是目前已知的壓縮性能和解壓性能最好的開源三方庫,從實測結果看,LZ4的壓縮率是偏低的。我們仔細分析了其演算法原理,LZ4是基於LZ77演算法的一種實現,LZ77演算法的思想非常簡單,就是把要壓縮的數據看成一個位元組流,演算法從位元組流的當前位置開始,前向尋找和當前位置相同的匹配字元串,然後用匹配到的字元串的長度以及與當前位置的偏移,用來表示被匹配的字元串,從而達到壓縮的效果。從演算法原理上看,LZ77演算法對於長文本會有比較好的壓縮效果,但是對於結構化數據中大量的短文本以及數值類型,效果就有限,我們實際的測試也驗證了這一點。

接下來,我們將壓縮演算法分為了兩層:第一層,我們按列對一些數值類型進行了編碼,我們選擇了簡單的差值編碼,這種編碼足夠輕量級,解壓特定欄位不需要依賴其它欄位的值;第二層,我們將編碼後的數據再調用LZ4進行壓縮。註意在第一層中,我們實際上是按列編碼、按行存儲,這和業界的一般實現(按列編碼並存儲)有很大不同,按列存儲對壓縮率會更加友好,但是按列存儲意味著同一行的數據會被分散到BCA的不同區域,這種傳統的設計無法支持我們後續希望實現的部分解壓,我們將在結束語中更詳細地說明這一問題。

通過實測,我們發現這種列編碼+通用壓縮的實現方式有效地提升了壓縮率,同時控制了業務影響的明顯增加,但兩層實現之間是松耦合的,這引入了許多額外的開銷。因此我們在仔細權衡之後,決定放棄LZ4,而是完全基於LZ77演算法,重新實現一個緊耦合的壓縮演算法。

這在當時看來是一個非常冒險的嘗試,事實上,在我們之前,還沒有任何資料庫內核團隊,會選擇自己去實現一個通用壓縮演算法。但從最後取得的收益來看,我們實際上是打開了一扇全新的大門。當列編碼與LZ77演算法之間的邊界被打破時,我們引入了一系列的優化創新,考慮篇幅原因,我們無法展現全部技術細節,在這裡,我們只介紹兩個小的優化:

第一個優化是內置行邊界。我們發現,當系統採用兩層壓縮演算法後,我們需要額外地保存每一行數據在編碼後的長度,因為我們需要在LZ77演算法解壓後找到每一行的邊界,這是一個不小的開銷。為了消除這個開銷,我們選擇在LZ77的編碼格式中嵌入一個行邊界的標記,這個標記只占用了1個位,其開銷較現有方案大幅降低。當然,這個標記位被占用後,LZ77前向搜索的最大視窗長度減少了一半,但在我們這個場景中,這並不是什麼問題,因為我們的典型頁面長度只有8KB。

第二個優化是2位元組短編碼。原有LZ4的實現中,為了提高壓縮性能,系統使用3位元組編碼來描述一個匹配,這意味著系統能夠識別的最短匹配為4位元組。但是在結構化數據中,3位元組的匹配是非常普遍的,參考下麵一個例子:

A = 1 … B = 2

其中,A和B是同一行數據中的兩個整數型欄位,它們的值分別為1和2,基於當前的位元組序,該行數據實際在記憶體中存放的形式如下所示:

01 00 00 00 … 02 00 00 00

註意上面標紅的部分,很明顯,這裡面有一個3位元組的匹配,但是它無法被LZ4識別。

我們通過在LZ77演算法中額外引入2位元組短編碼來解決這一問題,2位元組短編碼可以識別最小3位元組的匹配,從而相對LZ4能夠提升壓縮率。當然,引入短編碼會有額外的開銷:1)壓縮性能會有一定程度的下降,因為我們需要建立兩個獨立的HASH表,幸運的是,在我們這個場景中,極致壓縮性能並不是我們追求的目標;2)2位元組編碼減少了表達匹配串與被匹配串之間距離的位寬,這意味著3位元組的匹配必須離得更近才能被識別,在我們這個場景中,這並不是什麼問題,因為相對於這個限制,一個典型數據行的長度已經是足夠小的。

【效果評估】

我們使用標準的TPCC測試來評估啟用OLTP存儲壓縮特性對業務的影響。TPCC模型共包含9張表,其中空間會動態增長的流水錶共有3張,在這3張表中,訂單明細表(Orderline表)的空間增長比其它表多一個數量級,因此我們選擇在這張表上開啟壓縮。基於TPCC的業務語義,每筆訂單一旦完成配送,其訂單狀態就進入完結狀態,完結的訂單不會再被修改,但仍有一定的概率被查詢。基於這個語義,我們選擇冷熱判定原則為只壓縮已經完結的訂單。

我們分別測試了在不開啟壓縮和開啟壓縮狀態下系統的性能值,結果如圖3所示:

cke_116.png

圖3:業務影響評估

測試結果表明:在TPCC測試場景下,開啟壓縮與不開啟壓縮相比,系統性能大概降低了1.5%。這是一個非常不錯的結果,這意味著即使在超過百萬tpmC的業務峰值場景中,系統也可以開啟壓縮。我們不知道在此之前,業內是否有其它資料庫產品也能夠達到這一水平。

我們測試了Orderline表的壓縮率,作為更豐富的數據集,我們同時選擇了TPCH模型中的4張表(Lineitem、Orders、Customer、Part表)進行測試。為了便於比較,對於每個數據集,我們同時測試了LZ4、ZLIB和我們的壓縮演算法的壓縮率表現,其中ZLIB是強調壓縮解壓性能和壓縮率均衡的演算法,其壓縮解壓性能較LZ4低了5-10倍。最終結果如圖4所示:

cke_117.png

圖4:壓縮率評估

測試結果與我們預期的相符,在數值型欄位較多時,我們的壓縮演算法的壓縮率要高於所有通用壓縮演算法,但在文本型欄位較多時,我們的壓縮演算法的壓縮率會介於LZ類和LZ + Huffman組合類的壓縮演算法之間。

【運維TIPS】

註意我們的壓縮方案實際上是離線的,也就是數據剛生成時必然是熱數據,它們不會觸發壓縮,業務訪問這些數據的性能也不會受任何影響;隨著時間的推移,這些數據的溫度會逐漸降低,最終被獨立的壓縮任務識別為冷數據併進行壓縮。

選擇在業務低峰期運行這些壓縮任務、並控制其資源消耗是運維端需要關註的問題。在這塊我們提供了豐富的運維手段,包括指定運維視窗、壓縮任務的並行度、每個壓縮任務的壓縮數據量等。對於絕大多數業務來說,單位時間內新增的數據量實際是比較有限的,因此業務也可以選擇一個特定的時間段集中完成壓縮任務,比如每個月第一天的凌晨兩點到四點,完成3個月前新增冷數據的壓縮。

業務在決定開啟壓縮之前,可能希望先瞭解開啟壓縮後的收益,並根據收益大小做出決策。為此我們提供了一個壓縮率評估工具,能夠對目標表的數據進行採樣,並使用和實際壓縮過程完全相同的演算法對採樣數據進行壓縮,計算壓縮率,但不會實際生成BCA,不會修改任何數據。

如果業務將壓縮數據遷移到另一個表,可能會導致所有數據從壓縮狀態變為非壓縮狀態,從而導致空間膨脹,這並非我們的方案引入的,而是所有壓縮方案都需要解決的問題。如果冷熱判定規則非常確定,那麼業務可以手動執行壓縮任務使壓縮立即生效;對於耗時較長的大容量壓縮表的遷移,業務仍然可以選擇定期地開啟自動壓縮任務來完成。

最後,對於壓縮的開啟和關閉,我們提供最細粒度的控制,無論是普通表、普通分區表中的單個分區,還是二級分區中的任意單個分區、子分區,業務都可以單獨開啟或關閉壓縮。這使得對於業務本身已經對數據區分了冷熱(比如基於時間分區)的場景,仍然可以和我們的壓縮特性很好地配合。

【結束語】

在OLTP表壓縮這個特性中,我們引入了一系列的技術創新,包括全新的壓縮演算法、細粒度的自動冷熱判定和塊內壓縮支持等,可以在提供合理壓縮率的同時,大幅度降低對業務的影響,我們希望這個特性能夠在支持關鍵線上業務的容量控制中發揮重要價值。

接下來我們還將在降低引入壓縮對業務的影響、部分解壓特性、OLTP索引壓縮等方面持續創新迭代,我們希望能夠有開創性的技術突破來解決相關的問題,為業務創造更大價值。

 

點擊關註,第一時間瞭解華為雲新鮮技術~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ## 引言 上文[編碼技巧 同步鎖對象的選定](url)中,提到了在C#中,讓線程同步有兩種方式: - 鎖(lock、Monitor等) - 信號量(EventWaitHandle、Semaphore、Mutex) 加鎖是最常用的線程同步的方法,就不再討論,本篇主要討論使用信號量同步線程。 ## W ...
  • [TOC] # PWM脈衝寬調點燈 ## 前言 對於燈等來說有很多種方法,前面介紹了一些基礎的點燈方法,比如直接點燈,按鍵控制點燈,按鍵中斷點燈,但都是比較簡單的一些方法也很基礎,要問我有沒有什麼高級點的點燈方法,答案是有的,在這我要介紹一種高級點燈的方法就是使用PWM進行點燈。 ## 1.什麼是P ...
  • 大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是**恩智浦i.MXRT1xxx系列MCU的Serial NAND啟動**。 最近越來越多的客戶在咨詢 i.MXRT1xxx 從 Serial NAND 啟動的事情,讓這個本來比較冷門的啟動設備突然火熱起來。據痞子衡的瞭解,其實客戶主要目 ...
  • # 安裝 安裝 ```bash sudo apt install samba ``` 檢查服務狀態 ```bash systemctl status smbd --no-pager -l ``` 檢查是否啟用(開機自啟動) ```bash systemctl is-enabled smbd # en ...
  • ![](https://img2023.cnblogs.com/blog/3076680/202307/3076680-20230719144557396-616589792.png) # 1. 結果集分頁 ## 1.1. 只有做過了排序,才有可能準確地從結果集中返回指定區間的記錄 ## 1.2.  ...
  • 一、約束的基本概念 1、概念:約束是作用於表中欄位上的規則,用於限制儲存在表中的數據 2、目的:保證資料庫中的數據的正確性,有效性和完整性 3、分類 非空約束(not null):限制該欄位的數據不能為null 唯一約束(unique):保證該欄位的所有數據都是唯一,不重覆的 主鍵約束(primar ...
  • ![file](https://img2023.cnblogs.com/other/3195851/202307/3195851-20230719181113912-393860575.jpg) > 版本說明: > > SeaTunnel:apache-seatunnel-2.3.2-SNAPHOT ...
  • 點亮Star⭐️ · 支持我們 https://github.com/apache/dolphinscheduler ![file](https://img2023.cnblogs.com/other/2685289/202307/2685289-20230719174824082-15652781 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...