最近手機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