前言
本文聚焦client-go v11.0.0 controller框架Indexer對象,分析源碼indexer的實現(xiàn)。關于client-go的介紹已有優(yōu)秀文章雇卷,可參考第一篇參考文檔洪橘,本文不再贅述。
1 cache - indexer對象關系
golang的struct和interface之間是弱耦合關系帚戳,即struct只需要實現(xiàn)了某個interface的所有方法玷或,就認為該struct實現(xiàn)了該interface。cache和Store對象關系如下:
從類的實現(xiàn)片任、組合關系上可見偏友,cache實現(xiàn)了Store interface和Index interface的所有方法,因此cache可以賦值給Store和Index接口对供。理解threadSafeMap的實現(xiàn)能幫助我們理解cache位他。
2 理解threadSafeMap的實現(xiàn)
幾個內部索引對象及其關系
type IndexFunc func(obj interface) ([]string, error)
type Indexers map[string]indexFunc
type Index map[string]sets.String
type indices map[string]Index
從上述幾個對象的命名和關系看,很難理解幾個對象的依賴關系产场。我們首先梳理幾個對象之間的關系鹅髓,其次分析一個pod對象的增、刪京景、改時窿冯,幾個索引對象的狀態(tài)遷移如何發(fā)生。
2.1 threadSafeMap內部對象關系
Items:
Items類型map[string] interface{}确徙,用來存儲runtime.object醒串,map的key(對象鍵)用函數(shù)MetaNamespaceKeyFunc生成,value是runtime.object本身鄙皇。
Indexers:
indexers類型是map[string]indexFunc芜赌,用來存儲indexFunc(索引鍵計算函數(shù)),map的key是indexFuncName伴逸,value是indexFunc缠沈。注意兩個要點:1. 區(qū)別對象鍵和索引鍵;2. {indexName: indexFunc}是外部調用者傳入错蝴,調用關系參考k8s源碼: kubernetes-master\pkg\client\informers\informers_generated\internalversion\extensions\internalversion\deployment.go:
cache.MetaNamespaceIndexFunc函數(shù)注釋:
// MetaNamespaceIndexFunc is a default index function that indexes based on an object's namespace.
Indices:
Indices類型map[string]Index博烂。indices是對象快速索引表,map的key是indexName漱竖,value是Index對象禽篱,即map[string]sets.String。
Index:
Index類型map[string]sets.String馍惹。Index map的key是indexFunc計算的值躺率,如MetaNamespaceIndexFunc返回的是namespace,如果使用indexByPodNodeName(源碼:kubernetes-master\pkg\controller\daemon\daemon_controller.go)那么返回nodename万矾。
indexSet:
IndexSet是筆者自己取的名字悼吱。IndexSet是set.String類型,值是對象鍵objkey良狈。
到此為止后添,相信細心的讀者可能會發(fā)現(xiàn),threadSafeMap做了兩件事:
1)存儲:保存k8s runtime.object到items map薪丁。
2)索引:為items map的每個對象建立三層索引:第一層是indices map的類別索引遇西,如按'namespace', 'nodeName'索引馅精;第二層是index map的詳細類別索引,如'namespace1','namespace2'… 或者'nodeName1','nodeName2'……粱檀;第三層是indexSet的對象鍵洲敢。第三層索引才真正索引到runtime.object。
2.2 threadSafeMap關鍵實現(xiàn)分析
以兩個典型的方法func (c *threadSafeMap) updateIndices(oldObj interface{}, newObj interface{}, key string)和func (c *threadSafeMap) deleteFromIndices(obj interface{}, key string)為例分析threadSafeMap內部對象的狀態(tài)遷移過程茄蚯。
deleteFromIndices被Delete压彭,updateIndices等函數(shù)調用,它的功能是刪除indices的某個索引渗常。deleteFromIndices函數(shù)執(zhí)行步驟如下:
1)遍歷indexFunc map c.indexers獲取第一層索引indices的類別name壮不,并計算第二層索引index的詳細索引類別indexValue;
2)遍歷第二層索引表index,依次刪除第三層索引表indexSet的對象鍵皱碘。
updateIndices函數(shù)被Add忆畅,Update,Replace等函數(shù)調用尸执。updateIndices執(zhí)行步驟如下:
1)updateIndices函數(shù)首先刪除oldObj的索引鍵家凯;
2)遍歷indexFunc map c.indexers,獲取第一層索引indices的索引類別name如失,并計算第二層索引Index的詳細索引類別indexValues(數(shù)組)绊诲;
3)遍歷第二層索引Index,依次執(zhí)行:若第三層索引IndexSet為空則添加一個空set褪贵;若非空則添加對象鍵到第三層索引IndexSet掂之。
3 結語
到此為止threadSafeMap的機制基本分析清楚,cache無非threadSafeMap的封裝和擴展脆丁,核心機制是一樣的世舰,就不再細說 。
4 參考文檔
http://www.reibang.com/p/d17f70369c35
https://blog.csdn.net/weixin_42663840/article/details/81530606