[轉]單表60億記錄等大資料場景的MySQL優化和運維之道
此文是根據楊尚剛在【QCON高可用架構群】中,針對MySQL在單表海量記錄等場景下,業界廣泛關注的MySQL問題的經驗分享整理而成,轉發請註明出處。
楊尚剛,美圖公司資料庫高階DBA,負責美圖後端資料儲存平臺建設和架構設計。前新浪高階資料庫工程師,負責新浪微博核心資料庫架構改造優化,以及資料庫相關的伺服器儲存選型設計。
前言
MySQL資料庫大家應該都很熟悉,而且隨著前幾年的阿里的去IOE,MySQL逐漸引起更多人的重視。
MySQL歷史
- 1979年,Monty Widenius寫了最初的版本,96年釋出1.0
- 1995-2000年,MySQL AB成立,引入BDB
- 2000年4月,整合MyISAM和replication
- 2001年,Heikki Tuuri向MySQL建議整合InnoDB
- 2003釋出5.0,提供了檢視、儲存過程等功能
- 2008年,MySQL AB被Sun收購,09年推出5.1
- 2009年4月,Oracle收購Sun,2010年12月推出5.5
- 2013年2月推出5.6 GA,5.7開發中
MySQL的優點
- 使用簡單
- 開源免費
- 擴充套件性“好”,在一定階段擴充套件性好
- 社群活躍
- 效能可以滿足網際網路儲存和效能需求,離不開硬體支援
上面這幾個因素也是大多數公司選擇考慮MySQL的原因。不過MySQL本身存在的問題和限制也很多,有些問題點也經常被其他資料庫吐槽或鄙視
MySQL存在的問題
- 優化器對複雜SQL支援不好
- 對SQL標準支援不好
- 大規模叢集方案不成熟,主要指中介軟體
- ID生成器,全域性自增ID
- 非同步邏輯複製,資料安全性問題
- Online DDL
- HA方案不完善
- 備份和恢復方案還是比較複雜,需要依賴外部元件
- 展現給使用者資訊過少,排查問題困難
- 眾多分支,讓人難以選擇
看到了剛才講的MySQL的優勢和劣勢,可以看到MySQL面臨的問題還是遠大於它的優勢的,很多問題也是我們實際需要在運維中優化解決的,這也是MySQL DBA的一方面價值所在。並且MySQL的不斷髮展也離不開社群支援,比如Google最早提交的半同步patch,後來也合併到官方主線。Facebook Twitter等也都開源了內部使用MySQL分支版本,包含了他們內部使用的patch和特性。
資料庫開發規範
資料庫開發規範定義:開發規範是針對內部開發的一系列建議或規則, 由DBA制定(如果有DBA的話)。
開發規範本身也包含幾部分:基本命名和約束規範,欄位設計規範,索引規範,使用規範。
規範存在意義
- 保證線上資料庫schema規範
- 減少出問題概率
- 方便自動化管理
- 規範需要長期堅持,對開發和DBA是一個雙贏的事情
想想沒有開發規範,有的開發寫出各種全表掃描的SQL語句或者各種奇葩SQL語句,我們之前就看過開發寫的SQL 可以打印出好幾頁紙。這種造成業務本身不穩定,也會讓DBA天天忙於各種救火。
基本命名和約束規範
- 表字符集選擇UTF8 ,如果需要儲存emoj表情,需要使用UTF8mb4(MySQL 5.5.3以後支援)
- 儲存引擎使用InnoDB
- 變長字串儘量使用varchar varbinary
- 不在資料庫中儲存圖片、檔案等
- 單表資料量控制在1億以下
- 庫名、表名、欄位名不使用保留字
- 庫名、表名、欄位名、索引名使用小寫字母,以下劃線分割 ,需要見名知意
- 庫表名不要設計過長,儘可能用最少的字元表達出表的用途
欄位規範
- 所有欄位均定義為NOT NULL ,除非你真的想存Null
- 欄位型別在滿足需求條件下越小越好,使用UNSIGNED儲存非負整數 ,實際使用時候儲存負數場景不多
- 使用TIMESTAMP儲存時間
- 使用varchar儲存變長字串 ,當然要注意varchar(M)裡的M指的是字元數不是位元組數;使用UNSIGNED INT儲存IPv4 地址而不是CHAR(15) ,這種方式只能儲存IPv4,儲存不了IPv6
- 使用DECIMAL儲存精確浮點數,用float有的時候會有問題
- 少用blob text
關於為什麼定義不使用Null的原因
* 1.浪費儲存空間,因為InnoDB需要有額外一個位元組儲存
* 2.表內預設值Null過多會影響優化器選擇執行計劃
關於使用datatime和timestamp,現在在5.6.4之後又有了變化,使用二者儲存在儲存空間上大差距越來越小 ,並且本身datatime儲存範圍就比timestamp大很多,timestamp只能儲存到2038年
索引規範
- 單個索引欄位數不超過5,單表索引數量不超過5,索引設計遵循B+ Tree索引最左字首匹配原則
- 選擇區分度高的列作為索引
- 建立的索引能覆蓋80%主要的查詢,不求全,解決問題的主要矛盾
- DML和order by和group by欄位要建立合適的索引
- 避免索引的隱式轉換
- 避免冗餘索引
關於索引規範,一定要記住索引這個東西是一把雙刃劍,在加速讀的同時也引入了很多額外的寫入和鎖,降低寫入能力,這也是為什麼要控制索引數原因。之前看到過不少人給表裡每個欄位都建了索引,其實對查詢可能起不到什麼作用。
冗餘索引例子
- idx_abc(a,b,c)
- idx_a(a) 冗餘
- idx_ab(a,b) 冗餘
隱式轉換例子
欄位:remark
varchar(50) NOT Null
MySQL>SELECT id
, gift_code
FROM gift WHERE deal_id
= 640 AND remark=115127; 1 row in set (0.14 sec)
MySQL>SELECT id
, gift_code
FROM pool_gift WHEREdeal_id
= 640 AND remark=‘115127’; 1 row in set (0.005 sec)
欄位定義為varchar,但傳入的值是個int,就會導致全表掃描,要求程式端要做好型別檢查
SQL類規範
- 儘量不使用儲存過程、觸發器、函式等
- 避免使用大表的JOIN,MySQL優化器對join優化策略過於簡單
- 避免在資料庫中進行數學運算和其他大量計算任務
- SQL合併,主要是指的DML時候多個value合併,減少和資料庫互動
- 合理的分頁,尤其大分頁
- UPDATE、DELETE語句不使用LIMIT ,容易造成主從不一致
資料庫運維規範
運維規範主要內容
- SQL稽核,DDL稽核和操作時間,尤其是OnlineDDL
- 高危操作檢查,Drop前做好資料備份
- 許可權控制和審計
- 日誌分析,主要是指的MySQL慢日誌和錯誤日誌
- 高可用方案
- 資料備份方案
版本選擇
- MySQL社群版,使用者群體最大
- MySQL企業版,收費
- Percona Server版,新特性多
- MariaDB版,國內使用者不多
建議選擇優先順序為:MySQL社群版 > Percona Server > MariaDB > MySQL 企業版
不過現在如果大家使用RDS服務,基本還以社群版為主
Online DDL問題
原生MySQL執行DDL時需要鎖表,且鎖表期間業務是無法寫入資料的,對服務影響很大,MySQL對這方面的支援是比較差的。大表做DDL對DBA來說是很痛苦的,相信很多人經歷過。如何做到Online DDL呢,是不是就無解了呢?當然不是!
上面表格裡提到的 Facebook OSC和5.6 OSC也是目前兩種比較靠譜的方案
MySQL 5.6的OSC方案還是解決不了DDL的時候到從庫延時的問題,所以現在建議使用Facebook OSC這種思路更優雅
下圖是Facebook OSC的思路
後來Percona公司根據Facebook OSC思路,用perl重寫了一版,就是我們現在用得很多的pt-online-schema-change,軟體本身非常成熟,支援目前主流版本。
使用pt-online-schema-change的優點有:
- 1.無阻塞寫入
- 2.完善的條件檢測和延時負載策略控制
值得一提的是,騰訊互娛的DBA在內部分支上也實現了Online DDL,之前測試過確實不錯,速度快,原理是通過修改InnoDB儲存格式來實現。
使用pt-online-schema-change的限制有:
- 改表時間會比較長(相比直接alter table改表)
- 修改的表需要有唯一鍵或主鍵
- 在同一埠上的併發修改不能太多
可用性
關於可用性,我們今天分享一種無縫切主庫方案,可以用於日常切換,使用思路也比較簡單
在正常條件下如何無縫去做主庫切換,核心思路是讓新主庫和從庫停在相同位置,主要依賴slave start until 語句,結合雙主結構,考慮自增問題。
MySQL叢集方案:
- 叢集方案主要是如何組織MySQL例項的方案
- 主流方案核心依然採用的是MySQL原生的複製方案
- 原生主從同步肯定存在著效能和安全性問題
MySQL半同步複製:
現在也有一些理論上可用性更高的其它方案
- Percona XtraDB Cluster(沒有足夠的把控力度,不建議上)
- MySQL Cluster(有官方支援,不過實際用的不多)
紅框內是目前大家使用比較多的部署結構和方案。當然異常層面的HA也有很多第三方工具支援,比如MHA、MMM等,推薦使用MHA
sharding拆分問題
- Sharding is very complex, so itʼs best not to shard until itʼs obvious that you will actually need to!
- sharding是按照一定規則資料重新分佈的方式
- 主要解決單機寫入壓力過大和容量問題
- 主要有垂直拆分和水平拆分兩種方式
- 拆分要適度,切勿過度拆分
- 有中間層控制拆分邏輯最好,否則拆分過細管理成本會很高
曾經管理的單表最大60億+,單表資料檔案大小1TB+,人有時候就要懶一些
上圖是水平拆分和垂直拆分的示意圖
資料庫備份
首先要保證的,最核心的是資料庫資料安全性。資料安全都保障不了的情況下談其他的指標(如效能等),其實意義就不大了。
備份的意義是什麼呢?
- 資料恢復!
- 資料恢復!
- 資料恢復!
目前備份方式的幾個緯度:
- 全量備份 VS 增量備份
- 熱備 VS 冷備
- 物理備份 VS 邏輯備份
- 延時備份
- 全量binlog備份
建議方式:
- 熱備+物理備份
- 核心業務:延時備份+邏輯備份
- 全量binlog備份
借用一下某大型網際網路公司做的備份系統資料:一年7000+次擴容,一年12+次資料恢復,日誌量每天3TB,資料總量2PB,每天備份資料量百TB級,全年備份36萬次,備份成功了99.9%。
主要做的幾點:
- 備份策略集中式排程管理
- xtrabackup熱備
- 備份結果統計分析
- 備份資料一致性校驗
- 採用分散式檔案系統儲存備份
備份系統採用分散式檔案系統原因:
- 解決儲存分配的問題
- 解決儲存NFS備份效率低下問題
- 儲存集中式管理
- 資料可靠性更好
使用分散式檔案系統優化點:
* Pbzip壓縮,降低多副本儲存帶來的儲存成本,降低網路頻寬消耗
* 元資料節點HA,提高備份叢集的可用性
* erasure code方案調研
資料恢復方案
目前的MySQL資料恢復方案主要還是基於備份來恢復,可見備份的重要性。比如我今天下午15點刪除了線上一張表,該如何恢復呢?首先確認刪除語句,然後用備份擴容例項啟動,假裝置份時間點是凌晨3點,就還需要把凌晨3點到現在關於這個表的binlog匯出來,然後應用到新擴容的例項上,確認好恢復的時間點,然後把刪除表的資料匯出來應用到線上。
效能優化
複製優化
MySQL複製:
- 是MySQL應用得最普遍的應用技術,擴充套件成本低
- 邏輯複製
- 單執行緒問題,從庫延時問題
- 可以做備份或讀複製
問題很多,但是能解決基本問題
上圖是MySQL複製原理圖,紅框內就是MySQL一直被人詬病的單執行緒問題
單執行緒問題也是MySQL主從延時的一個重要原因,單執行緒解決方案:
- 官方5.6+多執行緒方案
- Tungsten為代表的第三方並行複製工具
- sharding
上圖是MySQL5.6 目前實現的並行複製原理圖,是基於庫級別的複製,所以如果你只有一個庫,使用這個意義不大
當然MySQL也認識到5.6這種並行的瓶頸所在,所以在5.7引入了另外一種並行複製方式,基於logical timestamp的並行複製,並行複製不再受限於庫的個數,效率會大大提升
上圖是5.7的logical timestamp的複製原理圖
剛才我也提到MySQL原來只支援非同步複製,這種資料安全性是非常差的,所以後來引入了半同步複製,從5.5開始支援
上圖是原生非同步複製和半同步複製的區別。可以看到半同步通過從庫返回ACK這種方式確認從庫收到資料,資料安全性大大提高
在5.7之後,半同步也可以配置你指定多個從庫參與半同步複製,之前版本都是預設一個從庫
對於半同步複製效率問題有一個小的優化,就是使用5.6+的mysqlbinlog以daemon方式作為從庫,同步效率會好很多
關於更安全的複製,MySQL 5.7也是有方案的,方案名叫Group replication 官方多主方案,基於Corosync實現
主從延時問題
原因:一般都會做讀寫分離,其實從庫壓力反而比主庫大/從庫讀寫壓力大非常容易導致延時。
解決方案:
- 首先定位延時瓶頸
- 如果是IO壓力,可以通過升級硬體解決,比如替換SSD等
- 如果IO和CPU都不是瓶頸,非常有可能是SQL單執行緒問題,解決方案可以考慮剛才提到的並行複製方案
- 如果還有問題,可以考慮sharding拆分方案
提到延時不得不提到很坑人的Seconds behind master,使用過MySQL的應該很熟悉
這個值的原始碼裡演算法
long time_diff= ((long)(time(0) – mi->rli.last_master_timestamp) – mi->clock_diff_with_master);
Secondsbehindmaster來判斷延時不可靠,在網路抖動或者一些特殊引數配置情況下,會造成這個值是0但其實延時很大了。通過heartbeat表插入時間戳這種機制判斷延時是更靠譜的
複製注意點:
- Binlog格式,建議都採用row格式,資料一致性更好
- Replication filter應用
主從資料一致性問題:
- row格式下的資料恢復問題
InnoDB優化
成熟開源事務儲存引擎,支援ACID,支援事務四個隔離級別,更好的資料安全性,高效能高併發,MVCC,細粒度鎖,支援O_DIRECT。
主要優化引數:
- innodbfileper_table =1
- innodbbufferpool_size,根據資料量和記憶體合理設定
- innodbflushlog_attrxcommit= 0 1 2
- innodblogfile_size,可以設定大一些
- innodbpagesize
- Innodbflushmethod = o_direct
- innodbundodirectory 放到高速裝置(5.6+)
- innodbbufferpool_dump
- atshutdown ,bufferpool dump (5.6+)
上圖是5.5 4G的redo log和5.6 設定大於4G redo log檔案效能對比,可以看到穩定性更好了。innodblogfile_size設定還是很有意義的
InnoDB比較好的特性:
- Bufferpool預熱和動態調整大小,動態調整大小需要5.7支援
- Page size自定義調整,適應目前硬體
- InnoDB壓縮,大大降低資料容量,一般可以壓縮50%,節省儲存空間和IO,用CPU換空間
- Transportable tablespaces,遷移ibd檔案,用於快速單表恢復
- Memcached API,full text,GIS等
InnoDB在SSD上的優化:
- 在5.5以上,提高innodbwriteiothreads和innodbreadiothreads
- innodbiocapacity需要調大
- 日誌檔案和redo放到機械硬碟,undo放到SSD,建議這樣,但必要性不大
- atomic write,不需要Double Write Buffer
- InnoDB壓縮
- 單機多例項
也要搞清楚InnoDB哪些檔案是順序讀寫,哪些是隨機讀寫
隨機讀寫:
- datadir
- innodbdata file_path
- innodbundo directory
順序讀寫:
- innodbloggrouphomedir
- log-bin
InnoDB VS MyISAM:
- 資料安全性至關重要,InnoDB完勝,曾經遇到過一次90G的MyISAM表repair,花了兩天時間,如果在線上幾乎不可忍受
- 併發度高
- MySQL 5.5預設引擎改為InnoDB,標誌著MyISAM時代的落幕
TokuDB:
- 支援事務 ACID 特性,支援多版本控制(MVCC)
- 基於Fractal Tree Index,非常適合寫入密集場景
- 高壓縮比,原生支援Online DDL
- 主流分支都支援,收費轉開源 。目前可以和InnoDB媲美的儲存引擎
目前主流使用TokuDB主要是看中了它的高壓縮比,Tokudb有三種壓縮方式:quicklz、zlib、lzma,壓縮比依次更高。現在很多使用zabbix的後端資料表都採用的TokuDB,寫入效能好,壓縮比高。
下圖是我之前做的測試對比和InnoDB
上圖是sysbench測試的和InnoDB效能對比圖,可以看到TokuDB在測試過程中寫入穩定性是非常好的。
tokudb存在的問題:
- 官方分支還沒很好的支援
- 熱備方案問題,目前只有企業版才有
- 還是有bug的,版本更新比較快,不建議在核心業務上用
比如我們之前遇到過一個問題:TokuDB的內部狀態顯示上一次完成的checkpoint時間是“Jul 17 12:04:11 2014”,距離當時發現現在都快5個月了,結果堆積了大量redo log不能刪除,後來只能重啟例項,結果重啟還花了七八個小時
MySQL優化相關的case
Query cache,MySQL內建的查詢加速快取,理念是好的,但設計不夠合理,有點out。
鎖的粒度非常大MySQL 5.6預設已經關閉
When the query cache helps, it can help a lot. When it hurts, it can hurt a lot.明顯前半句已經沒有太大用處,在高併發下非常容易遇到瓶頸。
關於事務隔離級別 ,InnoDB預設隔離級別是可重複讀級別,當然InnoDB雖然是設定的可重複讀,但是也是解決了幻讀的,建議改成讀已提交級別,可以滿足大多數場景需求,有利於更高的併發,修改transaction-isolation。
上圖是一個比較經典的死鎖case,有興趣可以測試下
關於SSD
關於SSD,還是提一下吧。某知名大V說過“最近10年對資料庫效能影響最大的是快閃記憶體”,穩定性和效能可靠性已經得到大規模驗證,多塊SATA SSD做Raid5,推薦使用。採用PCIe SSD,主流雲平臺都提供SSD雲硬碟支援。
最後說一下大家關注的單表60億記錄問題,表裡資料也是線上比較核心的。
先說下當時情況,表結構比較簡單,都是bigint這種整型,索引比較多,應該有2-3個,單錶行數60億+,單表容量1.2TB左右,當然內部肯定是有碎片的。
形成原因:歷史遺留問題,按照我們前面講的開發規範,這個應該早拆分了,當然不拆有幾個原因:
- 效能未遇到瓶頸 ,主要原因
- DBA比較“懶“
- 想看看InnoDB的極限,挑戰一下。不過風險也是很大的,想想如果在一個1.2TB表上加個欄位加個索引,那感覺絕對酸爽。還有就是單表恢復的問題,恢復時間不可控。
我們後續做的優化 ,採用了剛才提到的TokuDB,單表容量在InnoDB下1TB+,使用Tokudb的lzma壓縮到80GB,壓縮效果非常好。這樣也解決了單表過大恢復時間問題,也支援online DDL,基本達到我們預期。
今天講的主要針對MySQL本身優化和規範性質的東西,還有一些比較好的運維經驗,希望大家能有所收穫。今天這些內容是為後續資料庫做平臺化的基礎。我今天分享就到這裡,謝謝大家。
QA
Q1:use schema;select * from table; 和select * from schema.table;兩種寫法有什麼不一樣嗎?會對主從同步有影響嗎?
對於主從複製來說執行效率上差別不大,不過在使用replication filter時候這種情況需要小心,應該要使用ReplicateWildIgnoreTable這種引數,如果不使用帶wildignore,第一種方式會有問題,過濾不起作用。
Q2:對於用於MySQL的ssd,測試方式和ssd的引數配置方面,有沒有好的建議?主要針對ssd的配置哈
關於SATA SSD配置引數,建議使用Raid5,想更保險使用Raid50,更土豪使用Raid 10
上圖是主要的引數優化,效能提升最大的是第一個修改排程演算法的
Q3:資料庫規範已制定好,如何保證開發人員必須按照規範來開發?
關於資料庫規範實施問題,也是有兩個方面吧,第一、定期給開發培訓開發規範,讓開發能更瞭解。第二、還是在流程上規範,比如把我們日常通用的建表和欄位策略固化到程式,做成自動化稽核系統。這兩方面結合 效果會比較好。
Q4:如何最大限度提高innodb的命中率?
這個問題前提是你的資料要有熱點,讀寫熱點要有交集,否則命中率很難提高。在有熱點的前提下,也要求你的你的記憶體要足夠大,能夠存更多的熱點資料。儘量不要做一些可能汙染bufferpool的操作,比如全表掃描這種。
Q5:主從複製的情況下,如果有CAS這樣的需求,是不是隻能強制連主庫?因為有延遲的存在,如果讀寫不在一起的話,會有髒資料。
如果有CAS需求,確實還是直接讀主庫好一些,因為非同步複製還是會有延遲的。只要SQL優化的比較好,讀寫都在主庫也是沒什麼問題的。
Q6:關於開發規範,是否有必要買國標?
這個國標是什麼東西,不太瞭解。不過從字面看,國標應該也是偏學術方面的,在具體工程實施時候未必能用好。
Q7:主從叢集能不能再細化一點那?不知道這樣問合適不?
看具體哪方面吧。主從叢集每個小叢集一般都是採用一主多從方式,每個小叢集對應特定的一組業務。然後監控備份和HA都是在每個小叢集實現。
Q8:如何跟蹤資料庫table某個欄位值發生變化?
追蹤欄位值變化可以通過分析row格式binlog好一些。比如以前同事就是通過自己開發的工具來解析row格式binlog,跟蹤資料行變化。
Q9:對超大表水平拆分,在使用MySQL中介軟體方面有什麼建議和經驗分享?
對於超大表水平拆分,在中介軟體上經驗不是很多,早期人肉搞過幾次。也使用過自己研發的資料庫中介軟體,不過線上應用的規模不大。關於目前眾多的開源中介軟體裡,360的atlas是目前還不錯的,他們公司內部應用的比較多。
Q10:我們用的MySQL proxy做讀負載,但是少量資料壓力下並沒有負載,請問有這回事嗎?
少量資料壓力下,並沒有負載 ,這個沒測試過,不好評價
Q11:對於binlog格式,為什麼只推薦row,而不用網上大部分文章推薦的Mix ?
這個主要是考慮資料複製的可靠性,row更好。mixed含義是指如果有一些容易導致主從不一致的SQL ,比如包含UUID函式的這種,轉換為row。既然要革命,就搞的徹底一些。這種mix的中間狀態最坑人了。
Q12: 讀寫分離,一般是在程式裡做,還是用proxy ,用proxy的話一般用哪個?
這個還是獨立寫程式好一些,與程式解耦方便後期維護。proxy國內目前開源的比較多,選擇也要慎重。
Q13: 我想問一下關於mysql執行緒池相關的問題,什麼情況下適合使用執行緒池,相關的引數應該如何配置,老師有這方面的最佳實踐沒有?
執行緒池這個我也沒測試過。從原理上來說,短連結更適合用執行緒池方式,減少建立連線的消耗。這個方面的最佳配置,我還沒測試過,後面測試有進展可以再聊聊。
Q14: 誤刪資料這種,資料恢復流程是怎麼樣的(從庫也被同步刪除的情況)?
看你刪除資料的情況,如果只是一張表,單表在幾GB或幾十GB。如果能有延時備份,對於資料恢復速度是很有好處的。恢復流程可以參考我剛才分享的部分。目前的MySQL資料恢復方案主要還是基於備份來恢復 ,可見備份的重要性。比如我今天下午15點刪除了線上一張表,該如何恢復呢。首先確認刪除語句,然後用備份擴容例項啟動,假裝置份時間點是凌晨3點。就還需要把凌晨3點到現在關於這個表的binlog匯出來,然後應用到新擴容的例項上。確認好恢復的時間點,然後把刪除表的資料匯出來應用到線上。
Q15: 關於備份,binlog備份自然不用說了,物理備份有很多方式,有沒有推薦的一種,邏輯備份在量大的時候恢復速度比較慢,一般用在什麼場景?
物理備份採用xtrabackup熱備方案比較好。邏輯備份一般用在單表恢復效果會非常好。比如你刪了一個2G表,但你總資料量2T,用物理備份就會要慢了,邏輯備份就非常有用了。
想和群內專家繼續交流MySQL相關技術,請關注公眾號後,回覆arch,申請進群。
本文策劃 慶豐@微博, 內容由王傑編輯,劉偉@途牛、陳剛@北京智識 校對與釋出,其他多位志願者對本文亦有貢獻。讀者可以通過搜尋“ArchNotes”或長按下面圖片,關注“高可用架構”公眾號,檢視更多架構方面內容,獲取通往架構師之路的寶貴經驗。轉載請註明來自“高可用架構(ArchNotes)”公眾號,敬請包含二維碼!