解決問題:(主要是InnoDB引擎)html
優化原則:mysql
優化思路:sql
1. 優化MySQL服務器的最大鏈接數。數據庫
具體操做:參考博客 Mysql查看狀態,鏈接數,線程數以及Mysql性能監控工具doDBA的使用以及優化緩存
2. 優化須知(主要是InnoDB)安全
2.1 優化原理服務器
2.1.1 InnoDB緩衝池(Buffer Pool)數據結構
若是大部分都是InnoDB表,InnoDB緩衝池或許比其餘任何東西更須要內存。InnoDB緩衝池並不只僅緩衝索引:它還會緩存行數據、自適應hash、插入緩存、鎖,以及其餘內部數據結構。InnoDB還使用緩衝池來幫助延遲寫入,這樣就能合併多個寫入操做,而後一塊兒順序地寫回。總之,InnoDB嚴重依賴緩衝區,你必須確認它分配了足夠的內存,竟可能的大。併發
2.1.2 優化MySQL的I/O行爲(如下內容來自《高性能MySQL》8.5小節)(若是不關心原理,可跳過2.1)socket
對於常見的應用,最重要的一部份內容是InnoDB日誌文件大小、InnoDB怎樣刷新它的日誌緩衝,以及InnoDB怎樣執行I/O。
InnoDB事務日誌。
InnoDB使用日誌來減小提交事務時的開銷。由於日誌中已經記錄了事務,就無須在每一個事務提交時把緩衝池的髒塊刷新到磁盤中。事務修改的數據和索引一般會映射到表空間的隨機位置,因此刷新這些變動到磁盤須要不少隨機I/O。InnoDB假設使用的是常規磁盤(機械磁盤),隨機I/O比順序I/O要昂貴得多,由於一個I/O請求須要時間把磁頭移動正確的位置,而後等待磁盤上讀出須要的部分,再轉到開始位置。
InnoDB用日誌把隨機I/O變成順序I/O。一旦日誌安全寫到磁盤,事務就持久化了,即便變動尚未寫到數據文件。若是一些糟糕的事情發生了(斷電),InnoDB能夠重放日誌並恢復已經提交的事務。
固然,InnoDB最後仍是必須把變動寫到數據文件,由於日誌有固定的大小。InnoDB日誌是環形方式寫的:當寫到日誌的尾部,會從新跳轉到開頭繼續寫,但不會覆蓋還沒應用到數據文件的日誌記錄,由於這樣作會清掉已提交的惟一持久化記錄。
InnoDB使用一個後臺線程智能地刷新這些變動到數據文件。這個線程能夠批量組合寫入,使得數據寫入更順序,以提升效率。實際上,事務日誌把數據文件的隨機I/O轉換爲幾乎順序的日誌文件和數據文件I/O。把刷新操做轉移到後臺使查詢能夠更快完成,而且緩和查詢高峯時I/O系統的壓力。
總體的日誌文件大小受控於innodb_log_file_size和innodb_log_files_in_group兩個參數,這對寫性能很是重要。日誌文件的總大小是每一個文件的大小之和。默認狀況下,只有兩個5MB的文件,總共10MB。對高性能工做來講這過小了。至少須要幾百MB或者上GB的日誌文件。
InnoDB使用多個文件做爲一組循環日誌。一般不須要修改默認日誌數量,只修改每一個日誌文件的大小便可。要修改日誌文件,須要徹底關閉MySQL,將舊的日誌文件移到其餘地方保存,從新配置參數,而後重啓。必定要確保MySQL乾淨地關閉了,或者還有日誌文件能夠保證須要應用到數據文件的事務記錄,否者數據庫就沒法恢復了!
一般不須要把日誌緩衝區設置得很是大,推薦範圍是1MB-8MB,通常來講就足夠了,除非要寫不少至關大的BLOB記錄。較大的日誌緩衝區在某些狀況下也是有好處的:能夠減小緩衝區中空間分配的爭用。當配置一臺有大點內存的服務器時,有時簡單地分配32MB-128MB的日誌緩衝。
日誌緩衝必須被刷新到持久化存儲,以確保提交的事務徹底被持久化了。若是和持久化相比更在意性能,能夠修改innodb_flush_log_at_trx_commit變量來控制日誌緩衝區刷新的頻繁程度。可能的設置以下:
0 :把日誌緩衝寫到日誌文件,而且每秒鐘刷新一次,可是事務提交時不作任何事。
1 :將日誌緩衝寫到日誌文件,而且每次事務提交都刷新到持久化存儲。這是默認的(而且是最安全的)設置,改設置能保證不會丟失任何已經提交的事務,除非磁盤或者操做系統是「僞」刷新的。
2 :每次提交時把日誌緩衝寫到日誌文件,可是並不刷新。InnoDB每秒作一次刷新。0與2最要的不一樣是(也是爲何2更合適),若是MySQL掛了,2不會丟失任何事務。若是整個服務器「掛了」或者斷電了,則仍是可能會丟失一些事務。
瞭解清楚「把日誌緩衝寫到日誌文件」和「把日誌刷新到持久化存儲」之間的不一樣是很重要的。在大部分操做系統中,把緩衝寫到日誌只是簡單地把數據從InnoDB的內存緩衝轉移到操做系統的內存,並無真的把數據寫到持久化存儲。
高性能事務處理須要的最佳配置是把innodb_flush_log_trx_commit設置爲1且把日誌文件放到一個有電池保護的寫緩存的RAID卷中。
2.2 優化結果
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # Recommended in standard MySQL setup sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES # 如下配置是優化後的結果 # MySQL服務器最大鏈接數 max_connections=1000 # MySQL服務器線程緩存大小 thread_cache_size=500 # 日誌緩衝刷新的頻繁程度 innodb_flush_log_at_trx_commit=2 # InnoDB緩衝池 innodb_buffer_pool_size=10000M # 每一個日誌文件的大小 innodb_log_file_size=512M # 日誌緩衝的大小 innodb_log_buffer_size=32M
(若是按照以上配置,Jmeter1000併發,數據鏈接池1000活躍鏈接,MySQL的寫數據操做能到5000-7000TPS)
(測試結果)若是一樣條件把innodb_flush_log_at_trx_commit改爲1,TPS會降低3000左右。