優化了MYSQL大量寫入問題,老闆獎勵了1000塊給我

摘要:你們提到Mysql的性能優化都是注重於優化sql以及索引來提高查詢性能,大多數產品或者網站面臨的更多的高併發數據讀取問題。然而在大量寫入數據場景該如何優化呢?

今天這裏主要給你們介紹,在有大量寫入的場景,進行優化的方案。mysql

總的來講MYSQL數據庫寫入性能主要受限於數據庫自身的配置,以及操做系統的性能,磁盤IO的性能。主要的優化手段包括如下幾點:sql

一、調整數據庫參數

(1) innodb_flush_log_at_trx_commit數據庫

默認爲1,這是數據庫的事務提交設置參數,可選值以下:c#

0: 日誌緩衝每秒一次地被寫到日誌文件,而且對日誌文件作到磁盤操做的刷新,可是在一個事務提交不作任何操做。緩存

1:在每一個事務提交時,日誌緩衝被寫到日誌文件,對日誌文件作到磁盤操做的刷新。安全

2:在每一個提交,日誌緩衝被寫到文件,但不對日誌文件作到磁盤操做的刷新。對日誌文件每秒刷新一次。性能優化

有人會說若是改成不是1的值會不會不安全呢? 安全性比較以下:服務器

在 mysql 的手冊中,爲了確保事務的持久性和一致性,都是建議將這個參數設置爲 1 。出廠默認值是 1,也是最安全的設置。架構

當innodb_flush_log_at_trx_commit和sync_binlog 都爲 1 時是最安全的,在mysqld 服務崩潰或者服務器主機crash的狀況下,binary log 只有可能丟失最多一個語句 或者一個事務。併發

可是這種狀況下,會致使頻繁的io操做,所以該模式也是最慢的一種方式。

  • 當innodb_flush_log_at_trx_commit設置爲0,mysqld進程的崩潰會致使上一秒鐘全部事務數據的丟失。
  • 當innodb_flush_log_at_trx_commit設置爲2,只有在操做系統崩潰或者系統掉電的狀況下,上一秒鐘全部事務數據纔可能丟失。

針對同一個表經過c#代碼按照系統業務流程進行批量插入,性能比較以下所示:

  • (a.相同條件下:innodb_flush_log_at_trx_commit=0,插入50W行數據所花時間25.08秒;
  • (b.相同條件下:innodb_flush_log_at_trx_commit=1,插入50W行數據所花時間17分21.91秒;
  • (c.相同條件下:innodb_flush_log_at_trx_commit=2,插入50W行數據所花時間1分0.35秒。

結論:設置爲0的狀況下,數據寫入是最快的,能迅速提高數據庫的寫入性能, 但有可能丟失上1秒的數據。

(2) temp_table_size,heap_table_size

這兩個參數主要影響臨時表temporary table 以及內存數據庫引擎memory engine表的寫入,設置過小,甚至會出現table is full的報錯信息.

要根據實際業務狀況設置大於須要寫入的數據量佔用空間大小才行。

(3) max_allowed_packet=256M,net_buffer_length=16M,set autocommit=0

備份和恢復時若是設置好這三個參數,可讓你的備份恢復速度飛起來哦!

(4) innodb_data_file_path=ibdata1:1G;ibdata2:64M:autoextend

很顯然表空間後面的autoextend就是讓表空間自動擴展,不夠默認狀況下只有10M,而在大批量數據寫入的場景,不妨把這個參數調大;

讓表空間增加時一次儘量分配更多的表空間,避免在大批量寫入時頻繁的進行文件擴容

(5) innodb_log_file_size,innodb_log_files_in_group,innodb_log_buffer_size

設置事務日誌的大小,日誌組數,以及日誌緩存。默認值很小,innodb_log_file_size默認值才幾十M,innodb_log_files_in_group默認爲2。

然而在innodb中,數據一般都是先寫緩存,再寫事務日誌,再寫入數據文件。設置過小,在大批量數據寫入的場景,必然會致使頻繁的觸發數據庫的檢查點,去把 日誌中的數據寫入磁盤數據文件。頻繁的刷新buffer以及切換日誌,就會致使大批量寫入數據性能的下降。

固然,也不宜設置過大。過大會致使數據庫異常宕機時,數據庫重啓時會去讀取日誌中未寫入數據文件的髒數據,進行redo,恢復數據庫,太大就會致使恢復的時間變的更長。當恢復時間遠遠超出用戶的預期接受的恢復時間,必然會引發用戶的抱怨。

這方面的設置倒能夠參考華爲雲的數據庫默認設置,在華爲雲2核4G的環境,貌似默認配置的buffer:16M,log_file_size:1G----差很少按照mysql官方建議達到總內存的25%了;而日誌組files_in_group則設置爲4組。

2核4G這麼低的硬件配置,因爲參數設置的合理性,已經能抗住每秒數千次,每分鐘8萬屢次的讀寫請求了。

而假如在寫入數據量遠大於讀的場景,或者說方便隨便改動參數的場景,能夠針對大批量的數據導入,再作調整,把log_file_size調整的更大,能夠達到innodb_buffer_pool_size的25%~100%。

(6) innodb_buffer_pool_size設置MySQL Innodb的可用緩存大小。理論上最大能夠設置爲服務器總內存的80%.

設置越大的值,固然比設置小的值的寫入性能更好。好比上面的參數innodb_log_file_size就是參考innodb_buffer_pool_size的大小來設置的。

(7) innodb_thread_concurrency=16

故名思意,控制併發線程數,理論上線程數越多固然會寫入越快。固然也不能設置過大官方建議是CPU核數的兩倍左右最合適。

(8) write_buffer_size

控制單個會話單次寫入的緩存大小,默認值4K左右,通常能夠不用調整。然而在頻繁大批量寫入場景,能夠嘗試調整爲2M,你會發現寫入速度會有必定的提高。

(9) innodb_buffer_pool_instance

默認爲1,主要設置內存緩衝池的個數,簡單一點來講,是控制併發讀寫innodb_buffer_pool的個數。

在大批量寫入的場景,一樣能夠調大該參數,也會帶來顯著的性能提高。

(10) bin_log

二進制日誌,一般會記錄數據庫的全部增刪改操做。然而在大量導數據,好比數據庫還原的時候不妨臨時關閉bin_log,關掉對二進制日誌的寫入,讓數據只寫入數據文件,迅速完成數據恢復,完了再開啓吧。

二、減小磁盤IO,提升磁盤讀寫效率

包括以下方法:

(1):數據庫系統架構優化

a:作主從複製;

好比部署一個雙主從,雙主從模式部署是爲了相互備份,能保證數據安全,不一樣的業務系統鏈接不一樣的數據庫服務器,結合ngnix或者keepalive自動切換的功能實現負載均衡以及故障時自動切換。

經過這種架構優化,分散業務系統的併發讀寫IO從一臺服務器到多臺服務器,一樣能提升單臺數據庫的寫入速度。

b:作讀寫分離

和1中要考慮的問題同樣,能夠減輕單臺服務器的磁盤IO,還能夠把在服務器上的備份操做移到備服務器,減輕主服務器的IO壓力,從而提高寫入性能。

(2):硬件優化

a: 在資源有限的狀況下,安裝部署的時候,操做系統中應有多個磁盤,把應用程序,數據庫文件,日誌文件等分散到不一樣的磁盤存儲,減輕每一個磁盤的IO,從而提高單個磁盤的寫入性能。

b:採用固態硬盤SSD

若是資源足夠能夠採用SSD存儲,SSD具備高速寫入的特性,一樣也能顯著提高全部的磁盤IO操做。

固然還有更多的硬件或者軟件優化方法,這裏就不一一列舉了。

本文分享自華爲雲社區《MYSQL大批量寫入之性能優化》,原文做者: 浮塵 。

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索