isql 測試mysql連接_[libco] 協程庫學習,測試連接 mysql

歷史原因,一直使用 libev 作為服務底層;異步框架雖然性能比較高,但新人學習和使用門檻非常高,而且串行的邏輯被打散為狀態機,這也會嚴重影響生產效率。

用同步方式實現異步功能,既保證了異步性能優勢,又使得同步方式實現源碼思路清晰,容易維護,這是協程的優勢。帶著這樣的目的學習微信開源的一個輕量級網絡協程庫:libco 。

1. 概述

libco 是輕量級的協程庫,看完下面幾個帖子,應該能大致搞懂它的工作原理。

2. 問題

帶著問題學習 libco:

搞清這幾個概念:阻塞,非阻塞,同步,異步,鎖。

協程是什么東西,與進程和線程有啥關系。

協程解決了什么問題。

協程在什么場景下使用。

協程切換原理。

協程切換時機。

協程需要上鎖嗎?

libco 主要有啥功能。(協程管理,epoll/kevent,hook)

3. libco 源碼結構布局

將 libco 的源碼結構展開,這樣方便理清它的內部結構關系。

1aed2774b60e98c377e0c64f28085c19.png

4. mysql 測試

測試目標:測試 libco 協程性能,以及是否能將 mysqlclient 同步接口進行異步改造。

測試系統:CentOS Linux release 7.7.1908 (Core)

測試源碼:github。

9f116947723b9334b27753f44a61bfcb.png

4.1. 測試源碼

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58/* 數據庫信息。 */

typedef struct db_s {

std::string host;

int port;

std::string user;

std::string psw;

std::string charset;

} db_t;

/* 協程任務。 */

typedef struct task_s {

int id; /* 任務 id。 */

db_t* db; /* 數據庫信息。 */

MYSQL* mysql; /* 數據庫實例指針。 */

stCoRoutine_t* co; /* 協程指針。 */

} task_t;

/* 協程處理函數。 */

void* co_handler_mysql_query(void* arg) {

co_enable_hook_sys();

...

/* 同步方式寫數據庫訪問代碼。 */

for (i = 0; i < g_co_query_cnt; i++) {

g_cur_test_cnt++;

/* 讀數據庫 select。 */

query = "select * from mytest.test_async_mysql where id = 1;";

if (mysql_real_query(task->mysql, query, strlen(query))) {

show_error(task->mysql);

return nullptr;

}

res = mysql_store_result(task->mysql);

mysql_free_result(res);

}

...

}

int main(int argc, char** argv) {

...

/* 協程個數。 */

g_co_cnt = atoi(argv[1]);

/* 每個協程 mysql query 次數。 */

g_co_query_cnt = atoi(argv[2]);

/* 數據庫信息。 */

db = new db_t{"127.0.0.1", 3306, "root", "123456", "utf8mb4"};

for (i = 0; i < g_co_cnt; i++) {

task = new task_t{i, db, nullptr, nullptr};

/* 創建協程。 */

co_create(&(task->co), NULL, co_handler_mysql_query, task);

/* 喚醒協程。 */

co_resume(task->co);

}

/* 循環處理協程事件邏輯。 */

co_eventloop(co_get_epoll_ct(), 0, 0);

...

}

5. hook

在 Centos 系統,查看 hook 是否成功,除了測試打印日志,其實還有其它比較直觀的方法。

5.1. strace

用 strace 查看底層的調用,我們看到 mysql_real_connect 內部的 connect,被 hook 成功,connect 前,被替換為 libco 的 connect 了。socket 在 connect 前,被修改為 O_NONBLOCK 。

1

2

3

4

5# strace -s 512 -o /tmp/libco.log ./test_libco 1 1

socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4

fcntl(4, F_GETFL) = 0x2 (flags O_RDWR)

fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0

connect(4, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now inprogress)

5.2. gdb

上神器 gdb,在 co_hook_sys_call.cpp 文件的 read 和 write 函數下斷點。

命中斷點,查看函數調用堆棧,libco 在 Centos 系統能成功 hook 住 mysqlclient 的阻塞接口。

1

2

3

4

5

6

7

8

9

10#0 read (fd=fd@entry=9, buf=buf@entry=0x71fc30, nbyte=nbyte@entry=19404) at co_hook_sys_call.cpp:299

#1 0x00007ffff762b30a in read (__nbytes=19404, __buf=0x71fc30, __fd=9) at /usr/include/bits/unistd.h:44

#2 my_read (Filedes=Filedes@entry=9, Buffer=Buffer@entry=0x71fc30 "", Count=Count@entry=19404, MyFlags=MyFlags@entry=0)

at /export/home/pb2/build/sb_0-37309218-1576675139.51/rpm/BUILD/mysql-5.7.29/mysql-5.7.29/mysys/my_read.c:64

#3 0x00007ffff7624966 in inline_mysql_file_read (

src_file=0x7ffff78424b0 "/export/home/pb2/build/sb_0-37309218-1576675139.51/rpm/BUILD/mysql-5.7.29/mysql-5.7.29/mysys/charset.c",

src_line=383, flags=0, count=19404, buffer=0x71fc30 "", file=9)

at /export/home/pb2/build/sb_0-37309218-1576675139.51/rpm/BUILD/mysql-5.7.29/mysql-5.7.29/include/mysql/psi/mysql_file.h:1129

#4 my_read_charset_file (loader=loader@entry=0x7ffff7ed7270, filename=filename@entry=0x7ffff7ed7320 "/usr/share/mysql/charsets/Index.xml",

myflags=myflags@entry=0) at /export/home/pb2/build/sb_0-37309218-1576675139.51/rpm/BUILD/mysql-5.7.29/mysql-5.7.29/mysys/charset.c:383

6. 壓測結果

從測試結果看,單進程單線程,多個協程是“同時”進行的,“并發”量也隨著協程個數增加而增加,跟測試預期一樣。

這里只測試協程的”并發性”,實際應用應該是用戶比較多,每個用戶的 sql 命令比較少的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14# ./test_libco 1 10000

id: 0, testcnt: 10000, cur spend time: 1.778823

total cnt: 10000, total time: 1.790962, avg: 5583.591448

# ./test_libco 2 10000

id: 0, testcnt: 10000, cur spend time: 2.328348

id: 1, testcnt: 10000, cur spend time: 2.360431

total cnt: 20000, total time: 2.373994, avg: 8424.620726

# ./test_libco 3 10000

id: 0, testcnt: 10000, cur spend time: 2.283759

id: 2, testcnt: 10000, cur spend time: 2.352147

id: 1, testcnt: 10000, cur spend time: 2.350272

total cnt: 30000, total time: 2.370038, avg: 12658.024719

7. mysql 連接池

用 libco 共享棧簡單造了個連接池,在 Linux 壓力測試單進程 10w 個協程,每個協程讀 10 個 sql 命令(相當于 1000w 個包),并發處理能力 8k/s,在可接受范圍內。

eea5ec44602de339927cbeda93fc634f.png

1

2# ./test_mysql_mgr r 100000 10

total cnt: 1000000, total time: 125.832877, avg: 7947.048692

壓測源碼(github)。

mysql 連接池簡單實現(github)。

壓測發現每個 mysql 連接只能獨立運行在固定的協程里,否則大概率會出現問題。

libco hook 技術雖然將 mysqlclient 阻塞接口設置為非阻塞,但是每個 mysqlclient 連接,必須一次只能處理一個命令,像同步那樣!非阻塞只是方便協程切換到其它空閑協程進行工作,充分利用原來阻塞等待的時間。而且 mysqlclient 本來就是按照同步的邏輯來寫的,一個連接,一次只能處理一個包,不可能被你設置為非阻塞后,一次往 mysql server 發 N 個包,這樣肯定會出現不可預料的問題。

libco 協程切換成本不高,主要是 mysqlclient 耗費性能,參考火焰圖。

壓測頻繁地申請內存空間也耗費了不少性能(參考火焰圖的 __brk),嘗試添加 jemalloc 優化,發現 jemalloc 與 libco 一起用在 Linux 竟然出現死鎖!!!

b03dae7c799af29a320620d16e77b5a7.png

8. 小結

通過學習其他大神的帖子,走讀源碼,寫測試代碼,終于對協程有了比較清晰的認知。

測試 libco,Centos 功能正常,但 MacOS 下不能成功 Hook 住 mysqlclient 阻塞接口。

libco 是輕量級的,它主要應用于高并發的 IO 密集型場景,所以你看到它綁定了多路復用模型。

雖然測試效果不錯,如果你考慮用 libco 去造一個 mysql 連接池,還有不少工作要做。

libco 很不錯,所以我選擇 golang 🐶。

9. 參考

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

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

相關文章

什么是數據倉庫,何時以及為什么要考慮一個

The term “Data Warehouse” is widely used in the data analytics world, however, it’s quite common for people who are new with data analytics to ask the above question.術語“數據倉庫”在數據分析領域中被廣泛使用&#xff0c;但是&#xff0c;對于數據分析新手來…

安裝好MongoDB,但服務中沒有MongoDB服務的解決辦法

以管理員身份打開CMD&#xff0c;添加路徑添加服務即可 winX 然后再選Amongod -dbpath "D:\MongoDB\Server\3.6\data\db" -logpath "D:\MongoDB\Server\3.6\data\log\mongo.log" -install -serviceName "MongoDB"轉載于:https://www.cnblogs.com…

DRF數據驗證+數據存儲

1.驗證數據的自定義類 class BooksDRFt(serializers.ModelSerializer):class Meta:model Bookfields __all__#要驗證的字段author serializers.CharField(requiredFalse)#要驗證的字段name serializers.CharField(min_length2, error_messages{required: 不能為空, min_len…

mysql變量 exec_MySQL slave_exec_mode 參數說明

背景&#xff1a;今天無意當中看到參數slave_exec_mode&#xff0c;從手冊里的說明看出該參數和MySQL復制相關&#xff0c;是可以動態修改的變量&#xff0c;默認是STRICT模式(嚴格模式)&#xff0c;可選值有IDEMPOTENT模式(冪等模式)。設置成IDEMPOTENT模式可以讓從庫避免1032…

C#word

主要功能為根據word模板生成word報表文檔,注意引用Interop.Word.dll;首先要生成word程序對象Word.Application app new Word.Application();根據模板文件生成新文件框架File.Copy(TemplateFile, FileName);生成documnet對象ord.Document doc new Word.Document(); 打開…

機器學習kaggle競賽實戰-泰坦尼克號

數據展示 首先登kaggle 下載泰坦尼克訓練相關數據 import pandas as pd import numpy as np data pd.read_csv(train.csv) print(data.shape) print(data.head) train data[:800] test data[800:] print(train.shape) print(test.shape)選擇特征 selected_features [Pcl…

上海大都會 H.A Simple Problem with Integers

題目描述 You have N integers A1, A2, ... , AN. You are asked to write a program to receive and execute two kinds of instructions: C a b means performing Ai (Ai2 mod 2018) for all Ai such that a ≤ i ≤ b.Q a b means query the sum of Aa, Aa1, ..., Ab. Note…

探索性數據分析入門_入門指南:R中的探索性數據分析

探索性數據分析入門When I started on my journey to learn data science, I read through multiple articles that stressed the importance of understanding your data. It didn’t make sense to me. I was naive enough to think that we are handed over data which we p…

用Javascript代碼實現瀏覽器菜單命令(以下代碼在 Windows XP下的瀏覽器中調試通過

每當我們看到別人網頁上的打開、打印、前進、另存為、后退、關閉本窗口、禁用右鍵等實現瀏覽器命令的鏈接&#xff0c;而自己苦于不能實現時&#xff0c;是不是感到很遺憾&#xff1f;是不是也想實現&#xff1f;如果能在網頁上能實現瀏覽器的命令&#xff0c;將是多么有意思的…

mysql程序設計教程_MySQL教程_編程入門教程_牛客網

MySQL 索引MySQL索引的建立對于MySQL的高效運行是很重要的&#xff0c;索引可以大大提高MySQL的檢索速度。打個比方&#xff0c;如果合理的設計且使用索引的MySQL是一輛蘭博基尼的話&#xff0c;那么沒有設計和使用索引的MySQL就是一個人力三輪車。拿漢語字典的目錄頁(索引)打比…

學習筆記整理之StringBuffer與StringBulider的線程安全與線程不安全

關于線程和線程不安全&#xff1a; 概述 編輯 如果你的代碼所在的進程中有多個線程在同時運行&#xff0c;而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的&#xff0c;而且其他的變量的值也和預期的是一樣的&#xff0c;就是線程安全的。或者說…

python web應用_為您的應用選擇最佳的Python Web爬網庫

python web應用Living in today’s world, we are surrounded by different data all around us. The ability to collect and use this data in our projects is a must-have skill for every data scientist.生活在當今世界中&#xff0c;我們周圍遍布著不同的數據。 在我們的…

NDK-r14b + FFmpeg-release-3.4 linux下編譯FFmpeg

下載資源 官網下載完NDK14b 和 FFmpeg 下載之后&#xff0c;更改FFmpeg 目錄下configure問價如下&#xff1a; SLIBNAME_WITH_MAJOR$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF) LIB_INSTALL_EXTRA_CMD$$(RANLIB)"$(LIBDIR)/$(LIBNAME)" SLIB_INSTALL_NAME$(SLI…

C# WebBrowser自動填表與提交

C# WebBrowser自動填表與提交 默認分類 2007-04-18 15:47:17 閱讀57 評論0 字號&#xff1a;大中小 訂閱 要使我們的WebBrowser具有自動填表、甚至自動提交的功能&#xff0c;并不困難。   假設有一個最簡單的登錄頁面&#xff0c;輸入用戶名密碼&#xff0c;點“登錄”…

html中列表導航怎么和圖片對齊_HTML實戰篇:html仿百度首頁

本篇文章主要給大家介紹一下如何使用htmlcss來制作百度首頁頁面。1)制作頁面所用的知識點我們首先來分析一下百度首頁的頁面效果圖百度首頁由頭部的一個文字導航&#xff0c;中間的一個按鈕和一個輸入框以及下邊的文字簡介和導航組成。我們這里主要用到的知識點就是列表標簽(ul…

C# 依賴注入那些事兒

原文地址&#xff1a;http://www.cnblogs.com/leoo2sk/archive/2009/06/17/1504693.html 里面有一個例子差了些代碼&#xff0c;補全后貼上。 3.1.3 依賴獲取 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml;//定義…

asp.net core Serilog的使用

先貼上關于使用這個日志組件的一些使用方法&#xff0c;等有時間了在吧官方的文檔翻譯一下吧&#xff0c;現在真是沒時間。 Serilog在使用上主要分為兩大塊&#xff1a; 第一塊是主庫&#xff0c;包括Serilog以及Serilog.AspNetCore&#xff0c;如果導入后一個的話會自動導入前…

在FAANG面試中破解堆算法

In FAANG company interview, Candidates always come across heap problems. There is one question they do like to ask — Top K. Because these companies have a huge dataset and they can’t always go through all the data. Finding tope data is always a good opti…

android webView的緩存機制和資源預加載

android 原生使用WebView嵌入H5頁面 Hybrid開發 一、性能問題 android webview 里H5加載速度慢網絡流量大 1、H5頁面加載速度慢 渲染速度慢 js解析效率 js本身的解析過程復雜、解析速度不快&#xff0c;前端頁面設計較多的js代碼文件 手機硬件設備的性能 機型多&#xff0c;…

mysql springboot 緩存_Spring Boot 整合 Redis 實現緩存操作

摘要: 原創出處 www.bysocket.com 「泥瓦匠BYSocket 」歡迎轉載&#xff0c;保留摘要&#xff0c;謝謝&#xff01;『 產品沒有價值&#xff0c;開發團隊再優秀也無濟于事 – 《啟示錄》 』本文提綱一、緩存的應用場景二、更新緩存的策略三、運行 springboot-mybatis-redis 工程…