深度優化LNMP之MySQL

MySQL數據庫優化框架體系php

1.硬件層面優化 前端

2.操做系統層面優化 node

3.MySQL數據庫層面優化 mysql

4.MySQL安全優化 linux

5.網站集羣架構上的優化 ios

6.MySQL流程、制度控制優化web

 

1

硬件層面優化面試

一、數據庫物理機採購redis

CPU: 64位CPU,一臺機器2-16顆CPU。至少2-4顆,L2(緩存)越大越好 算法

內存: 96-128G,MySQL 3-4個實例。32-64G,1-2實例 

硬盤:機械:選SAS,數量越多越好,轉速越高越好15k 

性能:SSD(高併發) > SAS(普通業務線上) >SATA(線下) 

選SSD:使用SSD或者PCIe SSD設備,可提高上千倍的IOPS效率。 

隨機IO:SAS單盤能力300IOPS SSD隨機IO:單盤能力可達35000IOPS Flashcache HBA卡

raid磁盤陣列: 4快盤:RAID0>RAID1(推薦)>RAID5(少用)>RAID1 

主庫選擇raid10,從庫可選raid5/raid0/raid10,從庫配置等於或大於主庫 

網卡:使用多塊網卡bond,以及buffer,tcp優化 

千兆網卡及千兆、萬兆交換機 

提示: 

數據庫屬於IO密集型服務,硬件儘可能不要使用虛擬化。 

Slave硬件要等於或大於Master的性能

 

二、企業案例:

百度:某部門IBM服務器爲48核CPU,內存96GB,一臺服務器跑3~4個實例: 

sina:服務器是DELL R510居多,CPU是E5210,48GB內存,硬盤12*300G SAS,作RAID10

 

三、服務器硬件配置調整

(1)服務器BIOS調整: 

提高CPU效率參考設置: 

a.打開Perfirmance Per Watt Optimeized(DAPC)模式,發揮CPU最大性能,數據庫一般須要高運算量 

b.打開CIE和C States等選項,目的也是爲了提高CPU效率 

c. Memory Frequency(內存頻率)選擇Maximum Performance(最佳性能) 

d.內存設置菜單中,啓動Node Interleaving,避免NUMA問題 

(2)陣列卡調整: 

a.購置陣列卡同時配備CACHE及BBU模塊(機械盤) 

b.設置陣列寫策略爲WEB,甚至OFRCE WB (對數據安全要求高)(wb指raid卡的寫策略:會寫(write back)) 

c.嚴禁使用WT策略,而且關閉陣列預讀策略

2

操做系統層面優化

1.操做系統及MySQL實例選擇

1.必定要選擇x86_64系統,推薦使用CentOS6.8 linux,關閉NUMA特性 

2.將操做系統和數據分開,不只僅是邏輯上,還包括物理上 

3.避免使用Swap交換分區 

4.避免使用軟件磁盤陣列 

5.避免使用LVM邏輯卷 

6.刪除服務器上未使用的安裝包和守護進程

2.文件系統層優化

(1)調整磁盤Cache mode

  1. 啓用WCE=1(Write Cache Enable),RCD=0(Read Cache Disable)模式

  2. 命令:sdparm -s WCE=1,RCD=0 -S /dev/sdb

(2)採用Linux I/O scheduler算法deadline
deadline調度參數 
對於Centos Linux建議 read_expire = 1/2 write_expire

  1. echo 500 /sys/block/sdb/queue/iosched/read_expire

  2. echo 1000 /sys/block/sdb/queue/iosched/write_expire

Linux I/O調度方法 Linux deadline io 調度算法

(3)採用xfs文件系統 
業務量不是很大也可採用ext4,業務量很大,推薦使用xfs:調整XFS文件系統日誌緩衝變量 
XFS高性能設置 

(4)mount掛載文件系統 
增長:async,noatime,nodiratime,nobarrier

noatime

訪問文件時不更新inode的時間戳,高併發環境下,推線顯示應用該選項,能夠提升系統I/O性能

async

寫入時數據會先寫到內存緩衝區,只到硬盤有空檔纔會寫入磁盤,這樣能夠提高寫入效率!風險爲若服務器宕機或不正常,會損失緩衝區中未寫入磁盤的數據 解決辦法:服務器主板電池或加UPS不間斷電源

nodiratime

不更新系統上的directory inode時間戳,高併發環境,推薦顯示該應用,能夠提升系統I/O性能 
   
nobarrier

不使用raid卡上電池 

(5)Linux 內核參數優化 
1.將vm,swappiness設置爲0-10 
2.將vm,dirty_background_ratio設置爲5-10,將vm,dirty_ratio設置爲它的兩倍左右,以確保能持續將髒數據刷新到磁盤,避免瞬間I/O寫,產生嚴重等待

3.優化TCP協議棧

  1. #減小TIME_WAIT,提升TCP效率

  2. net.ipv4.tcp_tw_recyle=1

  3. net.ipv4.tcp_tw_reuse=1

  4. #減小處於FIN-WAIT-2鏈接狀態的時間,使系統能夠處理更多的鏈接net.ipv4.tcp_fin_timeout=2

  5. #減小TCP KeepAlived鏈接偵測的時間,使系統能夠處理更多的鏈接。

  6. net.ipv4.tcp_keepalived_time=600

  7. #提升系統支持的最大SYN半鏈接數(默認1024)

  8. net.ipv4.tcp_max_syn_backlog 16384

  9. #減小系統SYN鏈接重試次數(默認5)

  10. net,ipv4.tcp_synack_retries 1

  11. net.ipv4.tcp_sync_retries 1

  12. #在內核放棄創建的鏈接以前發送SYN包的數量

  13. net.ipv4.ip_local_prot_range 4500 65535

  14. #容許系統打開的端口範圍

4.網絡優化 
#優化系統套接字緩衝區

  1. #Increase TCP max buffer size

  2. net.core.rmem_max=16777216 #最大socket讀buffer

  3. net.core.wmem_max=16777216 #最大socket寫buffer

  4. net.core.wmem_default 8388608 #該文件指定了接收套接字緩衝區大小的缺省

  5. 值(以字節爲單位)

  6. net.core.rmem_default 8388608

#優化TCP接收/發送緩衝區

  1. # Increase Linux autotuning TCP buffer limits

  2. net.ipv4.tcp_rmem=4096 87380 16777216

  3. net.ipv4.tcp_wmem=4096 65536 16777216

  4. net.ipv4.tcp_mem 94500000 915000000 927000000

#優化網絡設備接收隊列

  1. net.core.netdev_max_backlog=3000

5.其餘優化

  1. net.ipv4.tcp_timestamps 0

  2. net.ipv4.tcp_max_orphans 3276800

  3. net.ipv4.tcp_max_tw_buckets 360000

提示:面試的時候說框架,而後說一兩個小的優化參數便可 
更多內核能夠參考「跟老男孩學運維書的第三章」以及咱們的博客,近期將會更新

3

MySQL數據庫層面優化

my.cnf參數優化

此優化主要針對innodb引擎

  1. 若是採用MyISAM引擎,須要key_buffer_size加大。

  2. 強烈推薦採用innodb引擎,default-storage-engine=Innodb

  3. 調整innodb_buffer_pool_size大小,考慮設置爲物理內存的50%-60%左右

  4. 根據實際須要設置inno_flush_log_at_trx_commitsync_binlog的值。

  5. 若是要須要數據不能丟失,那麼兩個都設爲1.若是容許丟失大一點數據,

  6. 則可分別設爲20,在slave上可設爲0

  7. 設置innodb_file_per_table 1,使用獨立表空間

  8. 設置innodb_data_file_path = ibdata1:1G:autoextend,不要使用默認的10%

  9. 設置innodb_log_file_size=256M,設置innodb_log_files_in_group=2,基本可

  10. 知足90%以上的場景;

  11. 不要將innodb_log_file_size參數設置太大,這樣能夠更快同時又更多的磁盤空間,

  12. 丟掉多的日誌一般是好的,在數據庫崩潰後能夠下降恢復數據庫的事件

  13. 設置long_query_time 1記錄那些執行較慢的SQL,用於後續的分析排查;

  14. 根據業務實際須要,適當調整max_connection(最大鏈接數max_connection_error

  15. (最大錯誤數,建議設置爲10萬以上,而open_files_limitinnodb_open_files

  16. table_open_cachetable_definition_cache這幾個參數則可設爲約10倍於

  17. max_connection的大小;)不要設置太大,會將數據庫撐爆

  18. tmp_table_sziemax_heap_table_sizesort_buffer_size

  19. join_buffer_sizeread_buffer_sizeread_rnd_buffer_size等都是

  20. 每一個鏈接session分配的,所以不能設置過大

  21. 建議關閉query cache功能或下降設置不要超過512M

更多內核參數:my-innodb-heavy-4G.cnf 配置文件參數介紹 

MySQL工具mysqlreport 咱們可使用工具來分析MySQL的性能 
如何才能作到網站高併發訪問? 生產環境中對於防範DDOS攻擊的討論 
面試可能會問到DOOS 攻擊防禦

關於庫表的設計規範

  1. 推薦utf-8字符集,雖然有人說談沒有latin1

  2. 固定字符串的列儘量多用定長char,少用varchar

  3. 存儲可變長度的字符串使用VARCHAR而不是CAHR---節省空間,由於固定

  4. 長度的CHAR,而VARCHAR長度不固定(UTF8不愁此影響)

  5. 全部的InnoDB表都設計一個無業務的用途的自增列作主鍵

  6. 字段長度知足需求前提下,儘量選擇長度小的

  7. 字段屬性儘可能都加NOT NULL約束

  8. 對於某些文本字段,例如「省份」或者「性別」咱們能夠將他們定義爲ENUM類型儘量不使用TEXT/BLOB類型,確實須要的話,建議拆分到子表中,不要和主表

  9. 放在一塊兒,避免SELECT *的時候讀性能太差。

  10. 讀取數據時,只選取所須要的列,不要每次都SELECT 避免產生嚴重的隨機讀

  11. 問題,尤爲是讀到一些TEXT/BLOB類型,確實須要的話,建議拆分到子表中,不要

  12. 和主表放在一塊兒,避免SELECT *的時候讀性能太差

  13. 對一個VARCHARN)列建立索引時,一般取其50%(甚至更小)左右長度建立前綴

  14. 索引就足以知足80%以上的查詢需求了,不必建立整列的全長度索引。

  15. 多用符合索引,少用多個獨立索引,尤爲是一些基礎(Cardinality)過小

  16. (若是說:該列的惟一值總數少於255)的列就不要建立獨立索引了。

4

SQL語句的優化

索引優化 
1)白名單機制一百度,項目開發啊,DBA參與,減小上線後的慢SQL數據 
抓出慢SQL,配置my.cnf

  1. long_query_time 2

  2. log-slow-queries=/data/3306/slow-log.log

  3. log_queries_not_using_indexs

  4. 按天輪詢:slow-log.log

2)慢查詢的日誌分析工具——mysqlslapt-query-digest(推薦)

  1. pt-quey-diges,mysqldumpslow,mysqlsla,myprofi,mysql-explain-slow-log,mysqllogfileter

3)天天晚上0點定時分析慢查詢,發到核心開發,DBA分析,及高級運維,CTO的郵箱裏 
DBA分析給出優化建議-->核心開發確認更新-->DBA線上操做處理 
4)按期使用pt-duplicate-key-checker檢查並刪除重複的索引 
按期使用pt-index-usage工具檢查並刪除使用頻率很低的索引 
5)使用pt-online-schema-change來完成大表的ONLINE DDL需求 
6)有時候MySQL會使用錯誤的索引,對於這種狀況使用USE INDEX 
7)使用explainset profile優化SQL語句

大的複雜的SQL語句拆分紅多個小的SQL語句 
子查詢,JOIN連表查詢,某個表4000萬條記錄 
數據庫是存儲數據的地方,但不是計算數據的地方 
對數據計算,應用類處理,都要拿到前端應用解決。禁止在數據庫上處理 
搜索功能,like ‘%oldboy%’ 通常不要用MySQL數據庫 
使用鏈接(JOIN)來代替子查詢(Sub_Queries) 
避免在整個表上使用cout(*),它可能鎖住整張表 
多表聯接查詢時,關聯字段類型儘可能一致,而且都要有索引。 
在WHERE子句中使用UNION代替子查詢 
多表鏈接查詢時,把結果集小的表(注意,這裏是指過濾後的結果集,不同是全表數據量小的)做爲驅動表

爬蟲獲取數據的過程

5

網站集羣架構上的優化

1.服務器上跑多實例,2-4個(具體須要看服務器的硬件信息)

2.主從複製一主五從,採用mixed模式,儘可能不要跨機房同步(進程遠程讀本地寫)

3.按期使用pt-table-checksum、pt-table-sync來檢查並修復mysql主從複製的數據差別

4.業務拆分:搜索功能,like '%oldboy% ' 通常不要用MySQL數據庫

5.業務拆分:某些業務應用使用nosql持久化存儲,例如:memcached、redis、ttserver

  例如粉絲關注,好友關係等

6.數據庫前端必需要加cache,例如:memcached,用戶登陸,商品查詢

7.動態的數據庫靜態化,整個文件靜態化,頁面片斷靜態化

8.數據庫集羣與讀寫分離。一主多從,經過程序或dbproxy進行集羣讀寫分離

9.單表超過800萬,拆庫拆表。人工拆表拆庫(登陸、商品、訂單)

10.百度、阿里國內前三公司,會選擇從庫進行備份,對數據庫進行分庫分表

6

MySQL 流程、制度控制優化

任何一次人爲數據庫記錄的更新,都要走一個流程:

a.人的流程:開發-->核心開發-->運維或DBA

b.測試流程:內網測試-->IDC測試-->線上執行

c.客戶端管理,phpmyadmin

MySQL基礎安全

1.啓動程序700,屬主和用戶組爲MySQL

2.爲MySQL超級用戶root設置密碼

3.若是要求嚴格能夠刪除root用戶,建立其餘管理用戶,例如admin

4.登陸時儘可能不要在命令行暴露密碼,備份腳本中若是有密碼,給設置700,

  屬主和密碼組爲mysql或root

5.刪除默認存在的test庫

6.初始刪除無用的用戶,只保留

| root | 127.0.0.1 |

| root | localhost |

7.不要一個用戶管理全部的庫,儘可能專庫專用戶

8.清理mysql操做日誌文件~/.mysql_history(權限600,能夠不刪)

9.禁止開發得到到web鏈接的密碼,禁止開發鏈接操做生產對外的庫

10.phpmyadmin安全

11.服務器禁止設置外網IP

12.防SQL注入(WEB)php.ini或web開發插件監控,waf控制

文章轉自:https://www.abcdocker.com/abcdocker/952

相關文章
相關標籤/搜索