AP引擎助力加速生產環境運行

来源:https://www.cnblogs.com/greatsql/p/18028715
-Advertisement-
Play Games

Rapid存儲引擎簡介 從GreatSQL 8.0.32-25版本開始,新增Rapid存儲引擎,該引擎使得GreatSQL能滿足聯機分析(OLAP)查詢請求。 Rapid引擎採用插件(Plugin)方式嵌入GreatSQL中,可以線上動態安裝或卸載。 Rapid引擎不會直接面對客戶端和應用程式,用戶 ...


file

Rapid存儲引擎簡介

從GreatSQL 8.0.32-25版本開始,新增Rapid存儲引擎,該引擎使得GreatSQL能滿足聯機分析(OLAP)查詢請求。

Rapid引擎採用插件(Plugin)方式嵌入GreatSQL中,可以線上動態安裝或卸載。

Rapid引擎不會直接面對客戶端和應用程式,用戶無需修改原有的數據訪問方式。它是一個無共用、記憶體化、混合列式存儲的查詢處理引擎,其設計目的是為了高性能的處理分析型查詢。

並且在TPC-H性能表現優異在32C64G測試機環境下,TPC-H 100G測試中22條SQL總耗時 僅需不到80秒

file

下麵是幾個不同TPC-H數據量級的壓縮率數據:

TPC-H倉庫大小 InnoDB引擎數據文件大小 Rapid引擎數據文件大小 壓縮率
TPC-H 1GB 2003026076 276574208 7.24
TPC-H 100GB 184570593436 28728373248 6.42
TPC-H 500GB 1167795142848 146723045376 7.96

經過GreatSQL社區的測試分析可以看出,相較於InnoDB存儲引擎,Rapid存儲引擎在存儲效率上獲得了極大提升。在存放相同的數據集時,Rapid的數據文件所需要的空間僅為InnoDB的6~7分之1,大約 降低了85% 左右。

真實生產案例測試

為了全面驗證AP引擎的性能提升,我們成功獲取了真實生產環境下的SQL語句、表結構以及經過脫敏處理的數據。在此,特別感謝潲同學和貴司的協助!

測試環境介紹

本次測試採用的環境是 Arch Linux x86_64,機器配置為12C15G

$ uname -a
Linux myarch 6.6.3-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 29 Nov 2023 00:37:40 +0000 x86_64 GNU/Linux
$ cat /proc/cpuinfo | grep "processor" | wc -l
12
$  free -h
     total
Mem: 15Gi

採用的GreatSQL版本為 GreatSQL 8.0.32-25 版本

$ mysql --version           
mysql  Ver 8.0.32-25 for Linux on x86_64 (GreatSQL, Release 25, Revision 79f57097e3f)

真實生產SQL

展示即將進行測試的生產SQL(這裡不深入討論該SQL是否存在優化的可能性):

select c.id, c.dept_id, c.user_id, c.type, c.source, c.charge_no, c.amount, c.from_bank, c.to_bank, c.receipt,c.status, c.remark, c.create_by, c.create_time, c.update_by, c.update_time,c.reason,c.fr_no
, d.dept_name, dt.company_name, cp.company_name  
from charge c
left join dept d on c.dept_id = d.dept_id
left join user u on c.user_id = u.user_id
left join dept_tax dt on c.dept_id = dt.dept_id
left join dept_info di on c.dept_id = di.dept_id
left join company_bank cb on di.sign_cbid = cb.id
left join company cp on cb.company_id = cp.company_id
limit 3313445,10;

真實生產表結構

生產SQL涉及7張表,我們將逐一展示每張表的表結構。為了保護隱私,我們對部分欄位進行了脫敏處理以及一些微調

dept表

CREATE TABLE `dept` (
  `dept_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `parent_id` bigint(20) DEFAULT '0',
  `ancestors` varchar(50) DEFAULT '',
  `dept_name` varchar(30) DEFAULT '',
......
  `create_time` datetime DEFAULT NULL,
  `update_by` varchar(64) DEFAULT '',
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部門表'

user表

CREATE TABLE `user` (
  `user_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `dept_id` bigint(20) DEFAULT NULL,
  `fans_id` bigint(20) DEFAULT NULL,
  `login_name` varchar(30) NOT NULL,
  `user_name` varchar(30) NOT NULL,
  `alias` varchar(100) DEFAULT NULL,
  `user_type` varchar(2) DEFAULT '00',
  `email` varchar(50) DEFAULT '',
  `phonenumber` varchar(11) DEFAULT '',
  `sex` char(1) DEFAULT '0',
......
  `create_by` varchar(64) DEFAULT '',
  `create_time` datetime DEFAULT NULL,
  `update_by` varchar(64) DEFAULT '',
  `update_time` datetime DEFAULT NULL,
  `remark` varchar(500) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶表'

dept_tax表

CREATE TABLE `dept_tax` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `dept_id` bigint(20) NOT NULL,
  `company_name` varchar(50) NOT NULL,
  `tax_no` varchar(50) DEFAULT NULL,
  `tax_type` varchar(30) DEFAULT NULL,
......
  `create_by` varchar(50) DEFAULT '',
  `create_time` datetime DEFAULT NULL,
  `update_by` varchar(50) DEFAULT '',
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='信息表'

dept_info表

CREATE TABLE `dept_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `dept_id` bigint(20) NOT NULL,
  `customer_id` bigint(20) DEFAULT NULL,
  `dept_type` char(1) DEFAULT '1',
  `industry_type` char(1) DEFAULT '0',
  `dept_flag` char(1) DEFAULT '1',
  `dept_kind` char(1) DEFAULT '0',
  `bus_scope` varchar(10) DEFAULT '1',
  `channel_id` bigint(20) DEFAULT NULL,
......
   PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='信息表'

company_bank表

CREATE TABLE `company_bank` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `company_id` bigint(20) DEFAULT NULL,
  `bank_name` varchar(50) DEFAULT NULL,
  `bank_card` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

company表

CREATE TABLE `company` (
  `company_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `company_name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`company_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

charge表

CREATE TABLE `charge` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `dept_id` bigint(20) NOT NULL,
  `user_id` bigint(20) DEFAULT NULL,
  `type` char(1) DEFAULT NULL,
......
  `create_time` datetime DEFAULT NULL,
  `update_by` varchar(50) DEFAULT '',
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

不深入探討SQL和表結構是否存在優化的可能性,只驗證AP引擎提升查詢測試。

載入數據

鑒於原始數據較為有限,為了更明顯地進行測試,我們為每張表生成了一些新數據,來看下各表數據和表空間大小是多少:

表名 數據量 表空間大小
dept 11000 10M
user 100000 31M
dept_tax 10000 88M
charge 1000000 184M
company 1000 160K
dept_info 10000 11M
company_bank 1000 176K

未改造測試

待測試的SQL語句:

select c.id, c.dept_id, c.user_id, c.type, c.source, c.charge_no, c.amount, c.from_bank, c.to_bank, c.receipt,c.status, c.remark, c.create_by, c.create_time, c.update_by, c.update_time,c.reason,c.fr_no
, d.dept_name, dt.company_name, cp.company_name  
from _charge c
left join dept d on c.dept_id = d.dept_id
left join user u on c.user_id = u.user_id
left join dept_tax dt on c.dept_id = dt.dept_id
left join dept_info di on c.dept_id = di.dept_id
left join company_bank cb on di.sign_cbid = cb.id
left join company cp on cb.company_id = cp.company_id
limit 3313445,10;

先不使用AP引擎測試查詢五次:

測試次數 耗時
第一次 10 rows in set (12.64 sec)
第二次 10 rows in set (12.77 sec)
第三次 10 rows in set (12.60 sec)
第四次 10 rows in set (12.61 sec)
第五次 10 rows in set (12.59 sec)

可以看到五次測試結果都是穩定在12秒左右,平均耗時12.64/s:

file

使用Rapid引擎測試

啟用Rapid引擎

greatsql> INSTALL PLUGIN Rapid SONAME 'ha_rapid.so';

greatsql> SHOW PLUGINS;
+----------------------------------+----------+--------------------+----------------------+---------+
| Name                             | Status   | Type               | Library              | License |
+----------------------------------+----------+--------------------+----------------------+---------+
| binlog                           | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
...
| Rapid                            | ACTIVE   | STORAGE ENGINE     | ha_rapid.so          | GPL     |
+----------------------------------+----------+--------------------+----------------------+---------+
55 rows in set (0.00 sec)

加上Rapid輔助引擎

greatsql> ALTER TABLE dept SECONDARY_ENGINE = rapid;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
greatsql> ALTER TABLE user SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE charge SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE company SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE company_bank SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE dept_info SECONDARY_ENGINE = rapid;
greatsql> ALTER TABLE dept_tax SECONDARY_ENGINE = rapid;

查看建表DDL,發現增加了 SECONDARY_ENGINE=rapid

greatsql> SHOW CREATE TABLE _company\G
*************************** 1. row ***************************
       Table: company
Create Table: CREATE TABLE `company` (
  `company_id` bigint NOT NULL AUTO_INCREMENT COMMENT '序號ID',
  `company_name` varchar(100) DEFAULT NULL COMMENT '簽約主體',
  PRIMARY KEY (`company_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci SECONDARY_ENGINE=rapid
1 row in set (0.00 sec)

數據全量導入Rapid引擎中

greatsql> ALTER TABLE dept SECONDARY_LOAD;
greatsql> ALTER TABLE user SECONDARY_LOAD;
greatsql> ALTER TABLE charge SECONDARY_LOAD;
greatsql> ALTER TABLE company SECONDARY_LOAD;
greatsql> ALTER TABLE company_bank SECONDARY_LOAD;
greatsql> ALTER TABLE dept_info SECONDARY_LOAD;
greatsql> ALTER TABLE dept_tax SECONDARY_LOAD;

開始測試Rapid引擎

有兩種方式啟用Rapid引擎

方式一

-- 設置use_secondary_engine=ON的時候,為保證查詢語句能夠使用rapid,
-- 通常需要設置secondary_engine_cost_threshold = 0,或一個較小的閾值
SET use_secondary_engine = ON;
SET secondary_engine_cost_threshold = 0; 

方式二(不建議)

-- 修改會話變數,設置強制使用Rapid引擎
SET use_secondary_engine = FORCED;

-- 或執行SQL查詢時指定HINT
SELECT /*+ SET_VAR(use_secondary_engine=forced) */ ...省略 FROM from charge c;

先使用方案二,執行SQL查詢時指定HINT測試五次看看表現如何

待測試的SQL語句:

select /*+ SET_VAR(use_secondary_engine=forced) */ c.id, c.dept_id, c.user_id, c.type, c.source, c.charge_no, c.amount, c.from_bank, c.to_bank, c.receipt,c.status, c.remark, c.create_by, c.create_time, c.update_by, c.update_time,c.reason,c.fr_no
, d.dept_name, dt.company_name, cp.company_name
from _charge c
left join dept d on c.dept_id = d.dept_id
left join user u on c.user_id = u.user_id
left join dept_tax dt on c.dept_id = dt.dept_id
left join dept_info di on c.dept_id = di.dept_id
left join company_bank cb on di.sign_cbid = cb.id
left join company cp on cb.company_id = cp.company_id
limit 3313445,10;

同樣測試查詢五次:

測試次數 耗時
第一次 10 rows in set (0.48 sec)
第二次 10 rows in set (0.47 sec)
第三次 10 rows in set (0.46 sec)
第四次 10 rows in set (0.48 sec)
第五次 10 rows in set (0.46 sec)

可以看到Rapid引擎出手即是秒殺,平均耗時0.47/s:

file

改造前(平均耗時12.64/s)和改造後(平均耗時0.47/s)對比測試結果:

file

總體來說改造後約提升了26.9倍:

file

如果我們選擇使用HINT進行改造,就需要對原SQL語句進行相應修改。因此,我們將採用方案一來進行試驗

greatsql> SET use_secondary_engine = ON;
greatsql> secondary_engine_cost_threshold = 0;
# 查看下執行計劃
greatsql> explain select c.id, c.dept_id, c.user_id, c.type, c.source, c.charge_no, c.amount, c.from_bank, c.to_bank, c.receipt,c.status, c.remark, c.create_by, c.create_time, c.update_by, c.update_time,c.reason,c.fr_no , d.dept_name, dt.company_name, cp.company_name from charge c left join dept d on c.dept_id = d.dept_id left join user u on c.user_id = u.user_id left join dept_tax dt on c.dept_id = dt.dept_id left join dept_info di on c.dept_id = di.dept_id left join company_bank cb on di.sign_cbid = cb.id left join company cp on cb.company_id = cp.company_id limit 3313445,10\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: c
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 905486
     filtered: 100.00
        Extra: Using secondary engine RAPID # 證明用到RAPID引擎
# 下方省略,證明有用到RAPID引擎即可

可以看到預設的使用了RAPID引擎

數據導入

在上方我們執行過ALTER TABLE xxx SECONDARY_LOAD這個操作,會將InnoDB主引擎中的數據全量載入到Rapid引擎中,這個過程稱為全量導入。全量導入成功後,Rapid引擎中的數據是靜態的,當向主引擎表中繼續插入、刪除、修改數據時,並不會導入到Rapid引擎中。

那數據會更新會修改要怎麼辦呢?總不能每次都全量導入吧?

所以此時可以利用binlog特性,可以在全量導入成功後,啟動增量導入任務。增量任務會讀取自全量導入成功之後的binlog數據,將binlog解析並應用到rapid引擎中,這個過程稱為增量導入

不同於全量導入,增量導入會啟動一個常駐的後臺線程,實時讀取和應用增量binlog數據。

增量導入數據的限制和需求

在手冊上有介紹到增量導入數據的限制和需求,如下:

  1. 需要設置表名大小寫不敏感,即設置 lower_case_table_names = 1
  2. 需要開啟GTID模式,即設置 gtid_mode = ONenforce_gtid_consistency = ON
  3. 需要採用row格式的binlog event,不支持statement格式,即設置 binlog_format = ROW。增量任務運行過程中,檢測到statement的DML event,可能會報錯退出。
  4. 需要關閉GIPKs特性,即設置 sql_generate_invisible_primary_key = OFF。用戶表不能有 invisible primary key,如果表包含隱式不可見的主鍵,在全量導入過程中會報錯;同時也不支持用戶表中存在任何不可見列(invisible column)。
  5. 需要先對錶執行過一次全量導入後,才能啟動增量導入任務,否則任務啟動會報錯。
  6. 不支持 PARTIAL_UPDATE_ROWS_EVENT 類型的binlog,即不要設置 binlog_row_value_options = PARTIAL_JSON
  7. 不支持 CREATE TABLE SELECT 語句,增量任務運行過程中,檢測到該語句產生的binlog event時可能會報錯退出。
  8. 不支持XA事務,運行過程中檢查到XA事務會報錯退出。

開啟增量導入

增量導入有兩個系統函數分別是

  • START_SECONDARY_ENGINE_INCREMENT_LOAD_TASK() :啟動任務
  • STOP_SECONDARY_ENGINE_INCREMENT_LOAD_TASK():停止任務

執行SQL命令 SELECT START_SECONDARY_ENGINE_INCREMENT_LOAD_TASK() 即可啟動增量任務,根據函數返回信息可以確認是否任務啟動成功。如果啟動失敗,可以從錯誤日誌中查看具體失敗的原因。

該函數包含3個參數:

  • db_name,必選項,指定增量導入任務對應的資料庫名。
  • table_name,必選項,指定增量導入任務對應的數據表名。
  • gtid,可選項,指定開始增量導入任務的起始gtid_set值。預設不需要指定,任務會自動根據ALTER TABLE ... SECONDARY_LOAD 全量導入時刻的 gtid_executed 進行計算和判斷。
-- 對user表啟動增量導入任務
greatsql> SELECT START_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user');
+------------------------------------------------------------------+
| START_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user') |
+------------------------------------------------------------------+
| success                                                          |
+------------------------------------------------------------------+
1 row in set (0.00 sec)
-- 查看增量導入任務狀態
greatsql>  SELECT * FROM information_schema.SECONDARY_ENGINE_INCREMENT_LOAD_TASK\G
*************************** 1. row ***************************
           DB_NAME: aptest
        TABLE_NAME: user
        START_TIME: 2024-02-21 09:33:55
        START_GTID: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:1-3808
COMMITTED_GTID_SET: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:1-3821
         READ_GTID: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:3821
  READ_BINLOG_FILE: ./binlog.000023
   READ_BINLOG_POS: 596312770
             DELAY: 0
            STATUS: RUNNING
          END_TIME: 
              INFO: 
1 row in set (0.00 sec)

當然如果想停止也可以使用以下操作停止增量同步

greatsql>  SELECT STOP_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user');
greatsql> SELECT STOP_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user');
+-----------------------------------------------------------------+
| STOP_SECONDARY_ENGINE_INCREMENT_LOAD_TASK('aptest', 'user') |
+-----------------------------------------------------------------+
| success                                                         |
+-----------------------------------------------------------------+
1 row in set (0.21 sec)

greatsql> SELECT * FROM information_schema.SECONDARY_ENGINE_INCREMENT_LOAD_TASK\G
*************************** 1. row ***************************
           DB_NAME: aptest
        TABLE_NAME: user
        START_TIME: 2024-02-21 09:33:55
        START_GTID: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:1-3808
COMMITTED_GTID_SET: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:1-3821
         READ_GTID: 9548406d-8ff1-11ee-97ec-ec5c6826bca3:3821
  READ_BINLOG_FILE: ./binlog.000023
   READ_BINLOG_POS: 596312770
             DELAY: 60
            STATUS: NOT RUNNING
          END_TIME: 2024-02-21 09:35:46
              INFO: NORMAL EXIT
1 row in set (0.00 sec)

更多Rapid存儲引擎介紹請前往GreatSQL用戶手冊上查看 Rapid引擎(Rapid Engine)https://greatsql.cn/docs/8032-25/user-manual/5-enhance/5-1-highperf-rapid-engine.html

總結

對於在不改造SQL的前提下,查詢速度提升了 26.9倍 的這一結果,潲同學表示非常驚訝。然而,令人遺憾的是,他們尚未遷移到GreatSQL資料庫。因此,他目前正緊鑼密鼓地向總監提議,爭取儘快完成遷移並採用GreatSQL資料庫:)

目前Rapid存儲引擎已經開放測試了,歡迎各位來體驗測試~

GreatSQL手冊:https://greatsql.cn/docs/8032-25/

GreatSQL下載地址:https://gitee.com/GreatSQL/GreatSQL/releases/tag/GreatSQL-8.0.32-25

Enjoy GreatSQL

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

-Advertisement-
Play Games
更多相關文章
  • 迪文屏TA指令開發_開機動畫 1. 新建項目 新建一個空白文件夾,點擊新建工程之後選擇新建文件夾地址即可 創建完成之後,文件夾結構如下: 2. 導入背景圖片素材 說是設置開機動畫,實際上是通過多個背景圖片的連續播放實現的動畫效果 點擊加號鍵,可以直接選中所有的背景圖片素材進行一鍵導入 3. 設置控制項 ...
  • 介紹 Windows Server 2025 為 Hyper-V 帶來了多項增強功能和新的存儲特性,主要用於優化虛擬機的運行體驗。這些新特性涵蓋 GPU 虛擬化、新的 ReFS 去重功能,以及在非 AD 域的集群上進行虛擬機實時遷移。 雲桌面方案的用戶最關心的GPU-P的技術也將在Windows S ...
  • 背景 在GreatSQL主從複製環境中,有時候可能會出現一些誤操作,將本應該寫入到主庫的數據寫入到了從庫,導致主從數據不一致,影響數據同步。是否可以將寫入從庫的數據同步寫入主庫呢? 測試環境 角色 IP地址 資料庫開放埠 版本 主庫 192.168.137.179 3308 GreatSQL 8. ...
  • 本文分享自華為雲社區《GaussDB資料庫SQL系列-游標管理》,作者:酷哥。 一、前言 在資料庫中,游標(cursor)是一種非常重要的工具,用於在資料庫查詢結果集中進行定位和操作。游標提供了一種在多行數據結果集中逐行處理每一行的機制,允許開發人員對每一行的數據進行操作,如檢索、過濾、修改等。本文 ...
  • <!-- 密碼突然登錄不上MySQL了,久了也不曉得是不是密碼不正確...只能改密碼...一年難得碰一次,感覺每次總有莫名其妙的問題 --> <!-- 修改方案只找到一個,就是無密碼驗證開啟mysql服務,然後登錄,設置新密碼 --> <!-- mysql版本不同有些命令無效,大概分高低兩版本 -- ...
  • 一、Mysql 1、什麼是資料庫? (1)資料庫(database) 資料庫是保存有組織的數據的容器(通常是一個文件或一組文件),資料庫是DBMS(資料庫管理系統或資料庫軟體)創建和操作的容器; (2)表、列、行、主鍵、數據類型分別是什麼 ①表:表是由某些特定的欄位組成的統一的結構化的存儲數據的容器 ...
  • Docker安裝Aseropike 找了一大堆,發現Aserospike的資料太少了(主要是官方文檔,好像沒有中文的) 看了很多的安裝部署,一直不滿意,於是直接上Docker。這樣就簡單多了。 Docker安裝 我看很多人都直接在Docker服務,但是最簡單的還是直接下載Docker Desktop ...
  • 歡迎閱讀袋鼠雲09期產品功能更新報告。在此期報告中,我們秉持創新與優化並重的理念,對產品進行了深度打磨與全面升級。每一處細節的改進,都是我們對卓越品質的不懈追求,期待這些新功能能助力您的業務運營與發展,讓數字化轉型之路更加暢通無阻。 以下為袋鼠雲產品功能更新報告09期內容,更多探索,請繼續閱讀。 離 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...