問題
帶着問題擼源碼系列-zookeeper-內存的數據如何持久化到硬盤
猜測
這種一般都是有個定時任務往硬盤寫吧
源碼
吸取經驗,直接從底層打斷點最舒服,直接摟出調用棧美美噠。
於是我們開始猜哪個是寫硬盤的類。
摟了一遍,大膽猜測是這個:
org.apache.zookeeper.common.AtomicFileOutputStream
斷點打起來
debug
客戶端發起寫請求,create /w1
沒有停在斷點。。
看來找錯地方了。
再猜:org.apache.zookeeper.server.ByteBufferOutputStream
也不對。。
org.apache.zookeeper.server.persistence.FileSnap#serialize(org.apache.zookeeper.server.DataTree, java.util.Map<java.lang.Long,java.lang.Integer>, java.io.File, boolean)
這個很有信心!
還是不對。。
好像又沒招了。。看來自底向上是不行了。
那再來自頂向下?
從啓動過程開始看:找到了定時purge清除的地方:
好吧我投降了,上網搜到是這樣的:http://www.guobingwei.tech/articles/2019/04/01/1554076444476.html
在zkDatabase.append裏整的
終究還是網上的大哥牛皮:
看調用棧,是SyncRequestProcessor調用的。
將請求寫到硬盤。將請求batch了,提升io效率。只有寫完硬盤纔會將請求pass到下一個requestProcessor
3個不同的case會用到:
1、Leader: 同步請求到硬盤,轉發到AckRequestProcessor, 然後AckRequestProcessor 又發ack發回來
2、Follower:同步請求到硬盤,轉發到SendAckRequestProcessor, AckRequestProcessor發包給leader。AckRequestProcessor 是flushable的,允許我們強行推送packet給leader
3、Observer先不管了。