一次mysql癱瘓解救

最近手機app項目訪問流量逐步的增長,對服務端webapi考驗極大,是在一次新的業務消息推送後,極光推送給手機接受到的客戶端達到19萬個,此時app立馬開始訪問速度變慢了,用戶體驗至關差java

客服接到的問題電話開始一個接一個,我一看心想完了,確定是流量起來了,要麼是數據庫要麼是nginx,要麼是帶寬不夠了,這三種可能比較大mysql

因而趕忙解決問題linux

打開數據庫服務監控:進程鏈接數達到1200個,每一個進程都有sql在處理中。。以下圖:nginx

很明顯問題出來了,mysql數據庫頂不住了,  我這裏用的是mysql的分支 percona,抗高併發能力強於官方版本https://www.percona.com/docs/wiki/benchmark:mysql:554-tpcc:startweb

因而調整參數,而後重啓,中間重啓出現了一次錯誤,把我給嚇壞了,而後趕忙還原my。cnf,還好每次改的時候會備份一下,否則只有哭了redis

還原了配置,mysql能夠啓動了,可是已啓動就立刻1200個鏈接所有被塞滿了,app操做依舊慢,個人天,不帶這麼玩個人,sql

因而調整參數,而後不重啓 用 service mysqld reload 命令來操做數據庫

 這裏調整好幾個參數,都是一點一點的加,結果發現起明顯做用的仍是api

innodb_buffer_pool_size,innodb_write_io_threads,innodb_read_io_threads,innodb_log_file_size,table_cache

這裏要經過監控 看 進程是查詢的多仍是 更新寫的多,分別來調整innodb_write_io_threads,innodb_read_io_threads
我最高把這兩個設置到12,設置完reload,排隊的sql進程 很快就由query變成sleep

綜合了linux服務器資源使用狀況 ,我最後調整成以下配置.

[mysqld]
basedir=/usr/local/mysql
user=mysql
socket=/var/run/mysqld/mysqld.sock

server_id=1

local_infile=1
tmpdir=/mnt/fio

datadir=/mnt/fio320
skip-grant-table

innodb_buffer_pool_size=4G[實際內存8G]

innodb_data_file_path=ibdata1:10M:autoextend
innodb_file_per_table=1
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=16M
innodb_log_files_in_group=2
innodb_log_file_size=900M
innodb_thread_concurrency=0
innodb_flush_method             = O_DIRECT

innodb_write_io_threads=9
innodb_read_io_threads=9
innodb_io_capacity=500
innodb_max_dirty_pages_pct=90
max_connections=12000
query_cache_size=0
skip-name-resolve
table_cache=400

調整後reload,瞬間 排隊的sql慢慢在減小,進程也開始逐步減小,到130穩定下
再次打開app,速度跟日常速度同樣了
用mysqlworkbench 監控,命中率 和buffer使用率達到100%

這裏數據庫環節優化完了,接下來的思路是要優化sql語句還有java服務程序的性能,用redis來承擔頻繁的讀取,最後同步到mysql
相關文章
相關標籤/搜索