火山引擎 ByteHouse 的增強型數據導入技術實踐

作為企業數字化建設的必備要素,易用的數據引擎能幫助企業提升數據使用效率,更好提升數據應用價值,夯實數字化建設基礎。

數據導入是衡量OLAP引擎性能及易用性的重要標準之一,高效的數據導入能力能夠加速數據實時處理和分析的效率。作為一款OLAP引擎,火山引擎云原生數據倉庫ByteHouse源于開源ClickHouse,在字節跳動多年打磨下,提供更豐富的能力和更強性能,能為用戶帶來極速分析體驗,支撐實時數據分析和海量離線數據分析,具備便捷的彈性擴縮容能力,極致的分析性能和豐富的企業級特性。

隨著ByteHouse內外部用戶規模不斷擴大, 越來越多用戶對數據導入提出更高的要求,這也為ByteHouse的數據導入能力帶來了更大的挑戰。

本篇文章來源于ByteHouse產品專家在火山引擎數智平臺(VeDI)主辦的“數智化轉型背景下的火山引擎大數據技術揭秘”線下Meeup的演講,將從ByteHouse數據庫架構演進、增強HaKafka引擎實現方案、增強Materialzed MySQL實現方案、案例實踐和未來展望四個部分展開分享。

ByteHouse數據庫的架構演進

作為一款分析型數據庫,ByteHouse已經應用在互聯網、金融、汽車領域,幫助企業實現人群洞察、行為分析、 IOT 風控等場景的實時分析。

ByteHouse的演進

  • 從2017年開始,字節內部的整體數據量不斷上漲,為了支撐實時分析的業務,字節內部開始了對各種數據庫的選型。經過多次實驗,在實時分析版塊,字節內部決定開始試水ClickHouse。

  • 2018年到2019年,字節內部的ClickHouse業務從單一業務,逐步發展到了多個不同業務,適用到更多的場景,包括BI 分析、A/B測試、模型預估等。

  • 在上述這些業務場景的不斷實踐之下,研發團隊基于原生ClickHouse做了大量的優化,同時又開發了非常多的特性。

  • 2020年, ByteHouse正式在字節跳動內部立項,2021年通過火山引擎對外服務。

  • 截止2022年3月,ByteHouse在字節內部總節點數達到18000個,而單一集群的最大規模是2400個節點。

ByteHouse的架構

ByteHouse架構分為分布式架構和云原生架構兩種。分布式架構的主要特點就是單集群可以支持 2000 多個節點的“大兵團”;通過分布式的并行計算體現的高性能,能夠充分利用每個節點的計算和存儲資源;云原生實現了存算分離,計算資源通過容器化進行彈性和秒級的擴容,這對業務是無感知的。

從分布式架構來看,ByteHouse具備MPP 1.0特點:

  • 存算一體:通過本地存儲能夠保證它極致的這種查詢性能。

  • 自研的表引擎:包含 HaMergeTree和 HaUniqueMergeTree。

  • 在社區 RBO 優化器的基礎上增強 RBO 加 CBO 的結合的查詢優化,并基于 CBO 的分布式計劃能夠在集群模式下計算全局最優的查詢計劃。

  • 支持數據的冷熱分存,同時兼顧性能和成本。

  • 增強關鍵的數據類型,從而優化查詢性能。

  • 通過統一的管控面提供可視化的管理查詢和運維,從內到外給用戶提供優質的使用體驗。

7fdc2254405d63ab983322e9386236db.png

但MPP 1.0存在資源隔離、擴容等痛點,由此演進到云原生架構,即MPP 2.0:其中存算分離通過結合 shared-everything 存儲和 shared-nothing 計算層,避免了傳統 MPP 架構中數據重新分配 (re-sharding) 的問題。

好處在于:

  • 更好地實現資源隔離。每個用戶不同的計算都提交到不同的計算組,并進行計算資源和存儲資源的擴容,再結合按量計費的計費策略可以降低用戶使用成本。

  • 底層存儲既支持HDFS,也支持 S3 對象存儲,能夠讓 ByteHouse實現真正的云原生。

7798a70bdf5421f634e7c5c67e8e7bf0.png

ByteHouse技術優勢

在增強型數據導入場景中,ByteHouse核心優勢體現在自研表引擎:

  • 在社區版的基礎上,ByteHouse對表引擎做了進一步增強,使其能夠實現開源的ClickHouse所做不到的場景。

  • 高可用引擎,相比社區高可用引擎,可以支持表的數量更多,集群的規模更大,穩定性會更高。

  • 實時數據引擎,相比社區實時數據引擎,消費能力更強,支持 at least once 的語義,排除單點寫入的性能故障。

  • Unique引擎,相比社區Unique引擎,ByteHouse沒有更新延遲問題,能夠實現真正實時的 upsert。

  • Bitmap 引擎,在特定的場景比如用戶圈選圈群的場景中支持大量的交并補操作,能夠使整體的性能提升 10 - 50 倍以上。

4cc9d467414bbf9c650ad5a2082700ca.png

這里具體再介紹一下ByteHouse自研引擎的優勢——與導入密切相關的表引擎。

首先,ByteHouse 提供的HaMergeTree方案能夠降低 ZK 負載,提升可承載的數據量級。

  • ClickHouse 社區版本: 社區提供的ReplicatedMergeTree表引擎讓 ClickHouse 實現了從單機到集群的演進,通過ZK節點來同步并維護兩個MergeTree之間的元數據和數據。痛點在于,在 TB 級的數據量級之下, ZK 重復地進行分發日志和數據交換等操作,極大地增加了ZK的壓力,使ZK 成為整個集群的故障點。

  • ByteHouse 自研HaMergeTree: 將元數據的同步和數據的同步解耦,ZK只負責元數據的同步,而數據的同步是通過 LogExchange 來實現,在兩個MergeTree之間進行對等拷貝。優勢在于,降低了 ZK 的負載,即使是承載 PB 級的數據量,集群也能夠平穩地運行。

其次, ByteHouse 提供的HaMergeTree方案能平衡讀寫性能。

  • ClickHouse 社區版本: 提供ReplacingMerge Tree實現了對唯一鍵的支持;使用Merge-on-read的實現邏輯,在不同批次的數據中包含著相同的 key ,需要在讀時做合并,讓相同的 key 返回最新的版本。痛點在于,數據存在延遲、滯后,降低讀的性能。

  • ByteHouse 自研的HaUniqueMergeTree: 引入了 delete bitmap 的組件在數據插入時即標記刪除,然后在數據查詢時過濾掉標記刪除的數據。優勢在于,整體上平衡了讀和寫的性能,保障了讀取時性能一致性。

增強HaKafka引擎實現方案

HaKafka 引擎架構介紹

社區版Kafka 優勢 : 由于社區版ClickHouse是一個分布式結構,其數據分布在多個Shard上,Kafka引擎可以在多個Shard上去做并發的寫入,而在同一個Shard內可以啟動多線程做并發寫入,并具備本地盤的極致的性能讀寫。

社區版 Kafka 不足 :

  • 在內外部業務的場景中,會經常遇到唯一鍵場景,由于社區版本的 Kafka的 high level 的消費模式(這種模式就決定無法預知數據被寫入到哪一個Shard上),所以很難滿足這一類場景。

  • 社區版的 Kafka 引擎沒有高可用,即使ClickHouse是多副本的,在當一個節點發生宕機時,無法保證另一個節點繼續消費。

HaKafka引擎架構(分布式架構)

保持社區版本兩級并發兩大的優化點:

  • 引入高可用,讓備節點處于 stand-by 的狀態,一旦主節點發生宕機,備節點立刻繼續進行消費。

  • 升級為low-level的消費模式,當數據寫入的時候,相同的 key 會寫到相同的 partition 里面,保證在同一個Shard下支持的唯一鍵場景。

ByteHouse增強HaKafka引擎核心功能實現

  • 高可用(主備切換)

在備節點上起一個 stand by的consumer ,通過 ZK 來進行選組,選到的主節點進行消費,當主節點發生宕機或者無法進行服務時,在秒級之內切換到備節點上,讓備節點繼續消費。

假設現在 replica 1因為故障宕機了,無法繼續進行消費,那么Z K能在秒級內把 replica 2 選為leader。replica 2 隨即會立即啟動相同數量的消費者,啟動之后會繼續從 replica 1 的消費位置開始繼續進行消費。

b245807531972c6468dd87a11e0cddf0.png
  • 替換節點

隨著集群規模的增大,節點數越來越多的情況下,不可避免地遇到節點故障,這個時候就需要替換節點。

對于分布式架構,替換節點一個重要的操作就是拷貝數據,在拷貝數據的時候意味著新的節點的數據是不全的,如圖示,示意圖 replica 1為新替換的節點,還處于數據拷貝的狀態,即數據是不全,如果此時實施消費的 leader 起在了 replica 1,就意味著 最新的消費數據會寫進 replica 1,但是它缺失一部分舊的數據。

而replica 2有舊的數據,它的最新數據還需要從replica 1進行拷貝,那這個時候下載之內沒有一個副本上面的數據是完整的,所有的節點就不可能對外提供服務。

這時HaKafka會做強制限制,如果 replica 1是一個新節點,且還在拷貝數據的狀態,那么就會強制把 leader 切換成 replica 2,由 replica 2 繼續去消費最新的數據,replica 1保持繼續拷貝數據,這樣可以保證在節點替換的過程中至少有一個副本是能夠正常提供服務。

3af3e3554840676b5da9fbd94d7b0e13.png
  • Memory table

不同于社區的Memory Table和底層存儲綁定,ByteHouse的Memory Table是和Hakafka綁定的,主要使用在有百列或者千列的大寬表的場景。

對于ClickHouse來說,每一次導入的寫的文件的數量和列數是成正比的。如果列很多,但是每批次寫入的數據量不大,這時每一次寫入就會造成很多的碎片,這對于 IO的消耗會比較高,寫入的性能其實也會比較差。

針對這種情況,考慮使用Memory Table,讓寫不直接落盤,每一次寫先寫到Memory Table中,攢到一定的批次或者到達一定的時間之后再一次性刷盤。

當數據寫入Memory Table之后,就可以對外提供查詢服務了,因為 memory table 是跟 Kafka 綁定的,在同一個下的內是唯一的。當查詢來了之后,只需要路由到對應的消費節點下 the Memory Table,就能保證了數據查詢的一致性。

29468f9d8f44112388eefa97a847f2d1.png
  • 云原生架構增強

分布式架構的痛點在于:

1.節點故障: 字節的集群規模較大,每周/每天會遇到節點故障的問題,需要進行節點替換,是一個比較大的負擔。

2.讀寫沖突問題: 隨著集群的接入的業務越來越多,數據量越來越大的情況下,每一個節點同時承擔著查詢和寫入的操作,之間會有沖突。

3.擴容成本: 唯一鍵的場景對數據分布要求非常嚴格,擴容在這種場景下很難支持,因為擴容之后partition的映射關系發生了變化。

云原生架構優點在于,存算分離、自動擴容、自動容錯輕量級的擴縮容等,因為云原生支持事物,讓我們可以將消費語義增強到exactly once。

67a419d263a389390064edd5d5a426b1.png
  • 在云原生架構下的 Kafka 引擎是如何通過事務來實現 exactly once:

    • 事務保證: 因為云原生架構有事務的支持,所以每一輪的消費都需要有事物來保證。因為 Catalog 的元信息和 Catalog 元信息的交互是在 Server 端進行的,所以第一步會通過 RPC 的請求向 Server 端請求創建消費事務,然后客戶端創建正常,創建消費事務之后會把 transaction ID 給consumer, consumer 拿到這種全聲音 ID 之后就可以開始正常地消費了。之后它就會從分配到的 partition 里面不停地消費數據,當消費到足夠的數據量或者消費滿足一定的時間時,它就會把消費的這數據轉換為對應的 part 文件并dump到存儲層。在 dump 之后,數據是不可見的,因為這個時候的 transaction 還沒有提交,所以在第五步的時候,還是會通過一個 RPC 的 call 把剛才 dump 的元信息消費的 offseed 提交到 catalog 中。這一步是一個原子性的提交,也是我們的消費語義升級從 at least once 到 exactly once 的一個核心關鍵點

    • 容錯保證: 因為manager 和它具體之間的任務是在不同的節點上的,所以需要有一定的這種容錯機制。當前是讓 manager 和 task 之間保持一種一個雙向的心跳機制來保證,比如說manager每隔 10 秒鐘會去探活一次,看看當前任務是否正常運行,如果沒有在正常運行,它就會重新拉起一個新的task。而對于 task 來說,它每一次的消費都會有兩次的 RPC call 和 Server 端做交互,這兩次的 RPC 交互都會向 manager 去校驗自身的有效性,如果校驗到自己當前是一個失效的狀態,它就會把自己 kill 掉,從而保證整個全局的唯一任務的運行。

    • b6c99b8a6d78a58d78f10fa4d10b4170.png

    • Memory Buffer : 與社區相似,Memory Buffer和底層的存儲表綁定。因為都是寫入底表的,不僅Kafka的導入可以用,Flink的導入也可以用。memory buffer 的使用場景是高頻的小批量的導入場景,因為每一次導入都會寫一個part,不停地寫 part 會對集群產生壓力。而 ClickHouse 的話,對 ClickHouse 來說 part 越多性能越差,所以使用 memory buffer 來緩存小批量的數據,到達一定批次之后再進行導入。首先需要有一個事務的保證,才能保證導入的完整性和一致性。另外它需要有WAL,因為首先把數據要先寫到 WAL 中,數據寫入到 WAL 中之后,就認為導入成功了,因為 WAL 本身也是一個持久化的存儲,數據寫入 WAL 之后,再將數據寫入到 memory buffer。當數據寫入了 memory buffer 之后就可以對外提供查詢服務。

14373f20d52ff57d85e52bf2dfe9ec24.png

增強 Materialzed MySQL 實現方案

社區版 Materialzed MySQL 介紹

物化 MySQL 將MySQL的表映射到 ClickHouse 中, ClickHouse 服務會讀取binlog,并執行 DDL 和 DML 的請求,實現了這種基于實現了基于 MySQL binlog 的實時 CDC 同步。它的架構很簡單,不依賴于數據同步工具,使用自身的資源就能將整個 MySQL 的數據庫同步到 ClickHouse中,并且時效性很好,因為實時同步的延時一般在秒級、毫秒級到秒級之間。

社區版本的這種物化MySQL 在很大程度上去解決了 MySQL 數據庫到 ClickHouse 之間的這種實時同步。在實際業務、實際場景中,遇到不少問題

1.社區版本的物化MySQL,它是不支持同步到分布式表,也不支持跳過DDL,缺乏這些功能就很難將數據庫的引擎應用到實際生產中。

2.社區版本的物化 MySQL 不支持在數據同步發生異常時進行輔助,發生異常的時候發起重新同步的命令,它沒有同步的日志信息和沒有同步的狀態信息,缺少了這些信息會導致同步發生異常的時候,很難在短期內把這些任務重新啟動。

基于這些問題和痛點, ByteHouse在社區版本的物化 MySQL 的基礎之上做了一些功能增強易用性,降低了運維成本,讓數據的同步更加穩定。

f33a4915316704180584a1dcc7cf5aec.png

ByteHouse的物化 MySQL 結合了HaUniqueMergeTree表引擎:結合這樣的表引擎之后,它就能夠實現數據的實時去重能力,同時它能夠支持分布式的能力,我們通過底層的中間的參數優化,比如 include tables、 exclude tables、 SKIP DDL 等等能夠允許用戶自定義同步的表的同步范圍。

通過下 model 這樣的一個參數,能夠支持分布式表的同步,然后通過 Rethink 參數的設置支持將額外增加的表啟動獨立的數據同步任務去進行 CDC 同步,在出現異常的時候,我們也支持跳過這種不支持的 DDL 語句。另外,可以通過系統日志的抓取和展示進行可視化的運維。

b55fa18ca669b3383c9667b84253d45d.png

ByteHouse增強Materialzed MySQL核心功能實現

  • 實時去重 / 分布式

社區版的物化 MySQL 使用的是ReplacingMergeTree,每一個同步任務都會將源端的 MySQL 數據庫同步到 ClickHouse 的某一個節點上面,它不支持按照分片邏輯將數據分布到所有的節點,也無法利用 ClickHouse 整個集群的分布式計算和存儲能力,所ByteHouse的物化MySQL 支持分布式地同步利用。我們利用HaUniqueMergeTree表引擎,將每張表同步到對應的分布式節點上,充分利用集群的這種分布式計算能力,同時通過表引擎的實時 upsert 能力來實現快速地去重。

2a53fab2322eb3f290bb8d7cbcc870b8.png
  • 異步 Resync

這里有三個對象, SYNC manager是用來管理主 SYNC 線程和 Resync 線程,然后 SYNC task 和 resync task 各自管理各自的任務。比如說一個 MySQL 的庫有 100 張表,我們選了 50 張表進行同步,所以在同步進行過程中,當 think task 同步到 binlog 的 position 位置,比如到 1000 的時候,用戶修改了配置之后,它增加了 30 張表。增加 30 張表的時候, SYNC manager 就會啟動 Resync task 去同步另外 30 張表,那這個時候 SYNC task 是繼續執行的;RESYNC task 會從 position 0 開始,它先做全量的同步,然后再做增量的同步。所以當到達某一個階段,比如說 sync task 跑到了 position 1500 的時候, resync task 跑到了 position 1490 的時候,這時 SYNC manager 就會去判斷兩者的誤差,這個 position 的誤差在一定的閾值之內,在一定閾值之內之后,它會將 SYNC task 停止1秒鐘,將 RESYNC task 合并到 SYNC task 中。合并成功之后,這 80 張表就都會通過SYNC task 繼續同步,而 RESYNC task 這個任務就會被停止掉。這就是現在 RESYNC task 做了一個能力實現。

65376143e24d75201374df9a54d91781.png
  • 可視化運維

通過可視化的任務監控和任務啟停異常的重啟任務告警這些方式實現了物化 MySQL 的可視化易用性的極大提升。

a8c895e43093b20d3282ff01fb00aa91.png

案例實踐與未來展望

案例一:短視頻直播

該場景下的數據是批流一體寫入,為了維護和管理抖音創作者的數據,并且面向這種業務運營和達人經營提供數據查詢服務,需要將短視頻和直播的實時數據和離線數據做融合,來構建 B端的數據分析。

  • 問題: 首先,創作者是唯一的,需要我們進行數據去重。第二,數據源是比較多樣化的,所以它整個字段超過 4000 +,是典型的大寬表場景。第三,T+1的數據,T+1數據離線同步后,T+0數據要對它進行更新。第四,是對任何指標的實時查詢需要秒級出結果,這是業務面臨的問題。

  • 解決方案: 第一,我們采用了自研的 Unique表引擎來做實時的去重,并且能夠讓數據在寫入時就可以實時去重、實時查詢。第二,通過 Kafka 引擎的 memory table 來實現大寬表數據先緩存,到達了一定的批次之后再集中刷盤。通過對 Byte house 的優化方案有效地解決了碎片化、IO負載高的問題,能夠支持 10 億+創作數據實時寫入和實時查詢。

5c2d8acabca7418bdbac43760951f4f3.png

案例二:營銷實時數據的監控

營銷實時監控是對業務營銷活動效果的實時查詢和實時回收,希望通過這種實時回收來動態調整獎品的實時發放策略來做到最終的 IOR、ROI 的提升。這就要求數據實時寫入、落盤延時要非常低,對數據處理的性能也有很高的要求。在數據傳送上面需要保證數據傳輸的唯一性,以保證獎品不會重復發放,也不會丟失。

  • 解決方案: 我們在方案上首先采用自研的Kafka 引擎來支持流式數據的實時寫入,實時寫入便實時入庫。通過 low-level 的這種消費來保證數據的有序分片,再通過增強的消費語義 exactly once 保證數據的精準一次傳輸。最后我們通過自研的Unique引擎來實現實時的這種 upsert 的語義,讓數據實時寫入、實時去重。通過 ByteHouse 方案的優化,營銷業務的每一個節點的實時性能達到了 30 MB/s/node,分析性能也是在秒級的延時,讓運營人員能根據不同用戶群,實時發放獎勵,并秒級地監控獎品發放的進展,從而調整獎品的發放策略。

69fca8fcca854a78dd6da68aba65dd28.png

案例三:游戲廣告的數據分析

游戲廣告數據分析是在廣告業務中會做一些人群圈選、廣告投放、效果反饋等投放策略,用戶行為預測這些全流程的統計和監控來實現廣告營銷過程的數字化,提升整個廣告游戲投放的 ROI 。

  • 問題: 業務數據和日志數據要求實時寫入、實時去重,由于體量比較大,所以寫入壓力和查詢壓力都比較大。

  • 解決方案: 首先使用 Kafka 引擎來支持流式數據寫入,通過 low level 消費模式保障數據的有序分片,再通過 Unique引擎來實現數據的唯一性,并且實時地去重。在業務數據方面,我們使用物化MySQL來保障業務數據從 MySQL 到 ByteHouse 之間能夠實時同步。最后使用自研的查詢優化器來優化查詢性能,通過ByteHouse 的優化之后,廣告效果分析從原來的小時級提升到了現在的秒級延時數據查詢的性能,單線程同步 20+MB/s ,并且整個查詢性能提升了 3 倍,用戶的收益和體驗得到了明顯的改善。

5b3d38baa0c51dfeb775da6579205b7c.png

未來戰略:全鏈路和一體化

  • 端到端。從語法轉換、數據遷移,到數據校驗,形成完整的全鏈路方案。

  • 一體化。通過DES的邏輯復制能力實現 TP / AP 的一體化,同時實現數據倉庫和數據集市的一體化。

  • 資源隔離。支持用戶使用共享資源池或者數據庫引擎來進行數據的同步,也支持用戶通過獨享的資源池來進行高效數據同步。

  • 多引擎方案。除了基于 ClickHouse 引擎的基礎能力,我們也會去探索更多的底層引擎能力來增強ByteHouse的數據同步。

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

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

相關文章

Sa-Token 整合Java17和SpringBoot

目錄 前言引入項目開啟登錄認證路由攔截鑒權解決兼容問題總結 前言 之前無意中發現Sa-Token權限認證框架,項目十分好用。 項目地址: https://github.com/dromara/sa-token 官網地址: https://sa-token.cc/doc.html#/start/example 我的個人…

如何輕松應對企業網絡管理挑戰,釋放網絡靈活性

企業在日常經營中,越來越依賴于云應用程序,分散的團隊和統一通信。這些變化使得保持網絡連接性不僅是必要的,而且對任務的成功完成至關重要。 傳統的廣域網(WAN)并不總能適應這些挑戰,因為它們往往無法提供…

不停的挖掘硬盤的最大潛能

從 NAS 上退休的硬盤被用在了監控的存儲上了。 隨著硬盤使用壽命的接近尾聲,感覺就是從高附加值數據到低附加值數據上。監控數據只會保留那么幾個月的時間,很多時候都會被覆蓋重新寫入。 有人問為什么監控數據不保留幾年的,那是因為監控數據…

java_函數式接口

文章目錄 一、什么是函數式接口二、四大核心函數式接口三、使用舉例 一、什么是函數式接口 如果一個接口只有一個抽象方法,那么該接口就是一個函數式接口函數式接口的實例可以通過 lambda 表達式、方法引用或者構造方法引用來創建如果我們在某個接口上聲明了 Funct…

【Unity入門】鼠標輸入和鍵盤輸入

Unity的Input類提供了許多監聽用戶輸入的方法,比如我們常見的鼠標,鍵盤,手柄等。我們可以用Input類的接口來獲取用戶的輸入信息 一、監聽鼠標輸入 GetMouseButtonUp 、GetMouseButtonDown、GetMouseButton input.GetMouseButtonDown和 inp…

從mysql源碼編譯出相應的庫和可執行文件及搭建mysql服務端

目錄 1. 問題的提出 2. 源碼下載 3. 升級或安裝某些前置軟件 3.1. 升級CMake 3.2. 升級gcc、g 4. 安裝依賴庫 4.1. 安裝OpenSSL 4.2. 安裝Curses 4.3. 安裝pkg-config 5. 編譯、安裝 6. 編譯結果、配置 7. 編譯錯誤處理 7.1. 錯誤1 7.2. 錯誤2 8. 搭建mysql數…

VMware三種網絡模式

橋接模式 NAT(網絡地址轉換模式) Host-Only(僅主機模式) 參考: vmware虛擬機三種網絡模式 - 知乎 (zhihu.com)

【中國平安社招校招】【內推】【當天內推】

中國平安社招校招內推 通過內推鏈接即時內推,反饋速度比正常要快(可私信問進度) 開放大量HC(不限崗位和地區,技術、設計、產品、運營、數據等都可內推) Step1:查看相關職位 瀏覽平安的招聘官網:復制以下地址至瀏覽器打開。注意以下鏈接包含…

一篇文章搞懂WPF動畫的使用技巧

WPF 動畫系統提供了豐富的功能,用于為 UI 元素創建流暢的動態效果。動畫可以應用于任何可用于渲染的屬性,比如位置、顏色、大小等。在 WPF 中,動畫是通過更改隨時間變化的屬性來實現的。 WPF動畫基本用法 例如實現如下的動畫效果&#xff1…

合并區間問題

以數組 intervals 表示若干個區間的集合,其中單個區間為 intervals[i] [starti, endi] 。請你合并所有重疊的區間,并返回 一個不重疊的區間數組,該數組需恰好覆蓋輸入中的所有區間 。 示例 1: 輸入:intervals [[1,…

Java如何獲取泛型類型

泛型(Generic) 泛型允許程序員在強類型程序設計語言中編寫代碼時使用一些以后才指定的類型,在實例化時作為參數指明這些類型。各種程序設計語言和其編譯器、運行環境對泛型的支持均不一樣。Ada、Delphi、Eiffel、Java、C#、F#、Swift 和 Vis…

WPF樹形控件TreeView使用介紹

WPF 中的 TreeView 控件用于顯示層次結構數據。它是由可展開和可折疊的 TreeViewItem 節點組成的&#xff0c;這些節點可以無限嵌套以表示數據的層次。 TreeView 基本用法 例如實現下圖的效果&#xff1a; xaml代碼如下&#xff1a; <Window x:Class"TreeView01.Mai…

springcloud整合seata我踩過的坑

版本問題 seata 1.5和1.5之前的目錄結構不同,使用docker修改的配置文件也不同 1.4的左右 1.5之后docker 掛載文件也不同 1.5之前是使用自己寫的掛載registry docker run -d -p 8091:8091 -p 7091:7091 --network newlead --name seata-serve -e SEATA_IP192.168.249.132…

4:kotlin 方法(Functions)

想要聲明一個函數需要使用fun關鍵字 fun hello() {return println("Hello, world!") }fun main() {hello()// Hello, world! }格式: fun 方法名(參數1: 參數1類型, 參數2 : 參數2類型, ...): 返回值類型 {方法體return 返回值 }fun 方法名(參數1: 參數1類型, 參數2…

人工智能基礎_機器學習047_用邏輯回歸實現二分類以上的多分類_手寫代碼實現邏輯回歸OVR概率計算---人工智能工作筆記0087

然后我們再來看一下如何我們自己使用代碼實現邏輯回歸的,對二分類以上,比如三分類的概率計算 我們還是使用鶯尾花數據 首先我們把公式寫出來 def sigmoid(z): 定義出來這個函數 可以看看到這需要我們理解OVR是如何進行多分類的,我們先來看這個 OVR分類器 思想 OVR(One-vs-…

UE 進階篇一:動畫系統

導語: 下面的動畫部分功能比較全,可以參考這種實現方式,根據自己項目的顆粒度選擇部分功能參考,我們商業項目動畫部分也是這么實現的。 最后實現的效果如下: 最終效果 目錄: ------------------------------------------- 文末有視頻教程/工程地址鏈接 -------------…

9、鴻蒙應用桌面圖標外觀和國際化

一、項目資源目錄 項目下的resoueces目錄為資源配置目錄&#xff0c;其中base為基礎配置&#xff0c;即在任何語言環境下都會加載的資源&#xff0c; color.json&#xff1a;用于配置顏色&#xff0c;如頁面的背景和文字的顏色。 string.json&#xff1a;用于設置文字&#…

Selenium切換窗口、框架和彈出框window、ifame、alert

一、切換窗口 #獲取打開的多個窗口句柄 windows driver.window_handles #切換到當前最新打開的窗口 driver.switch_to.window(windows[-1]) #最大化瀏覽器 driver.maximize_window() #刷新當前頁面 driver.refresh() 二、切換框架frame 如存在以下網頁&#xff1a; <htm…

Java基礎(程序控制結構篇)

Java的程序控制結構與C語言一致&#xff0c;分為順序結構、選擇結構&#xff08;分支結構&#xff09;和循環結構三種。 一、順序結構 如果程序不包含選擇結構或是循環結構&#xff0c;那么程序中的語句就是順序的逐條執行&#xff0c;這就是順序結構。 import java.util.Sc…

【 OpenGauss源碼學習 —— 列存儲(CStoreMemAlloc)】

列存儲&#xff08;CStoreMemAlloc&#xff09; 概述CStoreMemAlloc 類CStoreMemAlloc::Palloc 函數CStoreMemAlloc::AllocPointerNode 函數CStoreMemAlloc::FreePointerNode 函數CStoreMemAlloc::Repalloc 函數CStoreMemAlloc::PfreeCStoreMemAlloc::Register 函數CStoreMemAl…