資料庫並發連接
MySQL伺服器的最大並發連接數是16384。
受伺服器配置,及網路環境等制約,實際伺服器支持的並發連接數會小一些。主要決定因素有:
1、伺服器CPU及內存的配置。
2、網路的帶寬。互聯網連接中上行帶寬的影響尤為明顯。
(1)資料庫並發連接擴展閱讀:
優化資料庫結構:
組織資料庫的schema、表和欄位以降低I/O的開銷,將相關項保存在一起,並提前規劃,以便隨著數據量的增長,性能可以保持較高的水平。
設計數據表應盡量使其佔用的空間最小化,表的主鍵應盡可能短。·對於InnoDB表,主鍵所在的列在每個輔助索引條目中都是可復制的,因此如果有很多輔助索引,那麼一個短的主鍵可以節省大量空間。
僅創建需要改進查詢性能的索引。索引有助於檢索,但是會增加插入和更新操作的執行時間。
InnoDB的ChangeBuffering特性:
InnoDB提供了changebuffering的配置,可減少維護輔助索引所需的磁碟I/O。大規模的資料庫可能會遇到大量的表操作和大量的I/O,以保證輔助索引保持最新。當相關頁面不在緩沖池裡面時,InnoDB的changebuffer將會更改緩存到輔助索引條目。
從而避免因不能立即從磁碟讀取頁面而導致耗時的I/O操作。當頁面被載入到緩沖池時,緩沖的更改將被合並,更新的頁面之後會刷新到磁碟。這樣做可提高性能,適用於MySQL5.5及更高版本。
② 如何增加mysql資料庫並發數
現象
Sysbench對MySQL進行壓測, 並發數過大(>5k)時, Sysbench建立連接的步驟會超時.
猜想
猜想: 直覺上這很簡單, Sysbench每建立一個連接, 都要消耗一個線程, 資源消耗過大導致超時.
驗證: 修改Sysbench源碼, 調大超時時間, 仍然會發生超時.
檢查環境
猜想失敗, 回到常規的環境檢查:
MySQL error log 未見異常.
syslog 未見異常.
tcpmp 觀察網路包未見異常, 連接能完成正常的三次握手; 只觀察到在出問題的連接中, 有一部分的TCP握手的第一個SYN包發生了重傳, 另一部分沒有發生重傳.
自己寫一個簡單的並發發生器, 替換sysbench, 可重現場景. 排除sysbench的影響
檢查MySQL堆棧未見異常, 彷彿MySQL在應用層沒有看到新連接進入.
通過strace檢查MySQL, 發現accept()調用確實沒有感知到新連接.
Client 向 Server 發起連接請求, 發送SYN.
Server 預留連接資源, 向 Client 回復SYN-ACK.
Client 向 Server 回復ACK.
Server 收到 ACK, 連接建立.
在業務層上, Client和Server間進行通訊.
Client 向 Server 發起連接請求, 發送SYN.
Server 不預留連接資源, 向 Client 回復SYN-ACK, 包中附帶有簽名A.
Client 向 Server 回復ACK, 附帶 f(簽名A) (對簽名進行運算的結果).
Server 驗證簽名, 分配連接資源, 連接建立.
在業務層上, Client和Server間進行通訊.
從Client的視角, 連接已經建立.
從Server的視角, 連接並不存在, 既沒有建立, 也沒有」即將建立」 (若不啟用SYN-cookie, Server會知道某個連接」即將建立」)
若業務層的第一個包應是從 Client 發往 Server, 則會進行重發或拋出連接錯誤
若業務層的第一個包應是從 Server 發往 Client的, Server不會發出第一個包. MySQL的故障就屬於這種情況.
- Some of these packets get lost because some buffer somewhere overflows.
probe kernel.function("cookie_v4_check").return
{
source_port = @cast($skb->head + $skb->transport_header, "struct tcphdr")->source
printf("source=%d, return=%d ",readable_port(source_port), $return)
}
function readable_port(port) {
return (port & ((1<<9)-1)) << 8 | (port >> 8)
}
- static inline bool sk_acceptq_is_full(const struct sock *sk){ return sk->sk_ack_backlog > sk- >sk_max_ack_backlog;}
if (!queue->synflood_warned &&
sysctl_tcp_syncookies != 2 &&
xchg(&queue->synflood_warned, 1) == 0)
pr_info("%s: Possible SYN flooding on port %d. %s.
Check SNMP counters. ",
proto, ntohs(tcp_hdr(skb)->dest), msg);
猜想2
懷疑 MySQL 在應用層因為某種原因, 沒有發送握手包, 比如卡在某一個流程上:
懷疑是OS的原因, Google之, 得到參考文檔:A TCP 「stuck」 connection mystery【http://www.evanjones.ca/tcp-stuck-connection-mystery.html】
分析
參考文檔中的現象跟目前的狀況很類似, 簡述如下:
正常的TCP連接流程:
當發生類似SYN-flood的現象時, TCP連接的流程會使用SYN-cookie, 變為:
當啟用SYN-cookie時, 第3步的ACK包因為某種原因丟失, 那麼:
發生這種情況時:
TCP握手的第三步ACK包為什麼丟失
參考文檔中, 對於TCP握手的第三步ACK包的丟失原因, 描述為:
我們可以通過Systemtap進一步探究原因.通過一個簡單的腳本:
觀察結果, 可以確認cookie_v4_check(syn cookie機制進行包簽名檢查的函數)會返回 NULL(0). 即驗證是由於syn cookie驗證不通過, 導致TCP握手的第三步ACK包不被接受.
之後就是對其中不同條件進行觀察, 看看是哪個條件不通過. 最終原因是accept隊列滿(sk_acceptq_is_full):
恢復故障與日誌的正關聯
在故障處理的一開始, 我們就檢查了syslog, 結論是未見異常.
當整個故障分析完成, 得知了故障與syn cookie有關, 回頭看syslog, 裡面是有相關的信息, 只是和故障發生的時間不匹配, 沒有正關聯, 因此被忽略.
檢查Linux源碼:
可以看到日誌受到了抑制, 因此日誌與故障的正關聯被破壞.
粗看源碼, 每個listen socket只會發送一次告警日誌, 要獲得日誌與故障的正關聯, 必須每次測試重啟MySQL.
解決方案
這種故障一旦形成, 難以檢測; 系統日誌中只會出現一次, 在下次重啟MySQL之前就不會再出現了; Client如果沒有合適的超時機制, 萬劫不復.
解決方案:
1. 修改MySQL的協議, 讓Client先發握手包. 顯然不現實.
2. 關閉syn_cookie. 有安全的人又要跳出來了.
3. 或者調高syn_cookie的觸發條件 (syn backlog長度). 降低系統對syn flood的敏感度, 使之可以容忍業務的syn波動.
有多個系統參數混合影響syn backlog長度, 參看【http://blog.bbelboer.com/2012/04/09/syn-cookies.html】
下圖為精華總結
③ 大型網站資料庫系統,怎麼連接那麼多並發數量的
按我個人經驗有以下幾種方法:1.在連接資料庫的時候可以優化,使用連接池。主要就是不要頻繁地創建,銷毀連接。這是很費時的一個操作。因此,使用連接池來代替普通的建立連接操作,能提高並發度。2. 使用緩存技術。並不是每次都需要去資料庫裡面查詢的,我們其實可以把前一次的查詢結果放在內存里,如果下一次用戶來查詢相同的內容,直接內存返回即可,不需要再次查詢。這樣可以大大降低查詢頻率。3.使用分布式技術,將資料庫分布在多台伺服器上,同時也將用戶分區(如根據用戶ID的哈希值分區),不同的伺服器負責不同用戶群,這樣就能大大減少單台伺服器的負載,使得整體的吞吐量提高。這幾樣技術可以同時使用,你的並發數量將獲得非常大的提高。
④ 資料庫並發訪問是什麼意思是同時用資料庫的人數么
資料庫並發訪問是指:可能會發生兩個用戶同時對一張表的同一條數據進行修改等操作,這是可能發生的情況。 和資料庫連接人數是兩個概念。前者是對數據操作的一種可能,後者是和版權相關。