1. 程式人生 > 程式設計 >網路與MySQL的速度與激情

網路與MySQL的速度與激情

這兩天在看MySQL的經典書籍《高效能MySQL》,對其中的資料型別選擇產生了興趣。同時想起前陣子看到的高併發流量的瓶頸,和以前面試時問的關於MySQL通過索引查詢資料時耗時的級別。因此決定來動手算算這些時間。

基本資料型別

對於計算機儲存,我們知道,計算機內部資料儲存的最小單位是“bit位元位”,一個位元位可以儲存0或者1。但畢竟一個位元位儲存的資訊有限,所以使用8個bit來表示1個位元組Byte,Byte位元組是計算機中資料處理的基本單位,8個bit能表示2^8=256個資訊,儲存英文字母和其他ASCII碼足夠了。以下是Java和MySQL的一些基本資料型別儲存佔用空間。

Java和MySQL基本資料型別

MySQL儲存

這裡單講字元型別varchar,MySQL儲存varchar時使用頭1~2個位元組標記varchar的長度,故按理說varchar最長能達到(2^16-1)-2=65532個字元,但別忘記了MySQL規定每一行的最大長度是(2^16-1)=65535個位元組,而資料庫一般使用utf8編碼,故每個中文varchar字元儲存為3個位元組,因此儲存全中文varchar的最大長度可以定義為((2^16-1)-2)/3=21844,即varchar(21844),當然這是在不考慮其他列的情況下。

MySQL的查詢速度

對於innodb儲存引擎,我們知道其預設的索引資料結構是B+Tree,檔案系統和記憶體中是按頁存放和讀取的,每頁16K,一般的表大概都存放1~3層B+Tree,那麼我們來計算一下,3層的B+Tree大概能存放多少資料呢?

B+Tree

按照B+Tree高度為3、⻚為16K、⼀行記錄1K、主鍵bigint佔8位元組來計算,非葉⼦子可帶16K/(8+6指標) =1170個葉子節點,則最⼤大數量量為1170*1170*16 = 2.19千萬行資料。 獲取每一層,MySQL需要一次磁碟IO,而一般的磁碟1秒大概能進行100次IO,故如果是一層索引結構,那麼通過主鍵查詢只需要0.01s。如下圖。

主鍵查詢
空口無憑,怎麼證明磁碟IO大概是1秒100次IO呢?我們知道,磁碟存取資料時間=尋道時間+旋轉時間,而旋轉延遲取決於磁碟轉速,通常使用磁碟旋轉一週所需時間的1/2表示。比如,7200轉的磁碟平均旋轉延遲大約為(1000ms/s*60s/min)/(7200r/min)/2=4.17ms/r,即每一轉是4.17毫秒,即一次IO的旋轉時間大概4.17毫秒,因此,理論上可以計算出磁碟的最大IOPS(IO Per Second)。假設磁碟平均物理尋道時間為3ms,磁碟轉速為7200,則磁碟IOPS理論最大為,IOPS=1000/(3+1000*60/7200/2)=140。

QPS與網站的併發量級

說完MySQL通過索引查詢資料的時間,接下來看看web網站的幾個併發量級。假設現在一臺伺服器上有一個restful介面,該介面請求和返回引數最大為10KB。以下是阿里雲的頻寬費用,頻寬表示出站速率。

阿里雲頻寬

百兆頻寬 -- 1250QPS

單機單介面10KB大小,百兆頻寬意味著網站出口的實際頻寬是100Mb/8b/B=12.5MB,能抗得住的最高併發為(100Mb/8b/B)/10KB=1250。

C10K -- 10KQPS

C10K就是Client 10000問題,即「在同時連線到伺服器的客戶端數量超過10000個的環境中,即便硬體效能足夠,依然無法正常提供服務」,但是據說淘寶在12年雙11的時候,QPS已經能達到40K了。

DB極限型 -- 15100QPS

這只是假設,如上,我們分析瞭如果資料庫走的是聚集索引,那麼其每次IO的時間大概是0.01s,MySQL預設的最大連線數為151,因此一次性可以處理151個請求,則qps為151*(1s/0.01s)=15100。當然,這是極端的狀態,然而併發到達151個併發,MySQL不可能還能保持在0.01s的IO.

參考資料

  1. Web網站的幾個併發量級:www.cnblogs.com/aspirant/p/…
  2. 一些高併發的資料:colobu.com/2015/04/30/…