天天看點

Aerospike-Architecture系列之次索引Secondary Index(次索引)

Secondary Index(次索引)

次索引建立在非主鍵之上,給模型一個一對多關系的能力。索引的指定基于bin(類似RDBMS中的列)。允許高效更新并減少索引存儲資源的需求。

資料描述(DDL)被用于決定哪些bin和type被索引。索引可以通過工具或API動态建立或移除。類似RDBMS的模式,即使bin被DDL定義為索引,DDL也不進行資料校驗。更新索引bin的記錄時索引一起更新。

例如,索引隻能被建立在字元串(string)或整型上(integer)。考慮一下這種情況,一個bin存儲使用者年齡一個應用存儲為字元串類型另一個存儲正整型。整型索引将不包括字元串類型的記錄,字元串類型的索引也不包括整型的記錄。

次索引是這樣的:

  • 為快速查找存儲于記憶體中
  • 建立在叢集的每一個節點上。每個次索引條目包含指向本節點記錄位置的引用。
  • 次索引包含叢集中主記錄和複制記錄的指針

Data Structure

Aerospike-Architecture系列之次索引Secondary Index(次索引)

圖1  B-tree次索引

就像主索引一樣,次索引是一個在B-tree中的B-tree形式的哈希表。每個邏輯次索引擁有32個實體樹。當key被定義為索引操作,哈希函數用來決定索引條目建立在哪些實體樹上。辨別B-tree更新以後,注意一個次索引的鍵可以引用多個主記錄。結構的最底層是基于記錄數量的完整B-tree。

Index Management(索引管理)

Index Metadata(索引中繼資料)

Aerospike将索引建立資訊保留在特殊的全局維護的資料結構中-系統中繼資料(SMD)。系統中繼資料子產品位于多節點多次索引子產品中。次索引的變化最終由SMD觸發。

Aerospike-Architecture系列之次索引Secondary Index(次索引)

圖1 索引被系統中繼資料觸發

  1. 用戶端請求觸發 create / delete / update與次索引中繼資料由關的操作。請求通過次索引子產品到達SMD
  2. SMD發出對paxos master的請求
  3. Paxos master從叢集中所有節點請求相關的中繼資料資訊。當所有資料傳回,它調用次索引合并的回調函數。該函數負責分析元勝出的資料版本。
  4. 一旦為次索引确定了版本資訊,請求被發送到所有接節點來接受新的中繼資料資訊。
  5. 每個節點執行次索引create/delete DDL函數,然後觸發一個掃描并傳回用戶端。

Index Creation(索引建立)

Aerospike支援動态建立次索引。aql工具可以讀取目前可用的索引,并能夠建立和分布索引。

  1. 要建立次索引,使用者需要制定namespace, set, bin及索引類型(例如整型、字元串型)
  2. 從 SMD接收到确認每個節點以write-active模式建立次索引并啟動一個背景掃描作業,作業掃描所有資料并将條目插入次索引。
    • 索引條目隻有在記錄滿足所有索引制定條件的情況下才會被建立。
    • 次索引中的掃描作業與以完全相同的方式正常掃描的read/write事務互動,與正常掃描不同的是,索引掃描沒有網絡元件參與。在索引建立期間,所有新的影響索引屬性的寫操作都會更新索引。
  3. 索引建立掃描一完成所有的索引條目也就被建立了,索引立即準備用于查詢并被标記為read-active。
  4. 索引在所有節點建立成功以後,次索引對所有普通查詢有效。

Recommendations(建議)

  • 索引DDL (create/drop index)在叢集尚未形成或是叢集正在故障檢測時可能被忽略。索引的建立是I/O密集型操作,應該在低負載時進行。
  • 如果節點攜資料加入叢集,但錯過了索引定義,錯過的索引會被建立并加入叢集。在索引形成期間不允許查詢通路。為了避免在節點加入時出現這樣的情況應該在索引增長前進行清理。

Create Index Priority(建立索引的優先級)

索引建立掃描隻讀取應經被事務送出的記錄(沒有髒讀)。假設沒有記錄更新阻塞,掃描将全速執行。是以重要的優先級設定索引建構在正确的級别,以確定建立索引掃描不影響正在進行的讀和寫交易的延遲。Aerospike實時引擎中的作業優先級設定可以用來有效地控制建立索引掃描的資源使用率。預設參數應該滿足大多數情況,因為這基于多年的部署經驗,這些經驗來自于像再平衡與備份這樣的長事務與低延遲讀寫之間的平衡。

Writing data with indexes(帶索引的資料寫入)

當資料被寫入,目前索引的系統中繼資料 (SMD)被檢查。,次索引為所有帶索引的bin執行 update/insert/delete。注意Aerospike是一個flex-schema系統。如果對應的bin沒有值或者資料類型不合适,相應的下一個步驟不會被執行

所有這些次索引的變化在當記錄發生變化時被同步執行。由于索引是非持續的,送出索引與資料的困難送出問題沒有了,提高了速度。

Garbage Collection(垃圾回收)

為了删除次索引的條目,當主資料被删除(e.g delete/expiry/eviction/migration),資料将不能從磁盤讀入。這避免了不必要的I/O開銷。次索引條目會由一個定時喚起的背景線程進行清理。垃圾回收器被設計為非侵入式。它在一個小的批量中建立被删除條目的清單然後緩慢的從索引中删除。在系統中存在大量清理工作時,需要更多記憶體以适應垃圾回收。

Distributed Query(分布式查詢)

Aerospike-Architecture系列之次索引Secondary Index(次索引)

通過次索引的查詢請求被發送到每個叢集節點。圖B描述其基本架構,步驟如下:

  1. 分散請求到所有節點
  2. 記憶體中的索引快速映射到主鍵
  3. 索引與各節點SSD上的資料協作來保證ACID 并管理遷移
  4. 從所有 SSDs / DRAM并行讀取記錄
  5. 在各節點彙聚結果集
  6. 從所有節點整合結果集發送到用戶端

次索引查找一個非常長的主鍵記錄清單。出于這個原因我們選擇做小批量的次索引查找。也有一些在用戶端響應的批量,如果記憶體達到臨界值,響應立即被寫入網絡。這種行為就像Aerospike批處理請求的傳回值的情況。通常的想法是,不管請求的選擇度如何,保持一個獨立二次查找的記憶體為一個常數

Query Result(查詢結果)

查詢程序确認的結果,是與查詢記錄被掃描期間的真實資料同步的。不存在查詢執行過程中未送出的資料。然而可能傳回查詢期間被删除的資料。

In Presence of Cluster State Change(叢集狀态變化時的情況)

下面表格描述了次索引重建和查詢結果一緻性的場景

Scenario Persistent Namespace Boot Type Data-in-memory Secondary Index Population Node Boot Time Query Consistency during migrations
Node Joining With Data; Without Fast Restart False Post Data Load From Disk; Parallel Data Partition Scan Higher data load time than with no secondary index Best effort *
Node Joining With Data; With Fast Restart (Primary Key Index Available in Shared memory) False Post Fast Restart; Parallel Data Partition Scan ** Higher data load time than with no secondary index Best effort *
Node Joining With Data; Without Fast Restart True At the data load from disk No Signficant difference with and without Secondary Index Best effort *
Node Joining With No Data; Always Without Fast Restart True/False -NA- -NA- Consistent Copy
Node Leaving - NA - True/False -NA- -NA- Consistent Copy

Best Effort是資料的事務一緻的資料副本,不必是最新的(在記錄的副本中,在通過次索引查詢之前合并不會被執行)。在所有合并結束後副本最終一緻。

Fast restart  不支援 次索引

在通常的操作環境下,節點可以在被添加或移除時就被完全查詢可用。當遷移進行時,Aerospike照看從磁盤裝在資料是的資料負載(詳見結果一緻性表)

Query Node(查詢節點)

在資料遷移期間進行精确查詢非常複雜。當節點被添加到叢集或是從叢集移除時,會調用資料遷移子產品将資料轉換至新配置的适當節點。在遷移行動中,分區可能在很多節點上存在不同版本。為了通路到擁有查詢資料的分區位置。Aerospike利用其它叢集中在節點間共享的分區狀态查詢處理品質,并且每個可能被執行潮汛的分區選擇一個查詢節點。選擇分區的查詢節點基于很多因素(例如,分區中的記錄數,叢集中分區的副本數量等等)。系統設計的目标是查詢能夠得到最精确的結果。

Aggregations(彙聚)

查詢記錄可以提供給彙聚架構來執行過濾。每個節點上,查詢結果被發送到UDF子系統作為記錄流處理。使用者提及的UDF流将被調用,使用者定義的操作序列将被應用到查詢結果。各節點的結果由用戶端收集,也有可能執行其他資料操作。

Performance(性能)

為了確定彙聚不會影響資料庫整體性能,我們采用了多種技術:

全局隊列用來管理記錄通過處理的各個階段,線程池有效利用CPU并行能力。查詢狀态被線程池共享,使系統能夠正确管理流UDF管道。除了初始化資料,彙聚中的每個階段都是一個CPU綁定操作。是以各階段快速、優化的完成非常重要。為了達到這個目的,我們運用了類似記錄批量處理的技術,UDF狀态緩存等技術來優化實時海量記錄處理的系統上限。

此外,為了那些在資料存儲于記憶體中的namespace之上的操作(無存儲擷取),資料流處理實作在一個單獨的線程上下文中。即使在這種情況下,由于Aerospike原生的将資料劃分為固定數量的分區,系統仍然可以并行化操作跨分區的資料。

原文連結: <http://www.aerospike.com/docs/architecture/secondary-index.html>

譯          者:北京IT爺們兒

繼續閱讀