AppBoxFuture: 二級索引及索引掃描查詢數據

  數據庫索引對於數據查詢的重要性不可言喻,因此作者在存儲層實現了二級索引,以及利用索引進行掃描的功能。目前僅實現了分區表與非分區表的本地索引(數據與索引共用一個Raft組管理),全局索引及反向索引待以後再實現。

一、存儲結構:

  在介紹索引前先了解一下數據與索引是以何種結構存儲於RocksDB內的,每個節點的RocksDB實例都包含以下兩個ColumnFamily,每個列簇的存儲結構如下:

1. TableCF: 存儲實體數據

1.1 Key存儲編碼:

TableId(with OrderFlag) EntityId
32bit 128bit
  • OrderFlag用於EntityId按升序還是降序排列
  • EntityId包含實體創建時間戳,全局惟一

1.2 Value存儲編碼:

Versions GC Flag [VersionTS + DataPtr] [Data [FieldId + Value]]
15bit 1 bit Versions * (64+32bit) Versions * nbit
  • Versions表示該條記錄有多少個Mvcc版本
  • GC Flag表示第一個版本前是否被清理掉了
  • [VersionTS + DataPtr]其中VersionTS是混合邏輯時間戳,DataPtr指向此版本的數據位置,另外DataPtr=0xFFFFFFFF表示記錄刪除標記
  • 數據部分每100個(暫定)保存一個FullVersion的記錄數據,後跟差異部分

1.3 dbscan工具輸出示例:

2. IndexCF: 存儲索引數據

2.1 Key存儲編碼:

TableId IndexId IndexKey Values None unique index's EntityId
32bit 8bit [FieldId + Value] 128bit
  • IndexKey Values中的FieldId有一位是排序標誌位
  • None unique index's EntityID表示非惟一索引指向的目標,惟一索引存在於Value內

2.2 Value存儲編碼:

  與TableCF的Value編碼相同。

2.3 dbscan工具輸出示例:

二、索引管理:

  在新建實體模型及修改實體模型時均可添加與刪除索引(如下圖所示),需要注意的是修改模型時添刪索引會啓用異步任務變更表結構並重建索引數據(請參考之前的文章:異步結構變更),如果是重建惟一索引可能失敗,在實體模型設計器內可查看索引重建狀態。在索引重建過程中或重建失敗後利用索引掃描數據會直接報錯,告知索引尚未準備好。

三、索引掃描:

  不同於傳統Sql數據庫解析Sql後利用索引掃描,服務模型的代碼必須明確指定用哪個索引來查詢數據,具體參考以下示例代碼如何利用索引掃描數據:

public async Task<object> IndexScan()
{
    //新建索引掃描,範型參數1爲實體類型,參數2爲索引類型
    var q = new IndexScan<Entities.VehicleState, Entities.VehicleState.IX_VID_Speed>();
    //如果是分區表可通過分區謂詞指定分區掃描,非分區表無效
    q.Partitions.Equal(t => t.VID, 3);
    //可指定索引謂詞確定掃描範圍
    q.Keys.Equal(t => t.VID, 3);
    //如果是複合索引可指定其他索引謂詞
    q.Keys.Equal(t => t.Speed, 100);
    return await q.Take(10).ToListAsync();
}
  • 索引謂詞目前僅實現了相等性判斷,其他如大於、小於等稍後實現
  • 索引掃描的附加過濾條件尚未實現

  另如果需要插入一批測試數據可參考以下示例代碼:

public async Task<object> FillData()
{
    //第一個參數128表示並行任務數,第二個參數表示每個任務執行次數
    //作者虛擬機(I74C8G)執行以下代碼約每秒插入13000條記錄
    return await SimplePerfTest.Run(128, 500, async (i, j) =>
    {
        var obj = new Entities.VehicleState(i);
        obj.Speed = j;
        await EntityStore.SaveAsync(obj);
    });
}

四、本篇小結:

  本篇介紹數據及索引的存儲結構以及利用索引掃描api來查詢數據,下一步作者將實現其他謂詞條件,另外實現聚合掃描並優化單分區事務遞交。GitHub上的運行時已更新(包括dbscan工具)可供測試。如果您有問題或Bug報告,請留言或提交Issue,另外您的關注與點贊將是作者最大的動力。

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