當前位置:
首頁 > 知識 > MySQL挑戰:10萬連接數

MySQL挑戰:10萬連接數

MySQL挑戰:10萬連接數

在這篇文章中,我想探索一種與MySQL建立100,000個連接的方法。不限於空閑連接,還有執行查詢功能的連接。

你可能會問,使用MySQL的時候真的有必要建立100,000個連接嗎?雖然看起來有點過於追求極致,我還是在客戶部署的時候看到很多不同的設計方案。有的部署了應用程序連接池,每一個連接池中有100個應用服務和1000個連接。有的應用程序使用了一種很糟糕的技術,「在查詢慢時重連或重用」。這有可能會導致雪球效應,並在幾秒鐘內建立數千個MySQL連接。

所以現在我想設置一個超出預期的目標,看看能否實現。

配置

為此我將使用以下硬體配置:

由packet.net提供的裸機伺服器,實例大小:c2.medium.x86

物理內核 @ 2.2 GHz (1 X AMD EPYC 7401P)

內存: 64 GB of ECC RAM

磁碟: INTEL? SSD DC S4500, 480GB

這是一個伺服器級的 SATA SSD。

我們將使用到5台主機,下面作出解釋,一個用於MySQL伺服器的主機,以及四個用於客戶端連接的主機。

在伺服器上,我將使用帶有線程池插件的Percona Server for MySQL 8.0.13-4。這個插件可以支持數千個資料庫連接。

初始化伺服器設置

網路設置(Ansible格式):

MySQL挑戰:10萬連接數

這些是推薦用於10Gb網路和高並發工作負載的典型設置。

systemd限制設置:

MySQL挑戰:10萬連接數

還有my.cnf文件中MySQL相關設置:

MySQL挑戰:10萬連接數

客戶端使用sysbench 0.5版本而不是1.0.x版本,原因我們將在下面解釋。

工作負載配置

MySQL挑戰:10萬連接數

第一步 10,000連接數

這一步很簡單,沒有太多的事情需要處理。我們可以只用一個客戶端實現,但是你有可能會遇到下面的錯誤:

MySQL挑戰:10萬連接數

這個是由於打開文件數限制引起的,也叫做TCP/IP套接字連接限制。可以在客戶端設置 ulimit -n 100000 來解決。

我們能觀察到的:

MySQL挑戰:10萬連接數

第二步 25,000連接數

使用25,000個連接的時候,在MySQL端會看到錯誤信息:

MySQL挑戰:10萬連接數

如果你查找這個錯誤的信息的話,你可能會看到這篇文章:

https://www.percona.com/blog/2013/02/04/cant_create_thread_errno_11/

但是這並不能解決我們的問題,因為我們已經把限制設置的足夠高了:

MySQL挑戰:10萬連接數

我們是從這裡開始使用線程池功能的:https://www.percona.com/doc/percona-server/8.0/performance/threadpool.html

在my.cnf中增加:

MySQL挑戰:10萬連接數

並重啟 Percona 伺服器。

列印結果:

MySQL挑戰:10萬連接數

現在還是相同的吞吐量,但是實際上95%的響應時間已經從3690毫秒優化到979毫秒(由於使用了線程池)。

第三步 50,000連接數

這是目前我們遇到的最大的挑戰。首先,在嘗試從sysbench中獲取50,000個連接的時候遇到了以下錯誤:

MySQL挑戰:10萬連接數

Error(99)是一個很隱蔽的錯誤,它表示:無法分配請求地址。

它是由應用程序可以打開的埠限制所觸發,我的操作系統默認情況下是:

MySQL挑戰:10萬連接數

這表示有28231個埠可用(60999減32768),或者說是與給定IP地址所能建立的TCP連接的埠數限制。

你可以在客戶端和服務端上使用一個更大的範圍來擴展這些埠。

MySQL挑戰:10萬連接數

這給我們提拱了61000個連接,但是已經非常接近一個IP地址的連接限制了(最大埠號65535)。關鍵點在於,如果我們想要更多的連接數,那麼則需要為MySQL伺服器分配更多的IP地址。為了實現100,000連接數,我將在運行MySQL的伺服器上使用兩個IP地址。

在整理出埠範圍後,sysbench又拋出了以下問題

MySQL挑戰:10萬連接數

這是sysbench的內存分配問題(即lua子系統)。Sysbench只能為32,351個連接分配內存,這個問題在sysbench 1.0.x版本中尤為嚴重。

Sysbench 1.0.x的局限

Sysbench 1.0.x使用了一套不同的Lua JIT(Just In Time,即時編譯技術),甚至在連接數達到4000的時候就會產生內存問題,所以使用Sysbench 1.0.x想要超過4000連接數都是不可能的。

因此,與Percona Server相比,sysbench會更早達到連接數瓶頸。我們需要使用更多的sysbench客戶端來實現更多的連接。如果sysbench的連接上限是32,351,那麼至少要使用4個sysbench客戶端才能達到100,000個連接。

我使用2台伺服器(每個伺服器運行單獨的sysbench)實現50,000個連接,每個sysbench上運行25,000個線程。

每個sysbench上執行結果如下:

MySQL挑戰:10萬連接數

然而同樣的吞吐量(總共 16794 * 2 = 33588 tps)的情況下,有95%的響應時間都翻了一倍。這是可以預見的,因為相比於25,000個基準測試連接,我們使用的連接數是原來的兩倍。

第三步 75,000連接數

我們將使用3個sysbench伺服器來實現75,000個連接,每個伺服器上運行25,000個連接。

每個sysbench的運行結果:

MySQL挑戰:10萬連接數

第四步 100,000連接數

實現連接數從75k到100k並沒有什麼大的變化,我們只需要啟動一個額外的伺服器並啟動sysbench就可以了。對於100,000個連接,我們需要四個sysbench伺服器,每一個伺服器顯示:

MySQL挑戰:10萬連接數

所以相同吞吐量(總共 8065 * 4 = 32260 tps)時,有95%的相應時間為3405ms。

一個很重要的點是:建立100k個連接並使用線程池,95%的響應時間甚至比不帶線程池的10k個連接更快。線程池使得Percona Server更有效的管理資源並提供更快的響應時間。

總結

MySQL實現10萬連接數是完全可行的,而且我相信我們還可以更進一步。這裡有三個組件可以幫助我們實現目標:

  • Percona Server的線程池

  • 適當調整網路限制

  • 伺服器主機使用多個IP地址(一個IP地址支持大約60k個連接)

附錄:my.cnf

MySQL挑戰:10萬連接數

英文原文:https://www.percona.com/blog/2019/02/25/mysql-challenge-100k-connections/
譯者:敦偉

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python部落 的精彩文章:

針對Pythoner的ES6速查表

TAG:Python部落 |