架构-浅谈MySQL数据库优化
?
?主從復制博文:http://lizhenliang.blog.51cto.com/7876557/1290431
?
? 讀寫分離博文:http://lizhenliang.blog.51cto.com/7876557/1305083
?
?MySQL-MMM博文:http://lizhenliang.blog.51cto.com/7876557/1354576
?
(一)數據庫部署
(1)項目初期:訪問量單臺部署應對1500左右的QPS(每秒查詢率)
(2)項目后期,考慮到高可用行,可采用MySQL主從復制+Keepalived做雙機熱備。常見的集群軟件有Keepalived,Hearbeat。
雙機熱備博文:http://lizhenliang.blog.51cto.com/7876557/1362313
(二)數據庫性能優化:
MySQL部署到普通的X86,在不經過優化的情況下,MySQL理論值正常可以處理2000左右QPS,
經過優化后,有可能提升到2500左右QPS。
當訪問量達到1500QPS左右并發連接時,數據庫處理性能就會變慢,而且硬件資源還很富裕。
這時應該考慮到軟件問題了。
(1)一方面可以單擊運行多個MySQL實例讓服務器性能發揮到最大。
(2)另一方面可對數據庫進行優化,往往操作系統和數據默認配置都比較保守,會對數據庫發揮有一定限制,可對這些配置進行適當的調整,盡可能的處理更多連接數。
具體優化有一下三個層面:
3.1 數據庫配置優化
MySQL常用有兩種存儲引擎:
一個是MYISAM,不支持事物處理,讀性能處理快,表級別鎖。
另一個是InnoDB,支持事物處理(ACID),涉及目標是為處理大容量數據發揮最大化性能,行級別鎖。
表鎖:開銷小,鎖定力度大,發生死鎖概率高,相對并發也低。
行鎖:開銷大,鎖定力度小,發生死鎖概率低,相對并發也高。
公共參數默認值:
max_connection =151
#同時處理最大連接數,推薦設置最大連接數是上限連接數的80%左右。
sort_buffer_size = 2M
#查詢排序時緩沖區大小,只對order by 和 group by起作用,可增大此值為16M
open_files_limit = 1024
#打開文件數限制,如果打開文件數值等于或者大于open_files_limit 值時,程序會無法鏈接數據庫或者卡死。
MyISAM 參數默認值:
key_buffer_size =16M
#索引緩存大小,一般涉及就物理內存的30--40%? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? read_buffer_size = 128k
#讀操作緩沖區大小,推薦設置16M或32M
query_cache_type =ON
#打開查詢緩存功能
query_cache_limit = 1M
#查詢緩存限制,只有1M以下查詢結果才會被緩存,以免結果數據較大把緩存池覆蓋
query_cache_size =16M
#查詢緩沖區大小,用于緩存SELECT查詢結果,下一次有同樣SELECT查詢將直接從緩存池
返回結果,可適當成倍增加此值;
InnoDB參數默認值:
innodb_buffer_pool_size = 128M
#索引和數據緩沖區大小,一般設置物理內存的60%-70%
innodb_buffer_pool_instances = 1
#緩沖池實例個數,推薦設置4個至8個
innodb_flush_log_at_try=x_commit = 1
#關鍵參數,0代表大約每秒寫入到日志并同步到磁盤,數據庫故障會丟失1秒左右事物數據。
1為每執行一條SQL后寫入到日志并同步到磁盤,I/O開銷大,執行完SQL要等待日志讀寫,效率低。
2代表只把日志寫入到系統緩存區,再每秒同步到磁盤,效率很好,如果服務器故障,才會丟失事物數據。對數據安全性要求不是很高的推薦設置2,性能高,修改后效果明顯;
innodb_file_per_table =OFF
#默認是共享表空間,共享表空間idbdata文件不斷增大,影像一定的I/O性能。推薦開啟獨立表空間模式,每個表的索引和數據都存在自己獨立的表空間中。可以實現單表在不同數據庫中移動。
innodb_log_buffer_size = 8M
#日志緩沖區大小,由于日志最長每秒鐘刷新一次,所以一般不用超過16M。
?
3.2系統內核優化
大多數MYSQL都部署在linux系統上,所以操作系統的一些參數也會影響到MySQL性能,一下對linux內核進行適當優化。
net.ipv4.tcp_fin_timeout = 30
#TIME_WAIT超時時間,默認是60S
net.ipv4.tcp_tw_reuse =1
# 1代表開始復用,允許TIME_WAIT? socket 重新用于新的TCP 連接,0表示關閉;
net.ipv4.tcp_tw_recycle =1?
# 1表示開啟TIME_WAIT socket 快速回收,0表示關閉
net_ipv4.tcp_max_tw_buckets = 4096
#系統保持TIME_WAIT socket 最大數量,如果超出這個數,系統將隨機清除一些TIME_WAIT并打印警告信息。
net.vpv4.tcp_max_syn_backlog = 4096
#進入SYN隊列最大長度,加大隊列長度可容納更多的等待連接;
?
在linux系統中,如果進程打開的文件句柄數量超過系統默認值1024,就會提示“too many files open”信息,所以要調整打開文件句柄限制。
#?vi?/etc/security/limits.conf??#加入以下配置,*代表所有用戶,也可以指定用戶,重啟系統生效 *?soft?nofile?65535 *?hard?nofile?65535 #?ulimit?-SHn?65535???#立刻生效3.3硬件配置:
加大物理內存,提高文件系統性能。linux內核會從內存中分配出緩存區(系統緩存和數據緩存)來存放熱數據,
通過文件系統延遲寫入機制,等滿足條件時(如緩存區大小達到一定百分比或者執行sync命令)才會同步到磁盤。也就是說物理內存越大,分配緩存區越大,緩存數據越多。當然,服務器故障會丟失一定的緩存數據。
SSD固態硬盤代替SAS機械硬盤,將RAID級別調整為RAID1+0,相對RAID1和RAID5有更好的讀寫性能(IOPS),畢竟數據庫的壓力主要來自磁盤I/O方面。
(三)數據庫架構擴展
隨著業務量越來越大,單臺數據庫服務器性能已無法滿足業務需求,該考慮加機器了,該做集群了。主要思想是分解單臺數據庫負載,突破? I/O 性能,熱數據存放緩存中,降低磁盤I/O訪問頻率。
3.1主從復制與讀寫分離。
因為生產環境中,數據庫大多都是讀操作,所以部署一主多從架構,主數據庫負責寫操作,并做雙機熱備,多臺從數據庫做負載均衡,負責讀操作,主流的負載均衡器有LVS、HAProxy、Nginx.
實現方法1:代碼層面,利用多數據源進行處理讀寫;
實現方法2:常見代理程序有 MySQL Proxy, Amoeba.
(有一套基于perl語言開發的主從復制管理工具,叫MySQL-MMM(Master-Master replication managerfor Mysql,Mysql主主復制管理器),這個工具最大的優點是在同一時間只提供一臺數據庫寫操作,有效保證數據一致性。)
3.2 增加緩存
給數據增加緩存系統,把熱數據緩存到內存中,如果緩存中有要請求的數據就不再去數據庫中返回結果,提高了讀性能。緩存實現了本地緩存和分布式緩存;
本地緩存是將數據緩存到本地服務器內存或者文件中。
分布式緩存可以緩存海量數據,擴展性好;
主流的分布式緩存有memcached、redis;? ?
memcached 性能穩定,數據緩存在內存中,速度很快。QPS可達8W左右。
如果想數據持久化就選擇redis,性能不低于memcached。
?
3.3分庫
?分庫是根據業務不同把相關的表切分到不同的數據庫中,比如web、bbs、blog等庫。如果業務量很大,還可將切分后的庫做主從架構,進一步避免單個庫壓力過大。
3.4分表
?
數據量的日劇增加,數據庫中某個表有幾百萬條數據,導致查詢和插入耗時太長,怎么能解決單表壓力呢?你就該考慮是否把這個表拆分成多個小表,來減輕單個表的壓力,提高處理效率,此方式稱為分表。
?
? 分表技術比較麻煩,要修改程序代碼里的SQL語句,還要手動去創建其他表,也可以用merge存儲引擎實現分表,相對簡單許多。分表后,程序是對一個總表進行操作,這個總表不存放數據,只有一些分表的關系,以及更新數據的方式,總表會根據不同的查詢,將壓力分到不同的小表上,因此提高并發能力和磁盤I/O性能。
?
??分表分為垂直拆分和水平拆分:
?
? 垂直拆分:把原來的一個很多字段的表拆分多個表,解決表的寬度問題。你可以把不常用的字段單獨放到一個表中,也可以把大字段獨立放一個表中,或者把關聯密切的字段放一個表中。
?
? 水平拆分:把原來一個表拆分成多個表,每個表的結構都一樣,解決單表數據量大的問題。
?
3.5 分區
?分區就是把一張表的數據根據表結構中的字段(如range、list、hash等)分成多個區塊,這些區塊可以在一個磁盤上,也可以在不同的磁盤上,分區后,表面上還是一張表,但數據散列在多個位置,這樣一來,多塊硬盤同時處理不同的請求,從而提高磁盤I/O讀寫性能,實現比較簡單。
注:增加緩存、分庫、分表和分區主要由程序猿來實現。
5、數據庫維護
? 數據庫維護是運維工程師或者DBA主要工作,包括性能監控、性能分析、性能調優、數據庫備份和恢復等。
??5.1?性能狀態關鍵指標
? QPS,Queries Per Second:每秒查詢數,一臺數據庫每秒能夠處理的查詢次數
? TPS,Transactions Per Second:每秒處理事務數
? 通過show status查看運行狀態,會有300多條狀態信息記錄,其中有幾個值幫可以我們計算出QPS和TPS,如下:
? Uptime:服務器已經運行的實際,單位秒
? Questions:已經發送給數據庫查詢數
? Com_select:查詢次數,實際操作數據庫的
? Com_insert:插入次數
? Com_delete:刪除次數
? Com_update:更新次數
? Com_commit:事務次數
? Com_rollback:回滾次數
??那么,計算方法來了,基于Questions計算出QPS:
| 1 2 | ??mysql>?show?global?status?like?'Questions'; ??mysql>?show?global?status?like?'Uptime'; |
? QPS = Questions / Uptime
? 基于Com_commit和Com_rollback計算出TPS:
| 1 2 3 | ??mysql>?show?global?status?like?'Com_commit'; ??mysql>?show?global?status?like?'Com_rollback'; ??mysql>?show?global?status?like?'Uptime'; |
? TPS = (Com_commit + Com_rollback) / Uptime
??另一計算方式:基于Com_select、Com_insert、Com_delete、Com_update計算出QPS
| 1 | ??mysql>?show?global?status?where?Variable_name?in('com_select','com_insert','com_delete','com_update'); |
? 等待1秒再執行,獲取間隔差值,第二次每個變量值減去第一次對應的變量值,就是QPS
? TPS計算方法:
| 1 | ??mysql>?show?global?status?where?Variable_name?in('com_insert','com_delete','com_update'); |
? 計算TPS,就不算查詢操作了,計算出插入、刪除、更新四個值即可。
? 經網友對這兩個計算方式的測試得出,當數據庫中myisam表比較多時,使用Questions計算比較準確。當數據庫中innodb表比較多時,則以Com_*計算比較準確。
??5.2 開啟慢查詢日志
? MySQL開啟慢查詢日志,分析出哪條SQL語句比較慢,使用set設置變量,重啟服務失效,可以在my.cnf添加參數永久生效。
| 1 2 3 4 | mysql>?set?global?slow-query-log=on??#開啟慢查詢功能 mysql>?set?global?slow_query_log_file='/var/log/mysql/mysql-slow.log';??#指定慢查詢日志文件位置 mysql>?set?global?log_queries_not_using_indexes=on;???#記錄沒有使用索引的查詢 mysql>?set?global?long_query_time=1;???#只記錄處理時間1s以上的慢查詢 |
? 分析慢查詢日志,可以使用MySQL自帶的mysqldumpslow工具,分析的日志較為簡單。
? # mysqldumpslow -t 3 /var/log/mysql/mysql-slow.log ? ?#查看最慢的前三個查詢
? 也可以使用percona公司的pt-query-digest工具,日志分析功能全面,可分析slow log、binlog、general log。
? 分析慢查詢日志:pt-query-digest /var/log/mysql/mysql-slow.log
? 分析binlog日志:mysqlbinlog mysql-bin.000001 >mysql-bin.000001.sql?
? pt-query-digest --type=binlog mysql-bin.000001.sql?
? 分析普通日志:pt-query-digest --type=genlog localhost.log
??5.3 數據庫備份
? 備份數據庫是最基本的工作,也是最重要的,否則后果很嚴重,你懂得!但由于數據庫比較大,上百G,往往備份都很耗費時間,所以就該選擇一個效率高的備份策略,對于數據量大的數據庫,一般都采用增量備份。常用的備份工具有mysqldump、mysqlhotcopy、xtrabackup等,mysqldump比較適用于小的數據庫,因為是邏輯備份,所以備份和恢復耗時都比較長。mysqlhotcopy和xtrabackup是物理備份,備份和恢復速度快,不影響數據庫服務情況下進行熱拷貝,建議使用xtrabackup,支持增量備份。
? Xtrabackup備份工具使用博文:http://lizhenliang.blog.51cto.com/7876557/1612800
??5.4 數據庫修復
? 有時候MySQL服務器突然斷電、異常關閉,會導致表損壞,無法讀取表數據。這時就可以用到MySQL自帶的兩個工具進行修復,myisamchk和mysqlcheck。
??myisamchk:只能修復myisam表,需要停止數據庫
? 常用參數:
? -f --force ? ?強制修復,覆蓋老的臨時文件,一般不使用
? -r --recover ?恢復模式
? -q --quik ? ? 快速恢復
? -a --analyze ?分析表
? -o --safe-recover 老的恢復模式,如果-r無法修復,可以使用此參數試試
? -F --fast ? ? 只檢查沒有正常關閉的表
? 快速修復weibo數據庫:
? # cd /var/lib/mysql/weibo?
? # myisamchk -r -q *.MYI
??mysqlcheck:myisam和innodb表都可以用,不需要停止數據庫,如修復單個表,可在數據庫后面添加表名,以空格分割
? 常用參數:
? -a ?--all-databases ?檢查所有的庫
? -r ?--repair ? 修復表
? -c ?--check ? ?檢查表,默認選項
? -a ?--analyze ?分析表
? -o ?--optimize 優化表
? -q ?--quik ? 最快檢查或修復表
? -F ?--fast ? 只檢查沒有正常關閉的表
? 快速修復weibo數據庫:
? mysqlcheck -r -q -uroot -p123 weibo?
? 5.5?另外,查看CPU和I/O性能方法
? #查看CPU性能
? #參數-P是顯示CPU數,ALL為所有,也可以只顯示第幾顆CPU
? #查看I/O性能
?
? #參數-m是以M單位顯示,默認K
? #%util:當達到100%時,說明I/O很忙。
? #await:請求在隊列中等待時間,直接影響read時間。
? I/O極限:IOPS(r/s+w/s),一般RAID0/10在1200左右。(IOPS,每秒進行讀寫(I/O)操作次數)
? I/O帶寬:在順序讀寫模式下SAS硬盤理論值在300M/s左右,SSD硬盤理論值在600M/s左右。
?
?
注:X86(The X86 architecture)是微處理器執行的計算機語言指令集,指一個intel通用計算機系列的標準編號縮寫,也標識一套通用的計算機指令集合。1978年6月8日,Intel發布了新款16位微處理器“8086”。
轉載于:https://www.cnblogs.com/javaDB2019/p/10449922.html
總結
以上是生活随笔為你收集整理的架构-浅谈MySQL数据库优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一天搞懂深度学习
- 下一篇: SQL Server 日志清理、数据文件