1. 程式人生 > >對mysql的高並發優化配置的一些思考

對mysql的高並發優化配置的一些思考

mysql高並發 mysql優化 redis主從

mysql的高並發優化配置的一些思考


mysql的高並發優化配置方案很多,但是適應你自己的就變得很少了,我們對數據庫的優化,無非就是為了應對mysql的高並發情況罷了。隨著大數據的時代的到來和網絡用戶的增多,很多企業中,可能每天應對的數量達百萬,千萬,甚至上億的pv量,這樣的量已經是超過普通配置的mysql所承受的量,所以應對日益增長的pv量,我們需要對mysql做出相應的對策,進一步優化mysql,達到我們所預期的效果,預防因為高並發所引起的mysql宕機,通過調試優化mysql,我們便可以有效的應對這一些情況。

下面我們來談談關於mysql的一些優化方案,方案僅僅的參考,可能每個人的實際情況可能是有的不同,但是大體上可以嘗試這樣的優化。

1、基於redismysql讀寫分離。

對於基於redis的做緩存處理優化,也不是很復雜,對於運維人員來說,你只要安裝redis和調試一下就可以了,關於redis如何調用mysql(好像是需要java寫個腳本),那是開發的事了。基於redis讀寫分離優化並不是很好講,在這裏我先貼個圖,然後再講講。如圖1-1所示:

技術分享圖片

圖1-1 基於redis實現mysql讀寫分離

由上圖所示,我們可以發現其實redis調用就是那麽回事,首先它是由用戶發送請求信息(讀或者寫),然而在有redis的情況下;根據圖的解析可以有以下。

1.1、redis響應請求過程。

讀:讀的過程可能復雜一點,用戶會直接先讀取redis數據庫,然後把請求結果返回到

client;如果用戶在redis沒有讀取到想要請求結果,他會直接逃過redis直接讀取到mysql,然後redis會把數據復制一份到本地。

:寫的過程稍微簡單一點了,用戶會直接向redis寫入,然後redis在緩存到mysql上。可能你會發現,整個過程都基本是redis在工作,mysql好像沒它的事了,對的,我們就是要的是這種效果,任何請求都交給redis處理後,那你還怕mysql響應不過來了嗎。

1.2、redis配置優化

Redis配置,主要的是做持久化配置,主從復制,還有一些安全的配置,大概就是這樣,上圖我是有畫的,至於過程配置我就不寫了,我們大概有個思路就好了。

1.3、mysql優化配置(主從復制)

Mysql做主從復制,怎麽麽說呢,主要是為了安全,一般來說,在master有兩臺slave就可以了,已經足夠應對很多的意外情況了。做主從復制和備份,要註意得是,主從兩臺mysql配置一樣,對於備份的數據,不要放在mysql目錄下,要另起路徑,並給與mysql權限。配置可參考mysql主從復制配置

1.4、mysql監控系統

對於Mysql做監控,個人認為是很有必要的,首先我們可以在無人值守的情況之下,我們可以對mysql的狀態進行監控;通過監控,我們不但可以對mysql的負載情況進行告警,而且可以對mysql本身性能的一些優化處理,所以我在應用對mysql的監控中,使用了zabbix對負載情況做告警處理,並結合pmm-server對mysql系統的優化。對於pmm-sercer在這裏先貼個圖,如圖1.2、1.3所示

技術分享圖片

圖1.2 mysql資源數據圖

技術分享圖片

圖1.3 mysql資源數據圖

由以上圖可以發現,我們可以大體的可以看到mysql的資源配置情況,根據數值我們可以適當的優化,並調整一些mysql的自身的參數,這就是pmm-sever的監控的好處了。

對於zabbix,我現在就是拿來做告警處理,在對mysql的監控中,zabbix本身自帶的模板和結合percona插件,基本實現對整個mysql的監控(配合可參考percona監控mysql數據),因為兩個結合基本比較全面的實現對mysql的監控了,如圖1.4所示,可看到模板所提供的監控項。

技術分享圖片

圖1.4 zabbix的mysql模板監控項

總結以上,我們可以發現,一個良好的mysql優化架構,需要做的包括redis做讀寫分離,mysql主從,監控系統完善等等。如果你還有跟好的方案,也記得分享一下;接下來,我們是針對mysql本身性能的優化,提供性能的容錯率,在基礎上進一步提升mysql的性能。

2.mysql自身的優化

總的來說還是自身因素影響的比較多,我們可以通過修改my.cnf配置文件來對mysql進行進一步的優化。我們可以通過修改mysql的參數使得mysql擁有更可靠的性能。下面是我的數據庫配置,自己通過百度谷歌,找很多配置選項的解析(配置適合mysql5.5以上的版本),然後總結。希望對你有幫助。(註意一下優化配置均在【mysqld】選項下配置,不要搞錯成【mysql】)

[mysqld]
back_log = 300
binlog_format = MIXED
character-set-server=utf8mb4
long_query_time = 1
log-bin=/databack/data_logbin/mysql_binlog
innodb_log_file_size=2G
innodb_log_buffer_size=4M
innodb_buffer_pool_size=4G
#innodb_file_per_table = ON
innodb_thread_concurrency=8
innodb_flush_logs_at_trx_commit=2
#innodb_additional_mem_pool_size=4M
join_buffer_size = 8M
key_buffer_size=256M
max_connections = 1000
max_allowed_packet = 4M
max_connect_errors = 10000
myisam_sort_buffer_size = 64M
port = 3306
query_cache_type=1
query_cache_size = 64M
read_buffer_size=4M
read_rnd_buffer_size=4M
server-id = 1
skip-external-locking
slow_query_log = 1 
#skip-name-resolve
#skip-networking
sort_buffer_size=32M
sort_buffer_size = 6M
socket = /tmp/mysql.sock
table_cache=1024
thread_cache_size = 64
thread_stack = 256K
tmp_table_size=64M
wait_timeout = 10


下面是對上面配置的解析:

back_log = 300該參數的值表示在MySql的連接數據達到#max_connections 時,在它暫時停止響應新請求之前的短時間內有300個請求可以被存在堆棧中,即新來的請求將會被存在堆棧中,以等待某一連接釋放資源,該堆棧的數量即back_log,等 mysql處理完其他請求之後會對其作出響應,如果等待連接的數量超過#back_log,將不被授予連接資源。你可以合理的設置你的back_log,但是該值不要高於操作系統的限制的值。系統的默認值為50Linux系統一般設置小於512的整數。

binlog_format = MIXED配置主從模式下,選取同步的模式,Mysql主從的復制可以有三種復制類型,分別是:語句的復制STATEMEN,行的復制ROW和混合類型的復制MIXED,語句的復制顧名思義就是在主服務器上執行的SQL語句,在從服務器上執行同樣的語句,行的復制就是把改變的內容復制過去,而不是把命令在從服務器上執行一遍。默認采用基於語句的復制,一旦發現基於語句的無法精確的復制時,就會采用基於行的復制,配置,復制類型可以通過binlog_format =在配置文件上配置

character-set-server=utf8mb4 utf-8編碼可能2個字節、3個字節、4個字節的字符,但是MySQLutf8編碼只支持3字節的數據,而移動端的表情數據是4個字節的字符。如果直接往采用utf-8編碼的數據庫中插入表情數據,Java程序中將報SQL異常utf8mb4編碼是utf8編碼的超集,兼容utf8,並且能存儲4字節的表情字符。 采用utf8mb4編碼的好處是,存儲與獲取數據的時候,不用再考慮表情字符的編碼與解碼問題。

long_query_time = 1設置慢查詢響應的時間,記錄超過1秒的SQL執行語句。

log-bin=/databack/data_logbin/mysql_binlog 設置二進制日誌的存放路徑,如果不設置系統會默認存放到mysql的目錄下,建議創建新的目錄來存放二進制日誌,且該目錄不要同數據庫同個目錄,存放目錄擁有者為mysql

innodb_log_file_size=2G 在高寫入負載尤其是大數據集的情況下很重要。這個值越大則性能相對越高,跟據服務器大小而異。這是redo日誌的大小。redo日誌被用於確保寫操作快速而可靠並且在崩潰時恢復。在MySQL 5.5redo日誌的總尺寸被限定在4GB(默認可以有2log文件)。而MySQL 5.6裏可以設置允許大於4G。你可以一開始就把它設置成4G。這個值的設置其實是可以計算的 你可以通過命令SHOW GLOBAL STATUS的輸出看Innodb_os_log_written的值,把該值除以1024*1024 得到的結果是每分鐘處理的redo日誌大小,然後再乘以60得到每小時處理的日誌大小,因為在5.5以上版本都是默認有兩個日誌重做日誌文件ib_logfile0ib_logfile1,所得到結果再除以2,再取整就是你的redo該設置大小了。

innodb_log_buffer_size=4M默認為1M,在默認的設置在中等強度寫入負載以及較短事務的情況下,服務器性能還可以。如果存在更新操作峰值或者負載較大,就應該考慮加大它的值了。在 InnoDB在事務提交前,並不將改變的日誌寫入到磁盤中,因此在大事務中,可以減輕磁盤I/O的壓力。通常情況下,如果不是寫入大量的超大二進制數據,4MB-8MB已經足夠了。

innodb_buffer_pool_size=4G這配置對Innodb表來說非常重要。該參數主要作用是緩存innodb表的索引,數據,插入數據時的緩沖由於Innodb把數據和索引都緩存起來,因此在配置該參數時,可以設置它高達60-80% 的可用內存(官網是建議的也是系統內存的80%左右)。緩沖池是數據和索引緩存的地方這能保證你在大多數的讀取操作時使用的是內存而不是硬盤。一般配置的值是5-6GB(8GB內存)19-25GB(32GB內存)38-50GB(64GB內存)僅供參考。

#innodb_file_per_table = ON5.6中,該選項屬性默認值是ON,由於對新建的表有影響,所以在之前的版本中你需要把它設置成ON。這項設置告知InnoDB是否需要將所有表的數據單獨放在一個.ibd文件,這樣做的好處是使得每個表都有自已獨立的表空間。每個表的數據和索引都會存在自已的表空間中。也實現單表在不同的數據庫中移動,且空間可以回收。

innodb_thread_concurrency=8指服務器邏輯線程數可以設置成與系統一樣數量,參數可配置成邏輯CPU數量的兩倍。

系統CPU查看命令如下:

查看邏輯CPU個數:

#cat /proc/cpuinfo |grep "processor"|sort -u|wc –l


查看物理CPU個數:

# cat /proc/cpuinfo | grep "physical id" |sort -u|wc -l


查看每個物理CPU內核個數:

# cat /proc/cpuinfo |  grep "cpu cores" |uniq


innodb_flush_logs_at_trx_commit=2系統默認值是 1,但是這樣設置會使得提交更新事務都會刷新到磁盤中,會造成資源耗費。所以需要值設置為 2,這樣就不用不把日誌刷新到磁盤上,而只刷新到操作系統的緩存上。但然啦也可以設置為0 這樣設置是很快,但也造成了相對的不安全,會導致MySQL服務器崩潰時就會丟失一些事務。而設置為 2 剛好尼補了。

#innodb_additional_mem_pool_size=4M該參數默認為1M適當調整該參數的大小以確保所有數據都能存放在內存中提高訪問效率的,主要用來存放Innodb的內部目錄,這個值不用分配太大,系統可以自動調。在mysql5.6.3可以忽略。

join_buffer_size = 8M表示#聯合查詢操作所能使用的緩沖區大小。

key_buffer_size=256M指定索引緩沖區的大小,它決定索引處理的速度,你可以設置成系統的物理內存的1/4,它主要針對的是MyISAM引擎,但是設置大少不要超過4G,不然會出現問題。

max_connections = 1000設置MySQL的最大連接,按你實際情況適當設置就好。如果你經常看到‘Too many connections'錯誤,是因為max_connections的值太低了,所以需要設置更高的鏈接數,如果max_connection值被設高之後的缺陷是當服務器運行超過設置閾值或更高的活動事務時會變的沒有響應。

max_allowed_packet = 4M這個參數mysql消息緩沖區的大小,如果這個過小可能會影響到部分操作,默認是1M,一般設置成4-16M就可以了。

max_connect_errors = 10000表示如果有同一個主機訪問的參數值超出該參數值個數的中斷錯誤連接,則該主機將被禁止連接。如需對該主機進行解禁,執行:FLUSH HOST

myisam_sort_buffer_size = 64M這個參數默認是8M,表示MyISAM表發生變化時重新排序所需的緩沖,一般64M就已經足夠了。

port = 3306表示使用3306來做mysql啟動端口

query_cache_type=1表示控制緩存的類型,有三個參數可選(012)設置為0,表示緩存沒有應用,也就相當於禁用了,設置為1,表示緩存所有的結果,設置為2表示只緩存在select語句中通過SQL_CACHE指定需要緩存的查詢。

query_cache_size=32M參數表示mysql查詢結果的緩沖區大小,一般不建議設置太大,因為設置太大會增加開銷,一般設置成32M-256M左右即可,設置參數一般為2的倍數。

read_buffer_size=4M表示按順序查詢操作包括讀、查詢等操作所能使用的緩沖區大小,sort_buffer_size一樣,該參數對應的分配內存也是每連接獨享,一般不建議太大,對於4G16G內存的服務器2M-8M就可以了。

read_rnd_buffer_size=4M表示MySQL的隨機讀緩沖區大小。當任意順序讀取行時將分配一個隨機讀取緩沖區,進行排序查詢時,便分配隨機緩沖作為該操作的緩沖區大小,同樣的對於4G16G內存的服務器2M-8M就可以了。

server-id = 1表示做主從同步所定義的serverid,作為masterserver_id必須必slave端的要小,越小表示優先級越高,但是在同個網段內的mysql服務,不允許設置同樣的sever_id。參數可設參考範圍(1-200)。

skip-external-locking開啟該選項表示避免MySQL的外部鎖定,減少出錯幾率增強穩定性,適用於單服務器環境。

slow_query_log = 1開啟慢查詢日誌,作用於慢查詢日誌,顧名思義,就是查詢慢的日誌。

skip-name-resolve禁止MySQL對外部連接進行DNS解析,使用這一選項可以消除MySQL進行DNS解析的時間。但需要註意,如果開啟該選項,則所有遠程主機連接授權都要使用IP地址方式,否則MySQL將無法正常處理連接請求。

skip-networking開啟該選項可以徹底關閉MySQLTCP/IP連接方式,如果WEB服務器是以遠程連接的方式訪問MySQL數據庫服務器則不要開啟該選項,否則將無法正常連接。

sort_buffer_size = 8M表示查詢排序時所能使用的緩沖區大小。它直接與實時連接的個數 有關,實時連接的個數乘以sort_buffer_size的大小就是實際分配的總共排序緩沖區大小。所以,對於內存在4GB-8G左右的服務器可以設置為6-16M

socket = /tmp/mysql.sockmysql.sock 文件作用主要是serverclient在同一臺服務器,當使用本地連接時,就會使用socket進行連接,該文件一般是放在/var/lib/mysql/mysql.sock下,也常常使用ln –s /tmp目錄下做軟連接。

table_cache=1024table_cache主要用於設置table高速緩存的數量。由於每個客戶端連接都會至少訪問一個表,因此此參數的值與max_connections有關。你可以通過命令show variables like '%open%'; 查看open_files_limit參數,大量使用MyISAM的環境裏,應該保證open_files_limit表類型至少是table_cache的二到三倍,默認為2402,調到512-1024最佳。

thread_cache_size = 64 :這個變量值表示的是可以重新利用保存在緩存中線程的數量,當斷開連接時如果緩存中還有空間,那麽客戶端的線程將被放到緩存中,如果線程重新被請求,那麽請求將從緩存中讀取,如果緩存中是空的或者是新的請求,那麽這個線程將被重新創建,如果有很多新的線程,增加這個值可以改善系統性能.通過比較 Connections 和 Threads_created 狀態的變量,可以看到這個變量的作用 根據物理內存設置規則可以做以下配置2G-4G可以設置為16-64左右,當然大於4G的服務器,設置64也已經足夠了。

thread_stack = 256K表示每個連接線程被創建時,MySQL給它分配的內存大小,對於8-16G的服務器設置成256K就可以了,再大一點的,可以適當增加呢。

tmp_table_size=64M表示定義一個臨時表的大小,該值默認為16M,可調到64-256最佳,線程獨占,太大可能內存不夠造成I/O堵塞,如果動態頁面可以適當調大點。

wait_timeout = 10表示指定一個請求的最大連接時間,對於4G-8G左右內存的服務器可以設置為5-10

3、總結

預防Mysql病發的情況,是每個企業所要面對的事情,大數據的到來,更加使得mysql的性能要求更高,所以對mysql的優化升級,也是迫在眉睫。以上是本人總結,僅僅提供參考,希望能幫到你。


對mysql的高並發優化配置的一些思考