從NoSQL到NewSQL,談交易型分散式資料庫建設要點

来源:https://www.cnblogs.com/ivan-uno/archive/2018/06/04/9131847.html
-Advertisement-
Play Games

本文重點談交易型分散式資料庫的關鍵設計點,這裡並不針對具體的產品而是以普適性的結構,結合NoSQL與NewSQL的差異,從縱向來談談OLTP場景“分散式資料庫”實現方案的關鍵技術要點。算是分散式資料庫專題文章的一個總綱,其中的要點Ivan之後也會單獨撰文闡述。 ...


在上一篇文章《從架構特點到功能缺陷,重新認識分析型分散式資料庫》中,我們完成了對不同“分散式資料庫”的橫向分析,本文Ivan將講述拆解的第二部分,會結合NoSQL與NewSQL的差異,從縱向來談談OLTP場景“分散式數 據庫”實現方案的關鍵技術要點。本文既是前文的延伸,同時也算是分散式資料庫專題文章的一個總綱,其中的要點Ivan之後也會單獨撰文闡述。

特別說明:本文是原創文章,首發在DBAplus社群,轉載須獲得作者同意。


一、NewSQL & NoSQL

NewSQL是本專題關註的重點,也是前文中特指的“分散式資料庫”,其適用於OLTP場景,具有高併發低延遲的特點,特性接近Oracle/DB2等傳統資料庫,依賴通用X86伺服器實現性能上的水平拓展,能夠扛住海量交易的性能壓力。

目前具有較高知名度的NewSQL有Google的Spanner / F1、阿裡的OceanBase、CockroachDB、TiDB。其中後兩者是正在成長中的開源項目,2018年相繼發佈了2.0版本。

NewSQL與NoSQL有很深的淵源,所以下文在對NewSQL的介紹中會穿插一些NoSQL對應的實現技術方式。

1.存儲引擎

B+ Tree

B+樹是關係型資料庫常用的索引存儲模型,能夠支持高效的範圍掃描,葉節點相關鏈接並且按主鍵有序,掃描時避免了耗時的遍歷樹操作。B+樹的局限在於不適合大量隨機寫場景,會出現“寫放大”和“存儲碎片”。

以下借用薑承堯老師書中的例子[1]來說明B+樹的操作過程↓

存在高度為2的B+樹,存儲在5個頁表中,每頁可存放4條記錄,扇出為5。下圖展示了該B+ Tree的構造,其中略去了葉子節點指向數據的指針以及葉子節點之間的順序指針:

B+樹由內節點(InterNode)和葉節點(LeafNode)兩類節點構成,後者攜帶指向數據的指針,而前者僅包含索引信息。

當插入一個索引值為70的記錄,由於對應頁表的記錄已滿,需要對B+樹重新排列,變更其父節點所在頁表的記錄,並調整相鄰頁表的記錄。完成重新分佈後的效果如下:

變更過程中存在兩個問題:

  • 寫放大

本例中,邏輯上僅需要一條寫入記錄(黃色標註),實際變動了3個頁表中的7條索引記錄,額外的6條記錄(綠色標註)是為了維護B+樹結構產生的寫放大。

註: 寫放大(Write Amplification):Write amplification is the amount of data written to storage compared to the amount of data that the application wrote,也就是說實際寫入磁碟的數據大小和應用程式要求寫入數據大小之比

  • 存儲不連續

新 增葉節點會加入到原有葉節點構成的有序鏈表中,整體在邏輯上是連續的;但磁碟存儲上,新增頁表申請的存儲空間與原有頁表很可能是不相鄰的。這樣,在後續包 含新增葉節點的查詢中,將會出現多段連續讀取,磁碟定址的時間將會增加。進一步來說,在B+Tree上進行大量隨機寫會造成存儲的碎片化。

在 實際應用B+Tree的資料庫產品(如MySQL)中,通常提供了填充因數(Factor Fill)進行針對性的優化。填充因數設置過小會造成頁表數量膨脹,增大對磁碟的掃描範圍,降低查詢性能;設置過大則會在數據插入時出現寫擴大,產生大量 的分頁,降低插入性能,同時由於數據存儲不連續,也降低了查詢性能。

LSM-Tree

LSM-Tree(Log Structured-Merge Tree)由Patrick O'Neil首先提出,其在論文[2]中系統闡述了與B+樹的差異。而後Google在Bigtable中引入了該模型,如下圖所示:

LSM-Tree的主要思想是藉助記憶體將隨機寫轉換為順序寫,提升了寫入性能;同時由於大幅度降低了寫操作對磁碟的占用,使讀操作獲得更多的磁碟控制權,讀操作性能也並未受到過多的影響。

寫操作簡化過程如下:

  • 當寫入請求到達時,首先寫入記憶體中Memtable,處理增量數據變化,同時記錄WAL預寫日誌;
  • 內 存增量數據達到一定閾值後,當前Memtable會被凍結,並創建一個新的Memtable,已凍結的Memtable中的數據會被順序寫入磁碟,形成有 序文件SSTable(Sorted String Table),這個操作被稱為Minor Compaction(在HBase中該操作稱為Flush操作,而Minor Compaction有其他含義);
  • 這些SSTable滿足一定的規則後進行合併,即Major Compaction。每個Column Family下的所有SSTable被合併為一個大的SSTable。

該模型規避了隨機寫的IO效率問題,有效緩解了B樹索引的寫放大問題,極大的提升了寫入效率。

NoSQL廣泛使用了LSM-Tree模型,包括HBase、Cassandra、LevelDB、RocksDB等K/V存儲。

當然LSM-Tree也存在自身的缺陷:

  • 首先,其Major Compaction的操作非常重影響聯機讀寫,同時也會產生寫放大。因為這個原因,HBase的使用中通常會禁止系統自動執行Major Compaction。

註釋:

Major Compaction操作的意義是降低讀操作的時間複雜度。設系統包含多個SSTable文件,共有N數據,SSTable平均包含m數據。

執行讀操作時,對單一SSTable文件採用折半查找方法的時間複雜度為O(log2m),則整體時間複雜度為O(N/m* log2m);合併為一個SSTable後,時間複雜度可降低到O(log2N)

  • 其次是對讀效率的影響,因為SSTable文件均處於同一層次,根據批量寫的執行時序形成若幹文件,所以不同文件中的Key(記錄主鍵)會出現交叉重疊,這樣在執行讀操作時每個文件都要查找,產生非必要的I/O開銷。

  • 最後是空間上的放大(Space Amplification),最壞情況下LSM Tree需要與數據大小等同的自由空間以完成Compact動作,即空間放大了100%,而B+樹的空間放大約為1/3。

Leveled LSM Tree

Leveled LSM Tree 的變化在於將SSTable做了進一步的分層,降低寫放大的情況,縮小了讀取的文件範圍,在LevelDB 中率先使用,隨後Cassandra 1.0也引入了該策略[3]。

SSTable的層次化設計策略是:

  • 單個SSTable文件大小是固定的,在Cassandra中預設設置為5M;
  • 層 級從Level 0開始遞增,存儲數據量隨著層級的提升而增長,層級之間有一致的增長繫數(Growth Factor)。Cassandra中Growth Factor設置為10,Level 1文件為1-10M則Level 2 文件為10-100M,這樣10TB數據量會達到Level 7;
  • Level 0的SSTable比較特殊,固定為4個文件,且文件之間存在Key交叉重疊的情況,從Level 1開始,SSTable不再出現Key交叉情況;
  • Level 0層的SSTable超過容量大小時,向Level 1 Compaction,因為存在Key交叉,所以要讀取Level 0的所有SSTable;當Level 1 的文件大小超過閾值時,將創建Level 2的SSTable並刪除掉Level 1原有的SSTable;當Level 1的Key範圍對應Level 2的多個SSTable時,要重寫多個SSTable,但由於SSTable的大小固定,所以通常只會涉及少數的SSTable。
Level間Compact操作

多個有序的SSTable,避免了Major Compaction這樣的重量級文件重寫,每次僅更新部分內容,降低了寫放大率。

對於讀取元數據來鎖定相關的SSTable,效率顯然超過了對所有SSTable的折半查找和Bloom Filter。因此,讀取效率得到了顯著提升,按照某種評估方式[3],在每行數據大小基本相同的情況下,90%的讀操作僅會訪問一個SSTable。

該策略下,Compaction的操作更加頻繁,帶來了更多I/O開銷,對寫密集型操作而言,最終結果是否能夠得到足夠的效率提升存在不確定性,需要在應用中權衡。

NewSQL的策略

NewSQL 資料庫的存儲層普遍都採用K/V存儲,所以基本沿用了LSM Tree模型。其中CockroachDB和TiDB都在KV層使用RocksDB。OceanBase採用了不同的方法規避Major Compaction的影響,大體是利用閑置的副本(Follower)進行Compaction操作,避免了對讀操作的阻塞,在Compaction完 成後,進行副本的角色的替換。

同時,K/V存儲引擎仍然在繼續發展中,一些其他的改進如分形樹(Fractal Tree)等,限於篇幅我們就不在此展開了。

2.分片

分片(Sharding)概念與RDBMS的分區相近,是分散式資料庫或分散式存儲系統的最關鍵特性,是實現水平擴展的基礎,也在NoSQL類系統中得到了大量運用。

分片的目標是將數據儘量均勻地分佈在多個節點上,利用多節點的數據存儲及處理能力提升資料庫整體性能。

Range&Hash

雖然不同的系統中對分片策略有很多細分,但大致可以歸納為兩種方式,Range和Hash。

Range分片有利於範圍查詢,而Hash分片更容易做到數據均衡分佈。在實際應用中,Range分片似乎使用得更多,但也有很多應用會混合了兩種分片方式。

HBase採用了Range方式,根據Rowkey的字典序排列,當超過單個Region的上限後分裂為兩個新的Region。Range的優點是數據位置接近,在訪問數據時,範圍查找的成本低;缺點也比較明顯,在容易出現熱點集中的問題。

例 如,在HBase通常不建議使用業務流水號作為RowKey,因為連續遞增的順序號在多數時間內都會被分配到同一個RegionServer,造成併發訪 問同時競爭這個RegionServer資源的情況。為了避免該問題,會建議將RowKey進行編碼,序號反轉或加鹽等方式。這種方式實質上是使用應用層 的設計策略,將Range分片轉換成類似Hash分片的方式。

Spanner的底層存儲沿用了BigTable的很多設計思路,但在分片上有所調整,在Tablet內增加了Directory的動態調配來規避Range分片與操作熱點不匹配的問題,後續在事務管理部分再詳細描述。

靜態分片&動態分片

按照分片的產生策略可以分為靜態分片和動態分片兩類。

靜態分片在系統建設之初已經決定分片的數量,後期再改動代價很大;動態分片是指根據數據的情況指定的分片策略,其變更成本較低,可以按需調整。

傳 統的DB + Proxy方案,進行水平分庫分表就是一種常見的靜態分片。我們熟知的幾個互聯網大廠在大規模交易系統中都進行過類似的設計,預設將數據做成某個固定數量 的分片,比如100、255、1024,或者其它你喜歡的數字。分片的數量可以根據系統預期目標的整體服務能力、數據量和單節點容量進行評估,當然具體到 100片合適還是1024片合適,多少還是有拍腦袋的成分。

在NoSQL中,Redis集群也採用同樣的靜態分片方式,預設為16384個哈希槽位(等同於分片)。

靜 態分片的缺點是分片數量已經被確定,基於單點處理能力形成一個容量的上限;靈活性較差,後續再做分片數量調整時,數據遷移困難,實現複雜。優點也很明顯, 靜態分片的策略幾乎是固化的,因此對分區鍵、分區策略等元數據管理的依賴度很低,而這些元數據往往會形成分散式資料庫中的單點,成為提升可靠性、可用性的 障礙。

相比之下,動態分片的靈活性更好,適用於更豐富的應用場景,所以NewSQL也主要採用動態分片方式,代價則是對元數據管理的複雜度增加。

在分片處理上,NoSQL與NewSQL面臨的問題非常接近。

3.副本

首先是由於通用設備單機可靠性低,必須要通過多機副本的方式。本文中關註兩個問題:一是副本一致性;二是副本可靠性與副本可用性的差異。

數據副本一致性

多 副本必然引入了副本的數據一致性問題。之前已經有大名鼎鼎的CAP理論,相信大家都是耳熟能詳了,但這裡要再啰嗦一句,CAP里的一致性和事務管理中的一 致性不是一回事。Ivan遇到過很多同學有誤解,用CAP為依據來證明分散式架構不可能做到事務的強一致性,而只能是最終一致性。

事務的一致性是指不同數據實體在同一事務中一起變更,要麼全部成功,要麼全部失敗;而CAP中的一致性是指原子粒度的數據副本如何保證一致性,多副本在邏輯上是同一數據實體。

副本同步大致歸納為以下三種模式:

  • 強同步:即 在多個副本都必須完成更新,數據更新才能成功。這種模式的問題是高延時、低可用性,一次操作要等待所有副本的更新,加入了很多網路通訊開銷,增加了延時。 多個副本節點必須都正常運行的情況下,整個系統才是可用的,任何單點的不可用都會造成整個系統的不可用。假設單點的可用性是95%,則三個節點的構成的多 副本,其可靠性為95% * 95% * 95% = 85.7%。因此雖然Oracle/MySQL等主流資料庫都提供了強同步方式,但在企業實際生產環境中很少有應用。

  • 半同步:MySQL提供了半同步方式,多個從節點從主節點同步數據,當任意從節點同步成功,則主節點視為成功。這個邏輯模型有效規避了強同步的問題,多節點可用性的影響從“與”變為“或”,保障了整體的可用性。但遺憾的是在技術實現上存在瑕疵,會有退化為非同步的問題。

  • Paxos/Raft:該 方式將參與節點劃分為Leader/Follower等角色,主節點向多個備節點寫入數據,當存在一半以上節點寫入成功,即返回客戶端寫入成功。該方式可 以規避網路抖動和備節點服務異常對整體集群造成的影響。其他像Zookeeper的ZAB協議,Kafka的ISR機制,雖然與Paxos/Raft有所 區別,但大致是一個方向。

副本可靠性與副本可用性

數據副本僅保證了數據的持久性,即數據不丟失。我們還面臨著副本的可用性問題,即數據是否持續提供服務。以HBASE-10070為例來說明這個問題:

HBase通過分散式文件系統HDFS實現了數據多副本的存儲,但是在提供服務時,客戶端是連接到RegionServer進而訪問HDFS上的數據。因為一個Region會被唯一的RegionServer管理,所以RegionServer仍然是個單點。

在 RegionServer宕機時,需要在一定的間隔後才被HMaster感知,後者再調度起一個新的RegionServer並載入相應的Region, 整個過程可能達到幾十秒。在大規模集群中,單點故障是頻繁出現的,每個單點帶來幾十秒的局部服務中斷,大大降低了HBase的可用性。

為瞭解決這問題,HBase引入從RegionServer節點的概念,在主節點宕機時,從節點持續提供服務。而RegionServer並不是無狀態服務,在記憶體中存儲數據,又出現了主從RegionServer間的數據同步問題。

HBase實現了數據的可靠性,但仍不能充分實現數據的可用性。CockroachDB和TiDB的思路是實現一個支持Raft的分散式KV存儲,這樣完全忽略單節點上記憶體數據和磁碟數據的差異,確保數據的可用性。

4.事務管理

分散式事務處理由於其複雜性,是NoSQL發展中最先被捨棄的特性。但由於大規模互聯網應用廣泛出現,其現實意義逐漸突出,又重新成為NewSQL無法規避的問題。隨著NewSQL對事務處理的完善,也讓過去十餘年資料庫技術的演進終於實現了一個接近完整的上升螺旋。

鑒於分散式事務管理的複雜性,Ivan在本文中僅作簡要說明,後續文章中會進一步展開。

NewSQL 事務管理從控制手段上分為鎖(Lock-Base)和無鎖(Lock-Free)兩種,其中,無鎖模式通常是基於時間戳協調事務的衝突。從資源占用方式 上,分為樂觀協議和悲觀協議,兩者區別在於對資源衝突的預期不同:悲觀協議認為衝突是頻繁的,所以會儘早搶占資源,保證事務的順利完成;樂觀協議認為衝突 是偶發的,只在可以容忍的最晚時間才會搶占資源。

以下通過最經典的“兩階段提交協議”和具體的兩種應用實踐,來具體闡述實現方式:

兩階段提交協議(2PC)

兩階段提交協議(Tow phase commit protocol,2PC)是經典的分散式事務處理模型,處理過程分為兩個階段:

請求階段:

  • 事務詢問。協調者向所有參與者發送事務內容,詢問是否可以執行事務提交操作,並開始等待各參與者的相應;
  • 執行事務。各參與者節點執行事務操作,並將Undo和Redo信息記入事務日誌中;
  • 各參與者向協調者反饋事務詢問的響應。如果參與者成功執行了事務操作,那麼就反饋給協調者Yes,表示事務可以執行;如果參與者沒有成功執行事務,那麼就反饋給No,表示事務不可以執行。

提交階段:

  • 提交事務。發送提交請求。協調者向所有參與者節點發出Commit請求;
  • 事務提交。參與者接到Commit後,會正式執行事務提交操作,併在完成提交之後釋放在整個事務執行期間占有的事務資源;
  • 反饋事務提交結果。參與者在完成事務提交後,向協調者發送Ack消息;
  • 完成事務。協調者收到所有參與者反饋的Ack消息後,完成事務;
  • 中斷事務。發送回滾請求。協調者向所有參與者發出Rollback請求;
  • 事務回滾。參與者接收到Rollback請求後,會利用其階段一記錄的Undo信息來執行事務回滾操作,併在完成回滾之後釋放在整個事務執行期間占有的事務資源;
  • 反饋事務回滾結果。參與者在完成事務回滾後,向協調者發送Ack消息;
  • 中斷事務。協調者接收到所有參與者反饋的Ack消息後,完成事務中斷。

該模型的主要優點是原理簡單,實現方便。

缺點也很明顯,首先是同步阻塞,整個事務過程中所有參與者都被鎖定,必然大幅度影響併發性能;其次是單點問題,協調者是一個單點,如果在第二階段宕機,參與者將一直鎖定。

Spanner

根據Spanner論文[4]的介紹,其分散式事務管理仍採用了2PC的方式,但創新性的設計是改變了Tablet的數據分佈策略,Tablet不再是單一的連續Key數據結構,新增了Directory作為最小可調度的數據組織單元。

通過動態的調配,降低事務內數據跨節點分佈的概率。

Ivan將這種事務處理的設計思想理解為:“最好的分散式事務處理方式,就是不做分散式事務處理,將其變為本地事務”。在OceanBase的早期版本中也採用了一個獨立的伺服器UpdateServer來集中處理事務操作,理念有相近之處。

Percolator

Percolator[5] 是Google開發的增量處理網頁索引系統,在其誕生前,Google採用MapReduce進行全量的網頁索引處理。這樣一次處理的時間取決於存量網頁 的數量,耗時很長;而且即使某天只有少量的網頁變更,同樣要執行全量的索引處理,浪費了大量的資源與時間。採用Percolator的增量處理方式後,大 幅度減少了處理時間。

在這篇論文中給出了一個分散式事務模型,是“兩階段提交協議”的變形,其將第二階段的工作簡化到極致,大幅提升了處理效率。

具體實現上,Percolator是基於BigTable實現分散式事務管理,通過MVCC和鎖的兩種機制結合,事務內所有要操作的記錄均為新增版本而不更新現有版本。這樣做的好處是在整個事務中不會阻塞讀操作。

  • 事務中的鎖分為主(Primary)和從鎖(Secondary),對事務內首先操作的記錄對加主鎖,而後對事務內的其他記錄隨著操作過程逐步加從鎖並指向主鎖記錄,一旦遇到鎖衝突,優先順序低的事務釋放鎖,事務回滾;
  • 事務內的記錄全部更新完畢後,事務進入第二階段,此時只需要更新主鎖的狀態,事務即可結束;
  • 從鎖的狀態則依賴非同步進程和相關的讀操作來協助完成,由於從鎖記錄上保留了指向主鎖記錄的指針,非同步進程和讀操作都很容易判斷從鎖的正確狀態,併進行更新。

分散式事務管理的其他內容,包括無鎖事務控制、全局時鐘的必要性等等,待後續文章中再討論。

二、結語

本文最初的立意是面向幾類典型技術背景的同學,對“分散式資料庫”展開不同方向的解讀,並就其中部分技術要點進行闡述,使不同技術領域的同學能夠對相關技術有些許瞭解,為有興趣深入研究的同學做一個鋪墊。

隨著分析的深入愈發覺得文章框架過於龐大難於駕馭,因而對關鍵技術的解讀也存在深淺不一的情況。對於本文中未及展開的部分,Ivan會儘力在後續系列文章中予以補充,水平所限文中必有錯漏之處,歡迎大家討論和指正。

文獻參考:

[1] 薑承堯, MySQL技術內幕:InnoDB存儲引擎機, 械工業出版社, 2011

[2] Patrick O'Neil The Log-Structured Merge-Tree

[3] Leveled Compaction in Apache Cassandra

https://www.datastax.com/dev/blog/leveled-compaction-in-apache-cassandra

[4] James C. Corbett, Jeffrey Dean, Michael Epstein, et al. Spanner: Google's Globally-Distributed Database

[5] Daniel Peng and Frank Dabek, Large-scale Incremental Processing Using Distributed Transactions and Notifications


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

-Advertisement-
Play Games
更多相關文章
  • --查詢工資最高的前三名 (分頁的感覺)select * from(select * from emp order by sal desc) twhere rownum <=3--查詢工資最高的4到6名 (分頁-->排序 行號 選擇三步)select * from (select t.*,rownu ...
  • 在又是就業的高峰期了,我公司天天都有過來面試的,這不大學生們也都畢業了,今天這位小伙子就是個奇葩,面試不好好做酷炫特效或者能夠讓面試官眼前一輛的代碼,卻畫起了畫,面試官表示: 相信有很多學習大數據的道友,在這裡我給大家說說我滴群哦,大數據海量知識分享,784789432.在此我保證,絕對大數據的乾貨 ...
  • hive在查詢表信息時,中文顯示亂碼,數字或者url顯現null問題解決思路。 1、確定create hive表時指定的row format delimited fields terminated by ‘xxx’中“xxx”格式是否和原始導入表的data的行列分隔格式一致,如不一致,則會出現sel ...
  • oracle 11.2.0 expdp/impdp 數據泵參數 expdp參數 ATTACH 附加目前已有Job中。例如ATTACH=Job_name. CLUSTER 利用cluster或RAC分散式資源。設定值CLUSTER=[Y]/N 預設值為Y COMPRESSION 導出檔案的壓縮。設定值 ...
  • 目前,市場上的大數據產品太多,但遠遠低於IAAS的標準化水平,各產品之間的差異還不十分清楚。當許多公司正在製造大數據平臺或大數據解決方案時,他們往往不知道選擇哪些產品來滿足他們的需求。一般的做法是做研究、學習、建造環境、測試和整合各種產品,但通常這個過程很長,而且成本很高。如果你想瞭解大數據的學習路 ...
  • 原文:https://blog.csdn.net/andrewniu/article/details/78485312 原文:https://jingyan.baidu.com/article/76a7e40909b961fc3b6e1519.html ...
  • 一.概述 講到sql server鎖管理時,感覺它是一個大話題,因為它不但重要而且涉及的知識點很多,重點在於要掌握高併發要先要掌握鎖與事務,涉及的知識點多它包括各式各樣的鎖,鎖的組合,鎖的排斥,鎖延伸出來的事務隔離級別, 鎖住資源帶來的阻塞,鎖之間的爭用造成的死鎖,索引數據與鎖等。這次介紹鎖和事務, ...
  • 實驗一:實驗案例一(附加“練慣用的可以附加的資料庫--class”) 1、在products表中查詢出廠日期晚於2014年4月的水果信息。 select * from products where 出廠日期>'2014-04-30 ' 2、在products表中分組查詢所有水果,蔬菜,堅果的總成本。 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...