1、生產環境Redis中的熱點key如何發現並優化?
一、用戶消費的數據遠大於生產的數據(熱賣商品、熱點新聞、熱點評論、明星直播)
二、請求分片集中,超過單Server的性能極限。html
熱點key可能形成以下問題:
一、流量集中,達到物理網卡上限
二、請求過多,緩存分片服務被打垮
三、DB擊穿,引發業務雪崩mysql
如何發現熱點key:
一、經過tcpdump抓包,能夠分析抓取到網絡包分析key的頻率
二、redis客戶端抓取,例如請求key的時候記錄日誌,分析日誌獲得key的訪問頻率
三、redis的monitor能夠記錄redis的全部操做,記錄並分析monitor日誌獲得key的訪問頻率(注意:monitor可能會形成性能問題,慎重使用)
四、Redis 4.0提供了—hot-keys配合maxmemory-policy能夠統計熱點key
五、第三方開源項目,如facebook開源項目redis-faina,原理同3git
解決方案以下:
一、對於」get」類型的熱點key,一般能夠爲redis添加slave,經過slave承擔讀壓力來緩解
二、服務端本地緩存,服務端先請求本地緩存,緩解redis壓力
三、多級緩存方案,經過多級請求,層層過濾解決熱點key問題
四、proxy方案,有些方案會探測分片熱點key,緩存在proxy上緩解redis壓力
五、同解決big方案相似,將一個key經過hash分解爲多個key,value值同樣,將這些key分散到集羣多個分片中,須要訪問時先根據hash算出對應的key,而後訪問的具體的分片github
2、有哪些常見的核心的MySQL應用開發規範?
這裏重點介紹下Schema設計規範,其餘規範請參考末尾《知數堂開發規範》redis
(一)schema設計原則:
一、儘可能小的原則,不浪費
二、爲了高併發,禁止使用外鍵
三、每一個表必須有主鍵
四、字符集和庫級保持一致,不單獨定義字段字符集sql
(二)字段規範:
一、每一個表建議不超過30-50個字段
二、優先選擇utf8mb4字符集,它的兼容性最好,並且還支持emoji字符。若是對存儲容量比較敏感的,能夠改爲latin1字符集
三、嚴禁在數據庫中明文存儲用戶密碼、身份證、信用卡號(信用卡PIN碼)等核心機密數據,務必先行加密
四、存儲整型數據時,默認加上UNSIGNED,擴大存儲範圍
五、建議用INT UNSIGNED存儲IPV4地址,查詢時再利用INET_ATON()、INET_NTOA()函數轉換
六、若是遇到BLOB、TEXT字段,則儘可能拆出去,再用主鍵作關聯
七、在夠用的前提下,選擇儘量小的字段,用於節省磁盤和內存空間
八、涉及精確金額相關用途時,建議擴大N倍後,所有轉成整型存儲(例如把分擴大百倍),避免浮點數加減出現不許確問題數據庫
(三)經常使用數據類型參考:
一、字符類型建議採用varchar數據類型(InnoDB建議用varchar替代char)
二、金額貨幣科學計數建議採用decimal數據類型,若是運算在數據庫中完成能夠考慮使用bigint存儲,單位:分
三、自增加標識建議採用int或bigint數據類型,若是該表有大量的刪除及再寫入就使用bigint,反之int就夠用
四、時間類型建議採用爲datetime/timestamp數據類型
五、禁止使用text、longtext等的數據類型
六、字段值若是爲非負數,就加上unsigned定語,提高可用範圍緩存
(四)SQL規範
一、在MySQL中SQL語句通常不區分大小寫,所有小寫
二、sql語句在使用join, 子查詢必定先要進行explain肯定執行計劃
三、爲每一個業務收集sql list.安全
知數堂開發規範:https://github.com/zhishutech...服務器
3、高可用架構MHA有什麼樣的不足和風險點嗎?
MHA做爲傳統複製下的高可用霸主,在今天的GTID環境下,開始慢慢走向沒落,更多的人開始開始選擇replication-manager或者orchestrator等高可用解決方案
不足及風險點:
一、failover依賴於外部腳本,好比VIP切換須要本身編寫腳本實現
二、MHA啓動後只檢測主庫是否正常,並不檢查從庫狀態及主從延遲
三、須要基於SSH免認證配置,存在必定的安全隱患
四、沒有提供從服務器的讀負載均衡功能
五、從節點出現宕機等異常並無能力處理,即沒有從庫故障轉移能力
六、在高可用切換期間,某些場景下可能出現數據丟失的狀況,並不保證數據0丟失
七、沒法控制RTO恢復時間
具體的數據丟失場景移步吳老師公開課《把MHA拉下神壇》
https://ke.qq.com/course/430673?tuin=2ce85033
4、爲何pt-osc操做表之後中文註釋顯示???,如何避免?
通常來講,生產環境使用的表都會使用中文註釋表信息以及字段信息,可是若是使用pt-osc且未指定字符類型的狀況下進行在線變動後,中文註釋都會變成"???",雖然不影響正常使用,可是對於認爲閱讀起來會形成困擾,某些平臺會依據註釋生成數據字典,所以正確的姿式是在使用pt-osc工具時經過--charset=utf8指定utf8字符集
示例:
pt-online-schema-change -h 127.0.0.1 -u xxx -p xxx --alter="add index idx_id(id)" --chunk-size=5000 \ --print --no-version-check --execute D=xucl,t=test --charset=utf8
5、MySQL 5.6升級5.7都有什麼注意事項
(一)MySQL升級的方式通常來講有兩種
一、經過inplace方式原地升級,升級系統表
二、經過新建實例,高版本做爲低版本的從庫進行滾動升級
MySQL5.7版本作了很是多的改變,升級5.6到5.7時須要考慮兼容性,避免升級到5.7以後由於種種參數設置不正確致使業務受影響,建議首先逐一查看release note
(二)須要注意的參數及問題:
一、sql_mode:MySQL 5.7採用嚴格模式,例如ONLY_FULL_GROUP_BY等
二、innodb_status_output_locks:MySQL 5.7支持將死鎖信息打印到error log(其實這個參數MySQL 5.6就已支持)
三、innodb_page_cleaners:MySQL 5.7將髒頁刷新線程從master線程獨立出來了,對應參數爲innodb_page_cleaners
四、innodb_strict_mode:控制CREATE TABLE, ALTER TABLE, CREATE INDEX, 和 OPTIMIZE TABLE的語法問題
五、show_compatibility_56=ON:控制show變量及狀態信息輸出,若是未開啓show status 命令沒法獲取Slave_xxx 的狀態
六、log_timestamps:控制error log/slow_log/genera log日誌的顯示時間,該參數能夠設置爲:UTC 和 SYSTEM,可是默認使用 UTC
七、disable_partition_engine_check:在表多的狀況下可能致使啓動很是慢
八、range_optimizer_max_mem_size:範圍查詢優化參數,這個參數限制範圍查詢優化使用的內存,默認8M
九、MySQL 5.7新增優化器選項derived_merge=on,可能致使SQL全表掃描,而在MySQL 5.6下可能表現爲auto key
十、innodb_undo_directory && innodb_undo_logs:MySQL 5.7支持將undo從ibdata1獨立出來(只支持實例初始化,不支持在線變動)
十一、主從複製問題:MySQL5.7到小於5.6.22的複製存在bug(bug 74683)
十二、SQL兼容性問題:SQL在MySQL 5.7和MySQL 5.6環境下結果可能不一致,所以建議獲取線上SQL,在一樣數據的環境下,在兩個實例運行獲取到的結果計算hash,比較hash值作兼容性判斷
(三)友情提醒
一、升級前必定要作好備份!!!
二、升級正式環境前提早在測試環境進行仔細測試,確認無誤之後再升級正式環境
三、作好相應的回退方案
6、在用阿里雲、騰訊雲等公有云時,你是如何評估新建主機/數據庫對象的配置級別?
這裏以雲下業務遷移雲上爲例來探討
一、首先熟悉現有業務的基本架構,好比一主多從、sharding架構等,而且知道相應的業務分佈
二、獲取現有業務的監控獲取到的峯值QPS、TPS、IOPS、CPU使用率、磁盤使用量、內存使用量、最大鏈接數等關鍵指標
三、獲取現有數據庫的關鍵參數指標,如innodb_buffer_pool_size等
四、公有云每一個規格都提供了相應的參數指標,如:核數、內存、IOPS、最大鏈接數等指標
五、根據第二、三、4步選擇相應規格的RDS,原則爲RDS規格參數大於現有環境狀態指標,其中IOPS須要進行換算(雲上的IOPS通常按4k算,而自建的通常按16k算)
六、上雲前最好先購買實例進行測試,包括使用sysbench進行標準壓測、業務兼容性測試、業務壓測等來判斷實例規格是否知足性能要求,,建議雲上實例性能預留好比20-30%浮動空間
七、特別提醒,雲上實例一般會把binlog以及SQL運行產生的臨時表、臨時文件也計入磁盤空間,此外雲上數據表的碎片率可能會比自建實例大不少(曾經遇到本地5G的表雲上佔用120G),所以要特別注意磁盤空間要預留充足
八、最後說明一點,遷移雲上最好選擇數據庫版本同自建版本。還有,儘可能不要使用雲上數據
7、ALTER TABLE 出現duplicate primary xxx報錯的緣由及處理?
好多同窗都曾經問過這個問題,還有同窗說這是bug,實際上這並非bug
(一)緣由分析
一、Online DDL操做時MySQL會將DML操做緩存起來存入到變動日誌
二、等到DDL執行完成後再應用變動日誌中的DML操做
三、在Oline DDL執行期間,並行的DML可能會沒先檢查惟一性直接插入一條相同主鍵的數據,這時並不會致使DDL報錯,而是在DDL執行完成再次應用變動日誌時才報錯,最終致使DDL報錯執行失敗
(二)問題說明
其實這是Online DDL的正常狀況,官方文檔說明以下:
When running an in-place online DDL operation, the thread that runs the ALTER TABLE statement applies an online log of DML operations that were run concurrently on the same table from other connection threads. When the DML operations are applied, it is possible to encounter a duplicate key entry error (ERROR 1062 (23000): Duplicate entry), even if the duplicate entry is only temporary and would be reverted by a later entry in the online log. This is similar to the idea of a foreign key constraint check in InnoDB in which constraints must hold during a transaction
ref:https://dev.mysql.com/doc/ref...
(三)建議
一、推薦使用pt-osc、gh-ost等第三方工具進行DDL操做
二、建議在業務低谷期進行操做
8、InnoDB在什麼狀況下會觸發檢查點(checkpoint)?
(一)MySQL的checkpoint分類
一、sharp checkpoint(激烈檢查點,要求儘快將全部髒頁都刷到磁盤上,對I/O資源的佔有優先級高)
二、fuzzy checkpoint(模糊檢查點,會根據系統負載及髒頁數量適當平衡,不要求當即將全部髒頁寫入磁盤,這事默認的方式)
(二)觸發時機
一、數據庫正常關閉時,即innodb_fast_shutdown=0時須要執行sharp checkpoint
二、redo log發生切換時或者redo log快滿的時候進行fuzzy checkpoint
三、master thread每隔1秒或10秒按期進行fuzzy checkpoint
四、innodb保證有足夠多的空閒page,若是發現不足,須要移除lru list末尾的page,若是這些page是髒頁,那麼也須要fuzzy checkpoint
五、innodb buffer pool中髒頁比超過innodb_max_dirty_pages_pct時也會觸發fuzzy checkpoint
(三)checkpoint相關參數及狀態
一、innodb_fast_shutdown
二、innodb_io_capacity/innodb_io_capacity_max
三、innodb_lru_scan_depth
四、innodb_max_dirty_pages_pct/innodb_max_dirty_pages_pct_lwm
五、Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total
六、Innodb_buffer_pool_wait_free
9、update t set a=29 and b in (1,2,3,4);這樣寫有什麼問題嗎?
(一)SQL分析
乍一看這個SQL貌似沒有什麼問題,本意是將t表中b的值屬於1/2/3/4的數據的a列修改成29,但實際上該SQL是將t表數據的a列改爲了條件29 & b in (1,2,3,4)的真假判斷值
即:update t set a = (29 and b in (1,2,3,4));
修改後的SQL應該爲update t set a = 29 where b in (1,2,3,4);
(二)注意事項
一、生產環境中進行批量數據修改時應該開啓事務,修改確認後再進行提交操做
二、進行DML操做時,建議仍是經過SQL審覈工具審覈後執行
三、建議打開sql_safe_updates選項,避免沒有WHERE條件的更新、刪除操做
有任何問題均可以加微信討論,歡迎溝通~~ 互相進步!
微信:lvqingshan_
公衆號:知數堂,更多MySQL乾貨知識,關注公衆號獲取。