摘要:正常同步和副本集,在正常工作的情況下,是以一種不斷的異步的方式進行同步。是一個特殊的固定大小的,固定大小意味著,新的操作記錄的寫入會導致最老的操作記錄的刪除,以保證的大小。而且已經降級為,將無法接受請求,以及不能變成。
Devops一般很少時間會花在數據庫的部署上,只有到了不得不去考慮的情況下,才會去考慮如何調整數據庫,以適應業務的發展。mongodb本身就很適合Devops,大部分情況下,部署基本按照說明操作一下即可。但實際操作起來,其實還有會有一些坑,比如Resync。
正常同步和oplogmongo副本集,在正常工作的情況下,是以一種不斷的、異步的方式進行同步。每個副本都會不斷的記錄自己進行的操作進入到oplog表里;Secondary副本就會不斷的從Primary副本那里同步最新的操作,從而完成整個副本集的同步。當然Secondary的副本也可以選擇從其他的Secondary副本同步,因為每個副本都會記錄oplog。詳細的描述可以參考官方文檔Replica Set Data Synchronization。
Oplog是一個特殊的固定大小的collection,固定大小意味著,新的操作記錄的寫入會導致最老的操作記錄的刪除,以保證oplog的大小。這個值如果不去設置,mongo會自動根據硬盤大小的5%來設定。大部分情況下沒有什么問題,但有一個非常重要的設(da)定(keng):
oplog一旦大小固定,那么只能通過重啟+配置來進行修改
為什么這會是一個坑,后面會繼續討論。
同步延遲lag和optime副本集之間一般通過網絡連接,副本集之間的性能也有可能有差異(當然最好不要有),所以同步操作有可能出現毫秒級別的延遲,甚至到1s以上,這個可以通過在任意一個副本集上執行
rs.status()
來查看所有副本集的同步狀態。這個打印出的各個副本的optime,就是這個副本最后一條操作執行的時間,Secondary和Primary之間optime的時間差,其實就是同步延遲。
同步延遲一般情況下,頂多也就一兩秒,但是一些異常情況,例如宕機、長時間過載overload,可能會導致這個時間越來越長。這里,我們的oplog的巨大作用就顯現出來了!
Secondary和Primary之間的同步差,最大不能超過Primary的oplog能存儲的條數
注意!因為Secondary是從Primary同步oplog,所以,這里只與Primary的oplog大小有關,與Secondary自身記錄的oplog無關!當然,如果Secondary是從其他的Secondary同步數據,那么至于同步目標的oplog有關。
為了幫助用戶直觀的理解oplog里面存儲了多少條操作,mongo還額外提供了兩個數據:
tFirst 第一條oplog的時間
tLast 最后一條oplog的時間
這兩個數據,可以通過在primary上執行:
db.getReplicationInfo()
獲得。tLast - tFirst就是mongo同步機制所允許你進行停機同步數據的最大時間,當然這個時間不是固定的,如果當前的負載很低,相當于相同的oplog表可以存更長時間內的操作數據,就會給你留更多的停機操作時間。
上圖中,Secondary落后于Primary,也就是說,同步延遲有10分鐘(兩個optime相減),但此時,Primary上存有最近20分鐘的oplog,那么Secondary通過獲取這些oplog,仍然能夠在短時間內趕上Primary的進度。
但是,一旦optime的差距超出了Primary的tFirst,情況就不妙了,如下圖:
此時,自動的同步已經無法完成同步了(stale),必須執行手動操作Resync。而且Secondary已經降級為Recovering,將無法接受請求,以及不能變成master。
Resync機制Resync機制官網有詳細的介紹,基本思路就是把數據拷貝過來,再進行上面的oplog的同步。例如:
使用磁盤快照,把快照的數據庫文件直接覆蓋到Secondary上,重啟Secondary
使用Initial Sync,把Secondary的數據清空,讓mongo自動從0開始,重新同步所有數據
磁盤快照看起來很美好,但是是mongo的數據存儲是分配后就不返回的,也就是說實際占用的磁盤空間要比真實數據的大小要大,使用操作系統的scp也好rsync也好,這些無用的空間也會被復制,耽誤復制的時間。除此之外,建立快照本身也需要耗時,反正在阿里云上建快照并不快,200G的數據大約要1小時多。
而Initial Sync是mongo之間拷貝表數據,拷貝完了就地重建索引,所以相當于只傳輸了真實的表數據,連索引數據都不用傳輸,從整體的復制時間來看更加節省,但是會對拷貝對象Primary有一些性能影響,但畢竟只是讀,而且不需要Primary停機。
Resync的大坑無論使用上面的哪種Resync機制,思路都是一致的,通過某種快速的方式同步更多的數據,然后剩下的使用oplog彌補在執行操作時的新操作。看起來很美好,而實際的執行過程中,如果操作的時間,要大于oplog所記錄的時間,怎么辦?將永遠無法不停機Resync成功!
這里Initial Sync為什么也不能成功呢?其實在Initial Sync的日志中,就可以看出來,在STATUP2的狀態,就是一張表一張表的拷數據,也就是說,就算拷貝過程中的數據已經同步過去了,當拷貝下一張表時,上一張表的數據其實已經過期了。而當數據量很大的情況下(其實不需要太大,幾百G),整個拷貝過程也要持續數小時,此時如果oplog的記錄時間低于STARTUP2所需要花費的時間,恭喜你,你中獎了。
當然,如果你能有一臺正常同步數據的Secondary,新的機器指向這臺也是可以的,但是你的架構是一臺Arbiter一臺Primary一臺Secondary的話……就沒辦法了,只能指望Primary了。別問我為什么知道,我就是知道。(╯‵□′)╯︵┴─┴
遇到這種情況怎么辦?
半夜Primary停機,同步數據。這對于DBA也都不奇怪,只是在用了mongo集群后沒享受到mongo的便利。當然,到了半夜負載下降,相當于oplog允許的操作時間變長了,也許不用停機。
如果有很多冗余數據、日志數據什么的,可以刪除,從而降低Initial Sync花費的時間,那也是很值得嘗試的!
坑的真正原因上面的坑,其實主要是在于oplog的值相對于數據量過小的時候會出現。一般默認情況下,oplog取磁盤大小的5%似乎沒太大問題。坑在哪呢?
磁盤擴容
高負載
一開始我就提到,oplog的存儲大小一旦確定是不會改的,也就是說,一旦隨著業務的發展,進行了磁盤擴容,或者移動到了一塊更大的硬盤上,oplog的大小不會隨之改變!
一旦兩件巧合的事情遇到了一起:磁盤曾經擴容且沒有額外考慮oplog;需要新增副本或者副本stale了;此時正常的機器只有一臺Primary;就會變成一件解決起來不那么輕松的事情了。
而高負載也是潛在的另外一個可能,由于負載過高,雖然oplog存儲很大,但是實際上oplog所支持的停機操作時間變少了,此時也會遇到相同的情況。
防坑指南總結一下,在用mongo副本集群的時候,隨著數據的增長、磁盤的擴容,一方面在考慮sharding的同時,一定要注意當前的oplog存儲是否夠用,提前為下一次部署策略更換準備好,給下一次的操作留夠時間。特別是Devops,平時沒時間管的,一定要未雨綢繆呀。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/18813.html
摘要:申明本文由筆者首發于深入淺出復制中文社區深入淺出復制由于自己開了,所以將之前比較好的文章挪過來便于大家瀏覽。新增由于網絡問題導致失敗重試機制。 申明 本文由筆者首發于InfoQ:《深入淺出MongoDB復制》MongoDB中文社區:《深入淺出MongoDB復制》 由于自己開了blog,所以將之前比較好的文章挪過來便于大家瀏覽。 綜述 筆者最近在生產環境中遇到許多復制相關問題,查閱網上資...
摘要:先睹為快振奮人心的時刻終于到來了,在經過一個上市的日子后,終于發布了。實戰在線開啟認證模式解讀我是上海小胖,專注等開源數據庫的,擁抱開源,接受收費。上海小胖原創地址歡迎各位大神前來評論。每周五,敬請期待,上海小胖獨更。 MongoDB 3.6 先睹為快 Part 1 振奮人心的時刻終于到來了,在經過一個MongoDB 上市的日子后,MongoDB 終于發布了MongoDB 3.6 RC...
摘要:先睹為快振奮人心的時刻終于到來了,在經過一個上市的日子后,終于發布了。實戰在線開啟認證模式解讀我是上海小胖,專注等開源數據庫的,擁抱開源,接受收費。上海小胖原創地址歡迎各位大神前來評論。每周五,敬請期待,上海小胖獨更。 MongoDB 3.6 先睹為快 Part 1 振奮人心的時刻終于到來了,在經過一個MongoDB 上市的日子后,MongoDB 終于發布了MongoDB 3.6 RC...
閱讀 1164·2021-09-10 10:51
閱讀 896·2019-08-30 15:53
閱讀 2724·2019-08-30 12:50
閱讀 976·2019-08-30 11:07
閱讀 1990·2019-08-30 10:50
閱讀 3598·2019-08-29 18:47
閱讀 1308·2019-08-29 18:44
閱讀 1599·2019-08-29 17:01