LDAP搜索底層邏輯

一,ldap基本模型


DIT : ldap的樹結構,每個樹上的節點叫entry
DN (Distinguished
Name):從特定節點到樹的根的直接下級的節點的路徑序列爲DN,區別於其他節點的名字,相當於節點的絕對路徑,由不同部分的rdn組成
RDN(Relative Distinguished Name): 區別於同層節點的名字叫RDN,相當於相對路徑
Attribute:每個節點屬性都有相應的value,存放在文件中
objectClass: 對象類(ObjectClass)是屬性的集合,LDAP預想了很多人員組織機構中常見的對象,並將其封裝成對象類。
schema: 對象類、屬性類型、語法分別約定了條目、屬性、值。這些構成了模式(Schema),模式中的每一個元素都有唯一的OID編號


Cursor:遊標,指向查找的目前節點,有向前插入和向後插入兩種方式,通過此遊標可以存/取/刪除數據項
search scope :查詢範圍,默認有三種。baseObject:作用域僅限於由命名的條目; singleLevel:baseobject的直接子節點一層; wholeSubtree: baseObject及其所有子樹集合
search filter:分10種操作情況,分爲相應的過濾器
and/or/not/equalityMatch/substrings/greaterOrEqual/lessOrEqual/present/approcMarch/extensibleMatch
filterextensible
= ( attr [dnattrs]
[matchingrule] COLON EQUALS assertionvalue )
/ ( [dnattrs]
matchingrule COLON EQUALS assertionvalue )

 

二,底層搜索操作

下圖是apacheds和fortress的關係結構圖,有助於我們瞭解整體架構


執行搜索權限時的操作
客戶端通過guardian插件,經過guardian接入apacheds,通過傳入的perm數據會在後端提取信息並通過這些信息(datasource和component)得到一個自己具有唯一可區別的名稱Dn(getDn),對應於ladp目錄樹的一個節點,保存在permObjDn中。


根據perm數據的prefix,substring,action形成一個過濾器字符串存在filterbuf中,scope和cookie單獨作爲過濾條件傳到search部分。
於此同時拉取存在緩存中的該用戶對應的role和group權限,一併合併到filterbuf字段中。


將所有的過濾信息構建一個searchcursor,每次把符合條件的當前節點解析到perm中,然後pop出去,進行下一輪查找,最後形成一個permlist


有繼承的情況會包裝成一個組,然後照上面的邏輯再進行一次perm的查詢過濾。ldap把請求信息封裝成一個searchRequest, 具體結構見鏈接: https://tools.ietf.org/html/rfc4511


然後經過攔截器,apacheds總共有14個攔截器,search操作一共7個,每個Interceptor的調用會依據它的聲明順序依次執行。
然後接入ldap底層的lmdb,ldap的底層數據庫用的是LMDB搜索操作,先通過優化器優化查詢語句(通過scan count字段,把索引關聯比較少的查詢節點放在前面)然後根據屬性的匹配原則來定義evaluator,在cursor移動時執行設定的evaluate操作,實現節點過濾。最後根據節點的dn長度和接收請求的sortkey來確定返回順序。

三,ldap底層數據庫


LMDB的全稱是LightningMemory-Mapped Database,即閃電般的內存映射數據庫。它文件結構簡單,一個文件夾,裏面一個數據文件,一個鎖文件。數據隨意複製,隨意傳輸。它的訪問簡單,不需要運行單獨的數據庫管理進程,只要在訪問數據的代碼裏引用LMDB庫,訪問時給文件路徑即可。基於文件映射IO和B+樹的key-value接口。通過mvcc事務處理保證讀取內容不被修改,進行目錄訪問。


lmdb使用mmap,同時在創建env對象時,數據庫已經被整個映射進整個進程空間,因此係統在映射時,會給數據庫文件保留全部地址空間,從而在根據上述算法獲取真實數據庫,系統觸發缺頁錯誤,進而從數據文件中獲取整個頁面內容。

cursor對象是進行所有數據庫操作的對象,讀寫都是基於遊標進行。進行讀寫操作時,首先需要根據條件確定頁面位置,從而獲得一個遊標,應用程序根據遊標對象操作數據庫。

搜索階段分爲頁搜索和cursor搜索,時從B-Tree根節點檢索,根據key的值,從根節點開始遍歷子樹獲取每一層對應的page,在page之內檢索key,再根據B-Tree查找方法確定下一層子節點的page,層層遍歷,從而最終確定key的位置或者判斷B-Tree中沒有對應的key。同時將頁面存放到cursor頁堆棧中。這樣cursor將可以重用對應的頁面,爲後續進行更新等操作提供便利。


lmdb的結構與底層搜索參照:http://wiki.dreamrunner.org/public_html/C-C++/Library-Notes/LMDB.html

參考文獻: Chu H. MDB: A memory-mapped database and backend for OpenLDAP[C]//Proceedings of the 3rd International Conferenceon LDAP, Heidelberg, Germany. 2011: 35.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章