1. 程式人生 > >Mysql配置引數innodb_buffer_pool_size的學習與整理(配合之前文章配置資料庫)

Mysql配置引數innodb_buffer_pool_size的學習與整理(配合之前文章配置資料庫)

    這半個月來,一直在做一些關於伺服器交易端效能的提升工作,主要是分析和討論交易端效能的瓶頸,找出導致效能減慢的原因,擬定出合理的解決方案,主要是通過幾個方面進行研究和學習,今天總算有了一點點突破,主要是涉及mysql核心引數innodb_buffer_pool_size的學習和討論,這裡簡單的整理和總結一下。
    

    首先簡單的介紹一下伺服器交易端的環境,使用的是Spring + MyBatis + Mysql的架構,程式碼中使用了Spring宣告式事務進行管理,效能的瓶頸主要是存在於事務提交上面,通過測試和分析日誌,發現程式碼在進行事務提交時耗時比較嚴重,這半個月的研究也走了許多彎路,總算有得有失,對於其中的一些知識也有了一定的理解,主要是包含下面幾個方面:
    MyBatis

    第一點想到的可能原因是MyBatis對Connection的管理,由於對MyBatis的理解不深入,簡單的分析日誌,發現MyBatis日誌中出現大量的create SqlSession,於是簡單的研究了一下MyBatis SqlSession,這裡有一篇總結的文章:關於MyBatis sqlSession的一點整理

    通過研究討論和查閱原始碼,對MyBatis SqlSession有了一定的理解,發現問題可能不再這裡。

 Mysql 

    Mysql的配置是懷疑導致效能瓶頸的原因,不過沒有證據證明,同事提到了thread_concurrency引數,於是開始了mysql配置引數的學習,但是mysql的配置引數很多,短時間內無法做到面面俱到,於是通過分析線上執行的mysql的配置檔案進行學習,這裡也整理出了幾篇文章:

    通過對線上mysql一些配置引數的學習和討論,感覺這些所瞭解到的引數的配置較為合理,於是研究的重心發生了偏移,轉向了Spring事務管理機制的研究。
    Spring 

    Spring的事務管理機制,自己的理解也不清晰,對於原始碼也沒有過認真的研讀,於是花費了點時間對Spring Transaction事務管理機制和MyBatis SqlSession進行了再次的學習和研究討論,也算有了一點點收穫,期間也做了總結和整理,並根據自己的理解做了時序圖,詳情見這裡:Spring Transaction + MyBatis SqlSession事務管理機制研究學習

    但是問題又來了,通過與同事的討論和閱讀原始碼,更加的迷惑了,好像效能的瓶頸也不是Spring Transaction的問題。不知道接下來該怎麼突破了,一次偶然的與同事交流,出現了轉機,在本機進行測試時,發現我本機的效能要明顯優於同事的電腦,那麼問題來了,是什麼導致了效能的差異?

    首先是硬體的不同,雖然記憶體一致,但是CPU版本卻完全不同,CPU的差異是導致效能的一部分原因,這是第一個突破點;其次是本地mysql配置的不同,發現我本地使用的是mysql預設生成的配置,同事本地使用的是伺服器上的mysql配置,第二個突破點就是mysql配置的差異,主要是引數的不同,於是重心又轉移到了mysql配置檔案的研究學習討論上面。

    Mysql    

    中間出現的曲折就不說了,說多了都是淚,結果反覆的測試,發現在增大或減小一個引數的值時,效能差異明顯,經過與同事討論和測試,發現這個引數在高併發高I/O時正確的配置非常重要,可能帶來很大的效能提升,這個引數就是innodb_buffer_pool_size,下面,就來詳細的學習和整理一下這個引數的意義。        

    innodb_buffer_pool_size引數表示緩衝池位元組大小,InnoDB快取表和索引資料的記憶體區域。mysql預設的值是128M。最大值與你的CPU體系結構有關,在32位作業系統,最大值是 4294967295 (2^32-1) ,在64 位作業系統,最大值為18446744073709551615 (2^64-1)。在32位作業系統中,CPU和作業系統實用的最大大小低於設定的最大值。如果設定的緩衝池的大小大於1G,設定innodb_buffer_pool_instances的值大於1,在伺服器繁忙的時候可以提高伸縮性,不過在實際的測試中,發現帶來的效能提升並不明顯,而且參考了這裡的一篇文章mysql優化---第7篇:引數 innodb_buffer_pool_instances設定,初步設定innodb_buffer_pool_instances為1。

    這個值設定的越大,在不止一次的訪問相同的資料表資料時,消耗的磁碟I / O就越少。在一個專用的資料庫伺服器,則可能將其設定為高達80%機器物理記憶體大小。不過在實際的測試中,發現無限的增大這個值,帶來的效能提升也並不顯著,對CPU的壓力反而增大,設定合理的值才是最優。在出現以下問題時,你就需要考慮減少這個引數的值了:

  • 實體記憶體的競爭可能會導致作業系統分頁。

  • InnoDB儲備額外的記憶體緩衝區和控制結構,以便總分配空間大於指定的大小大約是10%。

  • 地址空間必須是連續的在通過DLL載入特定地址的Windows系統中,這可能存在問題。

  • 初始化緩衝池的時間大致與它的大小成正比。在大型系統中初始化的時間可能很顯著。例如:在現代化的Linux x86_64伺服器上,初始化一個10GB的緩衝池大小,大約需要6秒鐘。


    在MySQL 5.7.5版本後,innodb_buffer_pool_size引數的值可以動態的設定,這意味著你可以在不啟動伺服器的情況下,重新設定緩衝區的大小。這種調整的操作是按塊執行的。可以通過innodb_buffer_pool_chunk_size引數配置塊的大小。Innodb_buffer_pool_resize_status狀態變數記錄了從調整操作的狀態。


    同樣的,在mysql的眾多引數中,關係到磁碟IO的引數還有兩個,分別是:innodb_log_buffer_size和innodb_log_file_size。       

    innodb_log_buffer_size表示InnoDB寫入到磁碟上的日誌檔案時使用的緩衝區的位元組數,預設值為8M。一個大的日誌緩衝區允許大量的事務在提交之前不寫日誌到磁碟。因此,如果你有很多事務更新,插入或刪除很操作,通過這個引數會大量節省了磁碟I / O。

    innodb_log_file_size表示一個日誌組每個日誌檔案的位元組大小。日誌檔案的總大小innodb_log_file_size* innodb_log_files_in_group不能超過最高512GB。例如一對255 GB的日誌檔案,已經接近了極限,不能超過。預設值是48M。比較合適值的範圍是從1MB到1 / N個緩衝池大小其中N是該組中的日誌檔案的數量該值越大緩衝池中必要的檢查點重新整理活動就會越少,節省磁碟I/ O。但是越大的日誌檔案,mysql的崩潰恢復就越慢,儘管在mysql5.5之後改進了恢復效能和日誌檔案恢復的代價。

    上面的兩個引數,並沒有進行mysql效能的測試,也並沒有特定的進行配置,下一步,會仔細的研究測試一下,敬請期待。