IndexLib(8):索引类型:Normal、KV、KKV
发布于:
在上一篇文章中,我们深入了解了内存管理与资源控制的机制。本文将继续深入,详细解析索引类型的实现,这是理解 IndexLib 如何支持不同类型索引的关键。
索引类型概览:Normal、KV、KKV 三种索引类型的特点和应用场景:
flowchart TD
Start[索引类型体系] --> TypeLayer[索引类型层]
subgraph NormalGroup["NormalTable:标准表"]
direction TB
N1[支持全文检索<br/>倒排索引查询]
N2[支持属性查询<br/>正排索引查询]
N3[支持主键查询<br/>PrimaryKeyIndex]
N4[支持摘要查询<br/>SummaryReader]
N1 --> N2
N2 --> N3
N3 --> N4
end
subgraph KVGroup["KVTable:键值表"]
direction TB
K1[主键查询<br/>PrimaryKeyIndex]
K2[单值存储<br/>一个主键对应一个值]
K3[简单场景<br/>键值存储场景]
K1 --> K2
K2 --> K3
end
subgraph KKVGroup["KKVTable:键键值表"]
direction TB
KK1[主键+排序键查询<br/>PrimaryKey + SortKey]
KK2[多值存储<br/>一个主键对应多个值]
KK3[复杂场景<br/>多值存储场景]
KK1 --> KK2
KK2 --> KK3
end
TypeLayer --> NormalGroup
TypeLayer --> KVGroup
TypeLayer --> KKVGroup
NormalGroup --> Usage[使用场景]
KVGroup --> Usage
KKVGroup --> Usage
Usage --> U1[全文搜索场景<br/>NormalTable]
Usage --> U2[简单键值场景<br/>KVTable]
Usage --> U3[多值存储场景<br/>KKVTable]
style Start fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style TypeLayer fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style NormalGroup fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style N1 fill:#c5e1f5,stroke:#1976d2,stroke-width:1px
style N2 fill:#c5e1f5,stroke:#1976d2,stroke-width:1px
style N3 fill:#c5e1f5,stroke:#1976d2,stroke-width:1px
style N4 fill:#c5e1f5,stroke:#1976d2,stroke-width:1px
style KVGroup fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style K1 fill:#ffe0b2,stroke:#f57c00,stroke-width:1px
style K2 fill:#ffe0b2,stroke:#f57c00,stroke-width:1px
style K3 fill:#ffe0b2,stroke:#f57c00,stroke-width:1px
style KKVGroup fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
style KK1 fill:#c8e6c9,stroke:#2e7d32,stroke-width:1px
style KK2 fill:#c8e6c9,stroke:#2e7d32,stroke-width:1px
style KK3 fill:#c8e6c9,stroke:#2e7d32,stroke-width:1px
style Usage fill:#f5f5f5,stroke:#757575,stroke-width:2px
style U1 fill:#e0e0e0,stroke:#757575,stroke-width:1px
style U2 fill:#e0e0e0,stroke:#757575,stroke-width:1px
style U3 fill:#e0e0e0,stroke:#757575,stroke-width:1px
1. 索引类型概览
1.1 支持的索引类型
IndexLib 支持三种主要的索引类型:
- NormalTable:标准表,支持全文检索、倒排索引、正排索引等
- KVTable:键值表,支持主键查询,适用于简单的键值存储场景
- KKVTable:键键值表,支持主键+排序键查询,适用于多值存储场景
让我们先通过图来理解三种索引类型的区别:
索引类型对比:Normal、KV、KKV 的数据模型和查询方式:
flowchart TD
Start[索引类型对比] --> NormalTable[NormalTable<br/>标准表]
Start --> KVTable[KVTable<br/>键值表]
Start --> KKVTable[KKVTable<br/>键键值表]
subgraph NormalFeatures["NormalTable特性"]
direction TB
NF1[全文检索<br/>倒排索引]
NF2[属性查询<br/>正排索引]
NF3[主键查询<br/>PrimaryKeyIndex]
NF4[摘要查询<br/>SummaryReader]
NF1 --> NF2
NF2 --> NF3
NF3 --> NF4
end
subgraph KVFeatures["KVTable特性"]
direction TB
KF1[主键查询<br/>PrimaryKeyIndex]
KF2[单值存储<br/>一个主键对应一个值]
KF3[简单场景<br/>键值存储]
KF1 --> KF2
KF2 --> KF3
end
subgraph KKVFeatures["KKVTable特性"]
direction TB
KKF1[主键+排序键查询<br/>PrimaryKey + SortKey]
KKF2[多值存储<br/>一个主键对应多个值]
KKF3[复杂场景<br/>多值存储]
KKF1 --> KKF2
KKF2 --> KKF3
end
NormalTable --> NormalFeatures
KVTable --> KVFeatures
KKVTable --> KKVFeatures
style Start fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style NormalTable fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style NormalFeatures fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style NF1 fill:#c5e1f5,stroke:#1976d2,stroke-width:1px
style NF2 fill:#c5e1f5,stroke:#1976d2,stroke-width:1px
style NF3 fill:#c5e1f5,stroke:#1976d2,stroke-width:1px
style NF4 fill:#c5e1f5,stroke:#1976d2,stroke-width:1px
style KVTable fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style KVFeatures fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style KF1 fill:#ffe0b2,stroke:#f57c00,stroke-width:1px
style KF2 fill:#ffe0b2,stroke:#f57c00,stroke-width:1px
style KF3 fill:#ffe0b2,stroke:#f57c00,stroke-width:1px
style KKVTable fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
style KKVFeatures fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
style KKF1 fill:#c8e6c9,stroke:#2e7d32,stroke-width:1px
style KKF2 fill:#c8e6c9,stroke:#2e7d32,stroke-width:1px
style KKF3 fill:#c8e6c9,stroke:#2e7d32,stroke-width:1px
1.2 索引类型的选择
不同索引类型适用于不同的场景。让我们通过类图来理解三种索引类型的架构关系:
classDiagram
class ITabletFactory {
<<interface>>
+ CreateTabletWriter()
+ CreateTabletReader()
+ CreateMemSegment()
+ CreateDiskSegment()
}
class NormalTableFactory {
+ CreateTabletWriter()
+ CreateTabletReader()
}
class KVTableFactory {
+ CreateTabletWriter()
+ CreateTabletReader()
}
class KKVTableFactory {
+ CreateTabletWriter()
+ CreateTabletReader()
}
class NormalTabletReader {
- MultiFieldIndexReader _multiFieldIndexReader
- AttributeReader _attributeReader
- PrimaryKeyReader _primaryKeyReader
+ Search()
}
class KVTabletReader {
- KVIndexReader _kvIndexReader
- PackAttributeFormatter _formatter
+ Search()
}
class KKVTabletReader {
- KKVReader _kkvReader
- KKVIterator _iterator
+ Search()
}
ITabletFactory <|-- NormalTableFactory : 实现
ITabletFactory <|-- KVTableFactory : 实现
ITabletFactory <|-- KKVTableFactory : 实现
NormalTableFactory --> NormalTabletReader : 创建
KVTableFactory --> KVTabletReader : 创建
KKVTableFactory --> KKVTabletReader : 创建
索引类型的选择:
不同索引类型适用于不同的场景,选择合适的索引类型可以显著提高系统性能和降低复杂度:
- NormalTable:适用于全文检索、复杂查询、多字段查询等场景
- 全文检索:需要全文检索功能,支持倒排索引
- 复杂查询:需要范围查询、排序、聚合等复杂查询
- 多字段查询:需要多字段联合查询
- 灵活查询:需要灵活的查询方式,支持多种查询组合
- KVTable:适用于简单的键值存储、主键查询等场景
- 简单存储:只需要简单的键值存储,不需要复杂的索引
- 主键查询:主要查询方式是主键查询,查询性能要求高
- 高性能:需要高性能的主键查询,查询延迟要求低
- 简单使用:希望使用简单的接口,降低使用复杂度
- KKVTable:适用于多值存储、主键+排序键查询等场景
- 多值存储:一个主键需要对应多个值,通过排序键区分
- 排序键查询:需要根据排序键查询,支持精确查询和范围查询
- 有序存储:需要有序存储和查询,支持排序键排序
- 范围查询:需要排序键范围查询,支持范围扫描
2. NormalTable:标准表
2.1 NormalTable 的特点
NormalTable 是标准表,支持完整的索引功能:
NormalTable 的特点:支持全文检索、倒排索引、正排索引等:
flowchart TD
NormalTable[NormalTable<br/>标准表] --> Main
subgraph Main["主要组件"]
direction LR
A[倒排索引<br/>InvertedIndex<br/>全文检索]
B[正排索引<br/>AttributeIndex<br/>属性查询]
C[主键索引<br/>PrimaryKeyIndex<br/>主键查询]
end
NormalTable --> A
NormalTable --> B
NormalTable --> C
A --> Sub1
B --> Sub2
C --> Sub1
subgraph Sub["子组件"]
direction LR
Sub1[摘要索引<br/>SummaryIndex<br/>文档摘要]
Sub2[删除位图<br/>DeletionMap<br/>删除标记]
end
Sub --> Sub1
Sub --> Sub2
style NormalTable fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Main fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style A fill:#c5e1f5,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#64b5f6,stroke:#1976d2,stroke-width:1.5px
style Sub fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Sub1 fill:#ffe0b2,stroke:#f57c00,stroke-width:1.5px
style Sub2 fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
主要特点:
- 全文检索:支持倒排索引,实现全文检索
- 正排索引:支持正排索引,实现属性查询
- 主键索引:支持主键索引,实现主键查询
- 多字段查询:支持多字段联合查询
- 复杂查询:支持范围查询、排序、聚合等复杂查询
2.2 NormalTable 的架构
NormalTable 的架构:
NormalTable 的架构:NormalTabletReader、NormalTabletWriter 等组件:
flowchart TD
NormalTable[NormalTable<br/>标准表架构] --> Main
subgraph Main["主要组件"]
direction LR
A[NormalTabletReader<br/>读取器<br/>查询入口]
B[NormalTabletWriter<br/>写入器<br/>数据写入]
C[IndexReader<br/>索引读取器<br/>索引查询]
end
NormalTable --> A
NormalTable --> B
NormalTable --> C
A --> Sub1
B --> Sub2
C --> Sub1
subgraph Sub["子组件"]
direction LR
Sub1[AttributeReader<br/>属性读取器<br/>属性查询]
Sub2[SummaryReader<br/>摘要读取器<br/>文档摘要]
end
Sub --> Sub1
Sub --> Sub2
style NormalTable fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Main fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style A fill:#c5e1f5,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#64b5f6,stroke:#1976d2,stroke-width:1.5px
style Sub fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Sub1 fill:#ffe0b2,stroke:#f57c00,stroke-width:1.5px
style Sub2 fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
核心组件:
NormalTable 的架构采用组合模式,将不同的索引 Reader 组合在一起。让我们通过类图来理解详细的架构:
classDiagram
class NormalTabletReader {
- MultiFieldIndexReader _multiFieldIndexReader
- AttributeReader _attributeReader
- PrimaryKeyReader _primaryKeyReader
- SummaryReader _summaryReader
- DeletionMapReader _deletionMapReader
+ Search()
+ GetMultiFieldIndexReader()
+ GetAttributeReader()
}
class MultiFieldIndexReader {
- map_string_InvertedIndexReader _indexReaders
+ Search()
}
class AttributeReader {
- map_string_AttributeIndexReader _readers
+ ReadAttribute()
}
class PrimaryKeyReader {
- PrimaryKeyIndexReader _reader
+ Lookup()
}
NormalTabletReader --> MultiFieldIndexReader : 包含
NormalTabletReader --> AttributeReader : 包含
NormalTabletReader --> PrimaryKeyReader : 包含
核心组件详解:
- NormalTabletReader:标准表查询器,支持全文检索和属性查询
- 查询入口:提供统一的查询接口,支持 JSON 格式的查询
- 索引管理:管理各种索引 Reader,按需创建和缓存
- 结果合并:合并各种索引的查询结果,支持复合查询
- NormalTabletWriter:标准表写入器,支持文档构建和索引构建
- 文档构建:接收文档批次,构建索引
- 索引构建:构建倒排索引、正排索引、主键索引等
- 内存管理:管理构建时的内存使用,控制内存配额
- MultiFieldIndexReader:多字段倒排索引 Reader
- 多字段支持:支持多个字段的倒排索引查询
- 查询合并:合并多个字段的查询结果
- 性能优化:支持并行查询,提高查询性能
- AttributeReader:正排索引 Reader
- 属性查询:支持属性查询,快速获取文档属性
- 批量查询:支持批量查询属性,提高查询效率
- 缓存优化:支持属性缓存,减少 IO 操作
- PrimaryKeyReader:主键索引 Reader
- 主键查询:支持主键查询,快速定位文档
- 批量查询:支持批量主键查询,提高查询效率
- 性能优化:针对主键查询优化,查询延迟低
2.3 NormalTable 的查询
NormalTable 的查询方式:
NormalTable 的查询:全文检索、属性查询、主键查询等:
flowchart TD
NormalTable[NormalTable<br/>查询方式] --> Main
subgraph Main["主要查询方式"]
direction LR
A[全文检索<br/>FullTextSearch<br/>倒排索引查询]
B[属性查询<br/>AttributeQuery<br/>正排索引查询]
C[主键查询<br/>PrimaryKeyQuery<br/>主键索引查询]
end
NormalTable --> A
NormalTable --> B
NormalTable --> C
A --> Sub1
B --> Sub2
C --> Sub1
subgraph Sub["扩展查询方式"]
direction LR
Sub1[范围查询<br/>RangeQuery<br/>范围条件查询]
Sub2[聚合查询<br/>AggregationQuery<br/>数据聚合统计]
end
Sub --> Sub1
Sub --> Sub2
style NormalTable fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Main fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style A fill:#c5e1f5,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#64b5f6,stroke:#1976d2,stroke-width:1.5px
style Sub fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Sub1 fill:#ffe0b2,stroke:#f57c00,stroke-width:1.5px
style Sub2 fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
查询方式:
NormalTable 支持多种查询方式,可以灵活组合使用。让我们通过序列图来理解完整的查询流程:
sequenceDiagram
participant Client
participant NormalReader as NormalTabletReader
participant InvertedReader as MultiFieldIndexReader
participant AttributeReader as AttributeReader
participant PrimaryKeyReader as PrimaryKeyReader
participant ResultMerger as ResultMerger
Client->>NormalReader: Search(jsonQuery)
NormalReader->>NormalReader: 解析查询类型
alt 全文检索查询
NormalReader->>InvertedReader: Search(termQuery)
InvertedReader-->>NormalReader: DocIdList1
end
alt 属性查询
NormalReader->>AttributeReader: Filter(attrQuery)
AttributeReader-->>NormalReader: DocIdList2
end
alt 主键查询
NormalReader->>PrimaryKeyReader: Lookup(pk)
PrimaryKeyReader-->>NormalReader: DocId3
end
NormalReader->>ResultMerger: MergeResults([List1, List2, DocId3])
ResultMerger->>ResultMerger: 去重
ResultMerger->>ResultMerger: 排序
ResultMerger-->>NormalReader: MergedResult
NormalReader->>AttributeReader: ReadAttributes(MergedResult)
AttributeReader-->>NormalReader: Attributes
NormalReader->>NormalReader: 序列化为JSON
NormalReader-->>Client: jsonResult
查询方式详解:
- 全文检索:通过倒排索引进行全文检索
- Term 查询:通过 term 查询倒排索引,获取包含该 term 的文档列表
- 短语查询:支持短语查询,查询包含特定短语的文档
- 布尔查询:支持 AND、OR、NOT 等布尔查询
- 相关性排序:按相关性分数排序,返回最相关的文档
- 属性查询:通过正排索引进行属性查询
- 等值查询:支持属性等值查询,快速过滤文档
- 范围查询:支持属性范围查询,查询属性值在指定范围内的文档
- 多属性查询:支持多个属性的联合查询
- 属性排序:支持按属性值排序,返回排序后的文档
- 主键查询:通过主键索引进行主键查询
- 精确查询:通过主键精确查询,快速定位文档
- 批量查询:支持批量主键查询,提高查询效率
- 查询优化:针对主键查询优化,查询延迟低
- 复合查询:支持多种查询方式的组合
- 查询组合:可以组合全文检索、属性查询、主键查询等
- 查询优化:优化查询组合,减少不必要的查询
- 结果合并:合并各种查询的结果,支持去重、排序等
3. KVTable:键值表
3.1 KVTable 的特点
KVTable 是键值表,支持简单的键值存储:
KVTable 的特点:支持主键查询、简单的键值存储:
flowchart TD
KVTable[KVTable<br/>键值表] --> Main
subgraph Main["主要组件"]
direction LR
A[主键索引<br/>PrimaryKeyIndex<br/>主键查询]
B[键值存储<br/>KeyValueStorage<br/>键值对存储]
C[属性查询<br/>AttributeQuery<br/>属性条件查询]
end
KVTable --> A
KVTable --> B
KVTable --> C
A --> Sub1
B --> Sub2
C --> Sub1
subgraph Sub["子组件"]
direction LR
Sub1[打包属性<br/>PackAttribute<br/>属性打包存储]
Sub2[值读取器<br/>ValueReader<br/>值数据读取]
end
Sub --> Sub1
Sub --> Sub2
style KVTable fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Main fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style A fill:#c5e1f5,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#64b5f6,stroke:#1976d2,stroke-width:1.5px
style Sub fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Sub1 fill:#ffe0b2,stroke:#f57c00,stroke-width:1.5px
style Sub2 fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
主要特点:
- 主键查询:支持主键查询,快速定位数据
- 简单存储:简单的键值存储模型,易于使用
- 高性能:针对主键查询优化,查询性能高
- 属性查询:支持属性查询,可以查询指定属性
3.2 KVTable 的架构
KVTable 的架构:
KVTable 的架构:KVTabletReader、KVTabletWriter 等组件:
flowchart TD
KVTable[KVTable<br/>键值表架构] --> Main
subgraph Main["主要组件"]
direction LR
A[KVTabletReader<br/>KV读取器<br/>查询入口]
B[KVTabletWriter<br/>KV写入器<br/>数据写入]
C[KVIndexReader<br/>KV索引读取器<br/>索引查询]
end
KVTable --> A
KVTable --> B
KVTable --> C
A --> Sub1
B --> Sub2
C --> Sub1
subgraph Sub["子组件"]
direction LR
Sub1[PackAttributeFormatter<br/>打包属性格式化器<br/>属性格式化]
Sub2[ValueReader<br/>值读取器<br/>值数据读取]
end
Sub --> Sub1
Sub --> Sub2
style KVTable fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Main fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style A fill:#c5e1f5,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#64b5f6,stroke:#1976d2,stroke-width:1.5px
style Sub fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Sub1 fill:#ffe0b2,stroke:#f57c00,stroke-width:1.5px
style Sub2 fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
核心组件:
- KVTabletReader:KV 表查询器,支持主键查询
- KVTabletWriter:KV 表写入器,支持键值构建
- KVIndexReader:KV 索引 Reader,支持主键查询
- PackAttributeFormatter:打包属性格式化器,支持属性查询
3.3 KVTable 的查询
KVTable 的查询方式:
KVTable 的查询:主键查询、属性查询等:
flowchart LR
subgraph Query["查询接口层"]
A["主键查询<br/>PrimaryKeyQuery"]
B["批量主键查询<br/>BatchPrimaryKeyQuery"]
C["属性查询<br/>AttributeQuery"]
end
subgraph Read["数据读取层"]
D["值读取<br/>ValueRead<br/>读取完整值"]
E["属性读取<br/>AttributeRead<br/>读取指定属性"]
end
A -->|单主键定位| D
B -->|批量主键定位| D
B -->|指定属性| E
C -->|属性过滤| E
style Query fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Read fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style A fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
查询方式:
- 主键查询:通过主键快速定位数据
- 批量主键查询:支持批量主键查询,提高查询效率
- 属性查询:支持查询指定属性,减少数据传输
查询示例:
// table/kv_table/KVTabletReader.h
// JSON 查询格式
{
"pk": ["key1", "key2"], // 主键列表
"pkNumber": [123456, 623445], // 数字主键列表
"attrs": ["attr1", "attr2"], // 要查询的属性
"indexName": "kv1" // 索引名称
}
4. KKVTable:键键值表
4.1 KKVTable 的特点
KKVTable 是键键值表,支持主键+排序键查询:
KKVTable 的特点:支持主键+排序键查询、多值存储:
flowchart LR
subgraph Index["索引层"]
A["主键索引<br/>PrimaryKeyIndex<br/>定位主键"]
B["排序键索引<br/>SortKeyIndex<br/>排序键定位"]
end
subgraph Storage["存储层"]
C["多值存储<br/>MultiValueStorage<br/>一个主键多个值"]
end
subgraph Query["查询层"]
D["范围查询<br/>RangeQuery<br/>排序键范围"]
E["属性查询<br/>AttributeQuery<br/>指定属性"]
end
A -->|主键定位| C
B -->|排序键定位| C
A -->|主键+排序键| D
B -->|排序键范围| D
C -->|读取数据| E
style Index fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Storage fill:#c8e6c9,stroke:#388e3c,stroke-width:2px
style Query fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style A fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#a5d6a7,stroke:#388e3c,stroke-width:1.5px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
主要特点:
- 主键+排序键查询:支持主键+排序键查询,实现多值存储
- 多值存储:一个主键可以对应多个值,通过排序键区分
- 范围查询:支持排序键范围查询
- 属性查询:支持属性查询,可以查询指定属性
4.2 KKVTable 的架构
KKVTable 的架构:
KKVTable 的架构:KKVTabletReader、KKVTabletWriter 等组件:
flowchart LR
subgraph Read["读取组件"]
A["KKVTabletReader<br/>KKV表查询器<br/>主键+排序键查询"]
C["KKVReader<br/>KKV索引读取器<br/>索引查询"]
end
subgraph Write["写入组件"]
B["KKVTabletWriter<br/>KKV表写入器<br/>键键值构建"]
end
subgraph Support["支持组件"]
D["KKVIterator<br/>KKV迭代器<br/>范围查询迭代"]
E["ValueReader<br/>值读取器<br/>读取存储值"]
end
A -->|使用| D
A -->|使用| E
C -->|使用| D
C -->|使用| E
B -->|写入时读取| E
style Read fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Write fill:#c8e6c9,stroke:#388e3c,stroke-width:2px
style Support fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style A fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style B fill:#a5d6a7,stroke:#388e3c,stroke-width:1.5px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
核心组件:
- KKVTabletReader:KKV 表查询器,支持主键+排序键查询
- KKVTabletWriter:KKV 表写入器,支持键键值构建
- KKVReader:KKV 索引 Reader,支持主键+排序键查询
- KKVIterator:KKV 迭代器,支持范围查询
4.3 KKVTable 的查询
KKVTable 的查询方式:
KKVTable 的查询:主键+排序键查询、范围查询等:
flowchart LR
subgraph Query["查询类型"]
A["主键查询<br/>PrimaryKeyQuery<br/>查询所有值"]
B["主键+排序键查询<br/>PrimaryKey+SortKeyQuery<br/>精确查询"]
C["范围查询<br/>RangeQuery<br/>排序键范围"]
end
subgraph Support["查询能力"]
D["属性查询<br/>AttributeQuery<br/>指定属性"]
E["迭代器查询<br/>IteratorQuery<br/>范围迭代"]
end
A -->|可配合| D
B -->|可配合| D
C -->|使用| E
C -->|可配合| D
E -->|可配合| D
style Query fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Support fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style A fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
查询方式:
- 主键查询:通过主键查询所有值
- 主键+排序键查询:通过主键+排序键精确查询
- 范围查询:支持排序键范围查询
- 属性查询:支持查询指定属性
查询示例:
// table/kkv_table/KKVTabletReader.h
// JSON 查询格式
{
"pk": ["key1"], // 主键
"pkNumber": [123456], // 数字主键
"attrs": ["attr1", "attr2"], // 要查询的属性
"skey": ["skey1", "skey2"] // 排序键列表
}
5. 索引类型的实现差异
5.1 TabletReader 的实现差异
不同索引类型的 TabletReader 实现差异:
TabletReader 的实现差异:NormalTabletReader、KVTabletReader、KKVTabletReader:
flowchart LR
subgraph Reader["TabletReader 类型"]
A["NormalTabletReader<br/>标准表读取器<br/>全文检索+属性+主键"]
B["KVTabletReader<br/>键值表读取器<br/>主键查询"]
C["KKVTabletReader<br/>键键值表读取器<br/>主键+排序键"]
end
subgraph Component["核心组件"]
D["IndexReader<br/>索引读取器<br/>索引定位"]
E["AttributeReader<br/>属性读取器<br/>属性读取"]
end
A -->|使用| D
A -->|使用| E
B -->|使用| D
B -->|使用| E
C -->|使用| D
C -->|使用| E
style Reader fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Component fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style A fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
实现差异:
- NormalTabletReader:支持全文检索、属性查询、主键查询等多种查询方式
- KVTabletReader:主要支持主键查询,查询接口简化
- KKVTabletReader:支持主键+排序键查询,查询接口支持排序键
5.2 TabletWriter 的实现差异
不同索引类型的 TabletWriter 实现差异:
TabletWriter 的实现差异:NormalTabletWriter、KVTabletWriter、KKVTabletWriter:
flowchart TB
subgraph Writer["TabletWriter 类型"]
A["NormalTabletWriter<br/>标准表写入器"]
B["KVTabletWriter<br/>键值表写入器"]
C["KKVTabletWriter<br/>键键值表写入器"]
end
subgraph Build["构建流程"]
A1["文档构建<br/>DocumentBuilder<br/>倒排+正排+主键"]
B1["键值构建<br/>IndexBuilder<br/>主键索引"]
C1["键键值构建<br/>IndexBuilder<br/>主键+排序键"]
end
subgraph Output["构建输出"]
A2["NormalTable<br/>倒排索引+正排索引+主键索引"]
B2["KVTable<br/>主键索引+值存储"]
C2["KKVTable<br/>主键索引+排序键索引+多值存储"]
end
A -->|完整构建流程| A1
B -->|简化构建流程| B1
C -->|扩展构建流程| C1
A1 -->|生成| A2
B1 -->|生成| B2
C1 -->|生成| C2
style Writer fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Build fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style Output fill:#c8e6c9,stroke:#388e3c,stroke-width:2px
style A fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style B fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style C fill:#90caf9,stroke:#1976d2,stroke-width:1.5px
style A1 fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
style B1 fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
style C1 fill:#ffcc80,stroke:#f57c00,stroke-width:1.5px
style A2 fill:#a5d6a7,stroke:#388e3c,stroke-width:1.5px
style B2 fill:#a5d6a7,stroke:#388e3c,stroke-width:1.5px
style C2 fill:#a5d6a7,stroke:#388e3c,stroke-width:1.5px
实现差异:
- NormalTabletWriter:支持文档构建、倒排索引构建、正排索引构建等
- KVTabletWriter:主要支持键值构建,构建流程简化
- KKVTabletWriter:支持键键值构建,构建流程支持排序键
5.3 索引构建的差异
不同索引类型的索引构建差异:
索引构建的差异:Normal、KV、KKV 的索引构建流程:
flowchart TD
subgraph Main["主要组件"]
A["NormalTable构建<br/>倒排+正排+主键"]
B["KVTable构建<br/>主键索引"]
C["KKVTable构建<br/>主键+排序键"]
end
subgraph Sub["子组件"]
D["索引构建器<br/>IndexBuilder"]
E["文档构建器<br/>DocumentBuilder"]
end
A --> D
B --> E
C --> D
style Main fill:#e3f2fd
style Sub fill:#fff3e0
构建差异:
- NormalTable:需要构建倒排索引、正排索引、主键索引等多种索引
- KVTable:主要构建主键索引,构建流程简化
- KKVTable:构建主键索引和排序键索引,构建流程支持排序键
6. 索引类型的选择
6.1 选择 NormalTable 的场景
选择 NormalTable 的场景:
选择 NormalTable 的场景:全文检索、复杂查询等场景:
flowchart LR
subgraph Scene["NormalTable 适用场景"]
direction LR
A["全文检索场景<br/>FullTextSearch<br/>文本搜索需求"]
B["复杂查询场景<br/>ComplexQuery<br/>多条件组合查询"]
C["多字段查询场景<br/>MultiFieldQuery<br/>多字段联合查询"]
end
subgraph Feature["NormalTable 核心查询能力"]
direction LR
D["范围查询<br/>RangeQuery<br/>数值/时间范围"]
E["聚合查询<br/>AggregationQuery<br/>统计聚合"]
F["排序查询<br/>SortQuery<br/>结果排序"]
G["过滤查询<br/>FilterQuery<br/>条件过滤"]
end
Scene ==>|提供完整支持| Feature
style Scene fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Feature fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style G fill:#ffcc80,stroke:#f57c00,stroke-width:2px
适用场景:
- 全文检索:需要全文检索功能
- 复杂查询:需要范围查询、排序、聚合等复杂查询
- 多字段查询:需要多字段联合查询
- 灵活查询:需要灵活的查询方式
6.2 选择 KVTable 的场景
选择 KVTable 的场景:
选择 KVTable 的场景:简单的键值存储、主键查询等场景:
flowchart LR
subgraph Scene["KVTable 适用场景"]
direction LR
A["简单存储场景<br/>SimpleStorage<br/>键值存储需求"]
B["主键查询场景<br/>PrimaryKeyQuery<br/>主键快速查询"]
C["高性能场景<br/>HighPerformance<br/>高性能要求"]
end
subgraph Feature["KVTable 核心能力"]
direction LR
D["键值存储<br/>KeyValueStorage<br/>简单键值对"]
E["快速查询<br/>FastQuery<br/>主键定位"]
F["简化接口<br/>SimpleInterface<br/>易于使用"]
end
Scene ==>|提供| Feature
style Scene fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Feature fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
适用场景:
- 简单存储:只需要简单的键值存储
- 主键查询:主要查询方式是主键查询
- 高性能:需要高性能的主键查询
- 简单使用:希望使用简单的接口
6.3 选择 KKVTable 的场景
选择 KKVTable 的场景:
选择 KKVTable 的场景:多值存储、主键+排序键查询等场景:
flowchart LR
subgraph Scene["KKVTable 适用场景"]
direction LR
A["多值存储场景<br/>MultiValueStorage<br/>一主键多值"]
B["排序键查询场景<br/>SortKeyQuery<br/>主键+排序键"]
C["范围查询场景<br/>RangeQuery<br/>排序键范围"]
end
subgraph Feature["KKVTable 核心能力"]
direction LR
D["有序存储<br/>OrderedStorage<br/>排序键有序"]
E["迭代器查询<br/>IteratorQuery<br/>范围迭代"]
F["多值管理<br/>MultiValueManagement<br/>值集合管理"]
end
Scene ==>|提供| Feature
style Scene fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Feature fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
适用场景:
- 多值存储:一个主键需要对应多个值
- 排序键查询:需要根据排序键查询
- 范围查询:需要排序键范围查询
- 有序存储:需要有序存储和查询
7. 索引类型的性能对比
7.1 查询性能对比
不同索引类型的查询性能对比:
查询性能对比:Normal、KV、KKV 的查询性能特点:
flowchart TB
subgraph Type["索引类型"]
direction LR
A["NormalTable<br/>标准表<br/>全文检索性能高"]
B["KVTable<br/>键值表<br/>主键查询性能最高"]
C["KKVTable<br/>键键值表<br/>主键+排序键性能高"]
end
subgraph Query["查询场景性能"]
direction LR
D["全文检索<br/>FullTextSearch<br/>NormalTable 高"]
E["主键查询<br/>PrimaryKeyQuery<br/>KVTable 最高"]
F["主键+排序键<br/>PK+SortKeyQuery<br/>KKVTable 高"]
G["范围查询<br/>RangeQuery<br/>KKVTable 中等"]
H["复杂查询<br/>ComplexQuery<br/>NormalTable 中等"]
end
A -->|擅长| D
A -->|支持| H
B -->|最优| E
C -->|擅长| F
C -->|支持| G
style Type fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Query fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style G fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style H fill:#ffcc80,stroke:#f57c00,stroke-width:2px
性能特点:
- NormalTable:全文检索性能高,复杂查询性能中等
- KVTable:主键查询性能最高,查询延迟最低
- KKVTable:主键+排序键查询性能高,范围查询性能中等
7.2 存储性能对比
不同索引类型的存储性能对比:
存储性能对比:Normal、KV、KKV 的存储性能特点:
flowchart TB
subgraph Type["索引类型"]
direction LR
A["NormalTable<br/>存储空间:较大<br/>需要多种索引"]
B["KVTable<br/>存储空间:较小<br/>只需主键索引"]
C["KKVTable<br/>存储空间:中等<br/>主键+排序键索引"]
end
subgraph Storage["存储组成"]
direction LR
D["倒排索引<br/>InvertedIndex<br/>NormalTable 需要"]
E["正排索引<br/>ForwardIndex<br/>NormalTable 需要"]
F["主键索引<br/>PrimaryKeyIndex<br/>三种都需要"]
G["排序键索引<br/>SortKeyIndex<br/>KKVTable 需要"]
H["数据存储<br/>DataStorage<br/>三种都需要"]
end
A -->|包含| D
A -->|包含| E
A -->|包含| F
A -->|包含| H
B -->|包含| F
B -->|包含| H
C -->|包含| F
C -->|包含| G
C -->|包含| H
style Type fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Storage fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style G fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style H fill:#ffcc80,stroke:#f57c00,stroke-width:2px
存储特点:
- NormalTable:存储空间较大,需要存储多种索引
- KVTable:存储空间较小,只需要存储主键索引
- KKVTable:存储空间中等,需要存储主键和排序键索引
7.3 构建性能对比
不同索引类型的构建性能对比:
构建性能对比:Normal、KV、KKV 的构建性能特点:
flowchart TB
subgraph Type["索引类型"]
direction LR
A["NormalTable<br/>构建时间:较长<br/>需要构建多种索引"]
B["KVTable<br/>构建时间:最短<br/>构建流程简化"]
C["KKVTable<br/>构建时间:中等<br/>主键+排序键索引"]
end
subgraph Build["构建流程"]
direction LR
D["文档构建<br/>DocumentBuild<br/>NormalTable 需要"]
E["倒排索引构建<br/>InvertedIndexBuild<br/>NormalTable 需要"]
F["正排索引构建<br/>ForwardIndexBuild<br/>NormalTable 需要"]
G["主键索引构建<br/>PrimaryKeyIndexBuild<br/>三种都需要"]
H["排序键索引构建<br/>SortKeyIndexBuild<br/>KKVTable 需要"]
end
A -->|包含| D
A -->|包含| E
A -->|包含| F
A -->|包含| G
B -->|包含| G
C -->|包含| G
C -->|包含| H
style Type fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Build fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style G fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style H fill:#ffcc80,stroke:#f57c00,stroke-width:2px
构建特点:
- NormalTable:构建时间较长,需要构建多种索引
- KVTable:构建时间最短,构建流程简化
- KKVTable:构建时间中等,需要构建主键和排序键索引
8. 索引类型的扩展
8.1 自定义索引类型
IndexLib 支持自定义索引类型:
自定义索引类型:通过实现接口扩展索引类型:
flowchart TB
subgraph Step["扩展步骤"]
direction LR
A["实现 TabletReader<br/>自定义读取器<br/>实现查询接口"]
B["实现 TabletWriter<br/>自定义写入器<br/>实现写入接口"]
C["实现索引构建<br/>自定义构建逻辑<br/>实现构建流程"]
end
subgraph Action["扩展操作"]
direction LR
D["注册索引类型<br/>RegisterType<br/>注册到系统"]
E["扩展接口<br/>ExtendInterface<br/>扩展查询能力"]
F["配置索引类型<br/>ConfigureType<br/>配置参数"]
end
A -->|完成后| D
B -->|完成后| D
C -->|完成后| D
D -->|支持| E
D -->|需要| F
style Step fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Action fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
扩展方式:
- 实现 TabletReader:实现自定义的 TabletReader
- 实现 TabletWriter:实现自定义的 TabletWriter
- 实现索引构建:实现自定义的索引构建逻辑
- 注册索引类型:注册自定义索引类型
8.2 索引类型的演进
索引类型的演进:
索引类型的演进:从 Normal 到 KV、KKV 的演进过程:
flowchart LR
subgraph Evolution["索引类型演进"]
direction LR
A["NormalTable<br/>最早版本<br/>完整功能支持"]
B["KVTable<br/>简单场景优化<br/>主键查询优化"]
C["KKVTable<br/>多值存储优化<br/>排序键支持"]
end
subgraph Optimization["优化方向"]
direction LR
D["功能演进<br/>FeatureEvolution<br/>功能扩展"]
E["性能优化<br/>PerformanceOptimization<br/>查询性能提升"]
F["场景优化<br/>ScenarioOptimization<br/>特定场景优化"]
end
A -->|演进| B
B -->|演进| C
A -.->|带来| D
B -.->|带来| E
C -.->|带来| F
style Evolution fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Optimization fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
演进过程:
- NormalTable:最早的索引类型,支持完整的索引功能
- KVTable:针对简单场景优化的索引类型
- KKVTable:针对多值存储场景优化的索引类型
9. 索引类型的关键设计
9.1 统一的接口设计
索引类型的统一接口设计:
统一的接口设计:ITabletReader、ITabletWriter 等统一接口:
flowchart TB
subgraph Interface["统一接口层"]
direction LR
A["ITabletReader<br/>统一查询接口<br/>定义查询规范"]
B["ITabletWriter<br/>统一写入接口<br/>定义写入规范"]
C["ITabletSchema<br/>统一Schema接口<br/>定义Schema规范"]
end
subgraph Implementation["接口实现层"]
direction LR
D["NormalTable实现<br/>完整功能实现"]
E["KVTable实现<br/>简化功能实现"]
F["KKVTable实现<br/>扩展功能实现"]
end
A -->|实现| D
A -->|实现| E
A -->|实现| F
B -->|实现| D
B -->|实现| E
B -->|实现| F
C -->|实现| D
C -->|实现| E
C -->|实现| F
style Interface fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Implementation fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
设计要点:
- ITabletReader:统一的查询接口,不同索引类型实现不同的查询逻辑
- ITabletWriter:统一的写入接口,不同索引类型实现不同的构建逻辑
- ITabletSchema:统一的 Schema 接口,不同索引类型有不同的 Schema 配置
9.2 灵活的扩展设计
索引类型的灵活扩展设计:
灵活的扩展设计:支持自定义索引类型和扩展功能:
flowchart TB
subgraph Design["扩展设计机制"]
direction LR
A["接口抽象<br/>InterfaceAbstraction<br/>统一接口定义"]
B["插件机制<br/>PluginMechanism<br/>动态加载扩展"]
C["配置驱动<br/>ConfigurationDriven<br/>配置选择类型"]
end
subgraph Extension["扩展能力"]
direction LR
D["类型扩展<br/>TypeExtension<br/>自定义索引类型"]
E["功能扩展<br/>FeatureExtension<br/>扩展查询功能"]
F["接口扩展<br/>InterfaceExtension<br/>扩展接口能力"]
end
A -->|支持| D
A -->|支持| F
B -->|支持| D
B -->|支持| E
C -->|支持| D
style Design fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Extension fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
设计要点:
- 接口抽象:通过接口抽象支持不同的索引类型实现
- 插件机制:支持通过插件机制扩展索引类型
- 配置驱动:通过配置驱动选择不同的索引类型
9.3 性能优化设计
索引类型的性能优化设计:
性能优化设计:针对不同索引类型的性能优化策略:
flowchart TB
subgraph Strategy["优化策略"]
direction LR
A["针对性优化<br/>TargetedOptimization<br/>针对索引类型特点"]
B["查询优化<br/>QueryOptimization<br/>优化查询路径"]
C["构建优化<br/>BuildOptimization<br/>优化构建流程"]
end
subgraph Optimization["优化手段"]
direction LR
D["性能调优<br/>PerformanceTuning<br/>提升查询性能"]
E["资源优化<br/>ResourceOptimization<br/>降低资源消耗"]
F["索引优化<br/>IndexOptimization<br/>优化索引结构"]
end
A -->|采用| D
A -->|采用| F
B -->|采用| D
B -->|采用| F
C -->|采用| E
C -->|采用| F
style Strategy fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style Optimization fill:#fff3e0,stroke:#f57c00,stroke-width:3px
style A fill:#90caf9,stroke:#1976d2,stroke-width:2px
style B fill:#90caf9,stroke:#1976d2,stroke-width:2px
style C fill:#90caf9,stroke:#1976d2,stroke-width:2px
style D fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style E fill:#ffcc80,stroke:#f57c00,stroke-width:2px
style F fill:#ffcc80,stroke:#f57c00,stroke-width:2px
设计要点:
- 针对性优化:针对不同索引类型的特点进行性能优化
- 查询优化:优化查询路径,提高查询性能
- 构建优化:优化构建流程,提高构建效率
10. 性能优化与最佳实践
10.1 索引类型选择优化
选择策略:
- 场景分析:
- 查询模式:分析查询模式,选择最适合的索引类型
- 数据特征:分析数据特征,选择最适合的索引类型
- 性能要求:根据性能要求选择索引类型
- 性能权衡:
- 功能 vs 性能:权衡功能需求和性能要求
- 存储 vs 查询:权衡存储空间和查询性能
- 构建 vs 查询:权衡构建性能和查询性能
- 混合使用:
- 多索引类型:可以同时使用多种索引类型
- 索引组合:组合使用不同的索引类型,满足不同需求
- 索引切换:根据场景切换索引类型
10.2 查询性能优化
优化策略:
- NormalTable 优化:
- 索引优化:优化倒排索引和正排索引的结构
- 查询优化:优化查询路径,减少不必要的查询
- 结果优化:优化结果合并,提高合并效率
- KVTable 优化:
- 主键优化:优化主键索引结构,提高查询性能
- 批量优化:优化批量主键查询,提高查询效率
- 缓存优化:优化主键查询缓存,减少查询延迟
- KKVTable 优化:
- 排序键优化:优化排序键索引结构,提高查询性能
- 范围查询优化:优化范围查询,提高查询效率
- 迭代器优化:优化迭代器实现,减少迭代开销
10.3 构建性能优化
优化策略:
- NormalTable 构建优化:
- 并行构建:并行构建多个索引,提高构建速度
- 索引优化:优化索引构建算法,减少构建时间
- 内存优化:优化内存使用,减少构建内存占用
- KVTable 构建优化:
- 简化构建:简化构建流程,减少构建时间
- 批量构建:批量构建键值对,提高构建效率
- 压缩优化:优化数据压缩,减少存储空间
- KKVTable 构建优化:
- 排序键优化:优化排序键构建,提高构建效率
- 批量构建:批量构建键键值对,提高构建效率
- 索引优化:优化索引结构,减少构建时间
11. 小结
索引类型是 IndexLib 的核心功能,通过 NormalTable、KVTable、KKVTable 三种类型支持不同的应用场景。通过本文的深入解析,我们了解到:
核心类型:
- NormalTable:标准表,支持全文检索、倒排索引、正排索引等,适用于全文检索和复杂查询场景
- 功能完整:支持全文检索、属性查询、主键查询等多种查询方式
- 灵活查询:支持复杂的查询组合,满足各种查询需求
- 性能平衡:在功能和性能之间取得平衡,适合通用场景
- KVTable:键值表,支持主键查询,适用于简单的键值存储场景,查询性能高
- 简单高效:简单的键值存储模型,查询性能高
- 主键优化:针对主键查询优化,查询延迟低
- 存储优化:存储空间小,构建速度快
- KKVTable:键键值表,支持主键+排序键查询,适用于多值存储场景,支持范围查询
- 多值存储:一个主键可以对应多个值,通过排序键区分
- 范围查询:支持排序键范围查询,支持有序存储和查询
- 性能优化:针对主键+排序键查询优化,查询性能高
设计亮点:
- 统一接口设计:通过 ITabletReader 和 ITabletWriter 统一接口,支持不同的索引类型实现
- 工厂模式:通过工厂模式创建不同类型的 Tablet,便于扩展和维护
- 策略模式:不同索引类型采用不同的查询和构建策略,针对性强
- 性能优化:针对不同索引类型的特点进行性能优化,提高系统性能
- 灵活扩展:支持自定义索引类型和扩展功能,满足特殊需求
性能特点:
- 查询性能:KVTable 主键查询性能最高,延迟较低;NormalTable 全文检索性能高,延迟较低
- 存储空间:KVTable 存储空间最小,NormalTable 存储空间最大
- 构建性能:KVTable 构建速度最快,NormalTable 构建速度较慢
- 功能完整性:NormalTable 功能最完整,KVTable 功能最简单
理解索引类型,是掌握 IndexLib 索引功能的关键。在下一篇文章中,我们将深入介绍 Locator 与数据一致性的实现细节,包括 Locator 的完整结构、比较逻辑、更新机制、数据一致性保证等各个方面的实现原理和性能优化策略。