从内存到 ES:.NET 企业级向量检索架构演进之路

CSDN 技术教程系列:文本与向量检索实战(.NET C# 体系)

系列主题:从内存到 Elasticsearch ------ .NET C# 体系下的文本、向量检索技术演进与应用实例教程

目标读者:中高级 .NET 后端开发工程师、AI应用开发者、技术架构师

技术栈:.NET 8/9、C# 12、ONNX Runtime、BGE-M3、CLIP、Elasticsearch、Python Flask


📚 文章系列规划(共5篇)

序号 文章标题 核心技术
1 [BGE-M3 多语言向量模型实战:.NET C# 从原理到落地](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) BGE-M3、ONNX Runtime、Tokenizer
2 [内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) 内存计算、读写锁、并行检索
3 [Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) ES 8.x、Dense Vector、Hybrid Search
4 [CLIP 多模态搜索实战:.NET + Python 跨语言图片检索](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) OpenCLIP、Python Flask、跨模态
5 [从内存到 ES:.NET 企业级向量检索架构演进之路](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) 架构设计、性能优化、容灾策略

文章5:从内存到 ES:.NET 企业级向量检索架构演进之路

📝 文章信息

  • 分类:系统架构 / 技术演进 / 企业级应用 / .NET

  • 标签架构设计, 向量检索, 性能优化, 容灾, .NET, C#

📖 章节大纲

1. 引言:架构演进的驱动力
  • 业务增长带来的挑战

  • 技术选型的权衡

2. 阶段一:内存向量检索(C# 实现)
复制代码
┌─────────────┐     ┌──────────────────┐     ┌─────────────┐
│   Client    │────▶│  .NET API (C#)   │────▶│   SQL DB    │
└─────────────┘     │                  │     │  (主数据)    │
                    │  ┌────────────┐  │     └─────────────┘
                    │  │ C# 内存向量 │  │
                    │  │ 存储实现    │  │
                    │  │ (1024-dim) │  │
                    │  └────────────┘  │
                    └──────────────────┘
3. 阶段二:多模型并存(.NET + Python)
复制代码
┌─────────────┐     ┌──────────────────────────────────────────┐
│   Client    │────▶│              .NET API (C#)                │
└─────────────┘     │                                          │
                    │  ┌─────────────┐    ┌─────────────────┐  │
                    │  │ C# BGE-M3   │    │ C# CLIP 向量库   │  │
                    │  │ 内存向量库   │    │ (512-dim)       │  │
                    │  │ (1024-dim)  │    │                 │  │
                    │  └─────────────┘    └─────────────────┘  │
                    │                                          │
                    │  ┌─────────────────────────────────────┐ │
                    │  │        C# 查询策略路由               │ │
                    │  └─────────────────────────────────────┘ │
                    └──────────────────────────────────────────┘
                                        │
                    ┌───────────────────┼───────────────────┐
                    ▼                   ▼                   ▼
              ┌─────────┐        ┌──────────┐        ┌──────────┐
              │ SQL DB  │        │ Python   │        │Elasticsearch│
              │(主数据)  │        │ CLIP服务 │        │ (引入)   │
              └─────────┘        └──────────┘        └──────────┘
4. 阶段三:Elasticsearch 中心化
复制代码
┌─────────────┐     ┌──────────────────────────────────────────┐
│   Client    │────▶│              .NET API (C#)                │
└─────────────┘     │                                          │
                    │  ┌─────────────────────────────────────┐ │
                    │  │      C# 统一查询接口(优先ES)        │ │
                    │  └─────────────────────────────────────┘ │
                    └──────────────────────────────────────────┘
                                        │
                                        ▼
                    ┌──────────────────────────────────────────┐
                    │       Elasticsearch Cluster              │
                    │  ┌──────────────┐    ┌──────────────┐   │
                    │  │ Dense Vector │    │   Keyword    │   │
                    │  │   (向量检索)  │    │   (关键词)    │   │
                    │  └──────────────┘    └──────────────┘   │
                    │                                          │
                    │  ┌─────────────────────────────────────┐ │
                    │  │        Hybrid Search                │ │
                    │  │    向量相似度 + 关键词匹配           │ │
                    │  └─────────────────────────────────────┘ │
                    └──────────────────────────────────────────┘

//核心代码
                var esDoc = new ProductESDocument
                {
                   
                };

                // 4. 写入ES
                var response = await client.IndexAsync(esDoc, i => i.Index(ProductsIndexName));

                if (response.IsValidResponse)
                {
                    await _db.Updateable<CollectData>()
                        .SetColumns(p => p.EsSyncStatus == 1)
                        .Where(p => p.Id == collectDataId)
                        .ExecuteCommandAsync();
                  
                    return true;
                }
                else
                {
                    await _db.Updateable<CollectData>()
                        .SetColumns(p => p.EsSyncStatus == 2)
                        .Where(p => p.Id == collectDataId)
                        .ExecuteCommandAsync();
          
                    return false;
                }

var searchResponse = await client.SearchAsync<>(s => s
                    .Indices(ProductsIndexName)
                    .Query(q => q
                        .MultiMatch(mm => mm
                            .Fields(new[] { "title^3", "semanticKeywords^2", "description", "brandName" })
                            .Query(request.Query)
                            .Fuzziness(new Fuzziness("AUTO"))
                        )
                    )
                    .Sort(srt => srt.Score(new ScoreSort { Order = SortOrder.Desc }))
                    .From((request.Page - 1) * request.PageSize)
                    .Size(request.PageSize)
                    .SourceExcludes(new[] { "productVector", "imageVector" }) // 排除向量字段,减少返回数据量
                    .Explain() /
                );

                if (!searchResponse.IsValidResponse)
                {
                    _logger.LogError("智能搜索失败: {Error}", searchResponse.ElasticsearchServerError?.Error?.Reason);
                    return new ***
                    {
                        Items = new 
                        Total = 0,
                        Page = request.Page,
                        PageSize = request.PageSize
                    };
                }
5. 容灾与降级策略(C#)
复制代码
public class ResilientSearchService
{
    private readonly HybridSearchService _esService;
    private readonly InMemoryVectorStore<88> _memoryStore;
    private readonly ILogger<99> _logger;

    public async Task<List<SearchResult>> SearchWithFallbackAsync(string query, int topK)
    {
        try
        {
            // 优先 ES
            return await _esService.SearchAsync(query, topK);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "ES 查询失败,降级到内存检索");
            
            try
            {
                // 降级到内存检索
                var queryVector = BgeM3EmbeddingGenerator.GenerateEmbedding(query);
                return await _memoryStore.SearchSimilarAsync(queryVector, topK);
            }
            catch (Exception ex2)
            {
                _logger.LogError(ex2, "内存检索也失败,返回空结果");
                return new List<SearchResult>();
            }
        }
    }
}
6. 分层存储策略
层级 存储介质 数据范围 延迟 用途
L1 C# 本地内存 热点 1万条 1ms 实时推荐
L2 Redis 热点 10万条 5ms 缓存加速
L3 Elasticsearch 全量数据 50ms 完整检索
L4 SQL DB 全量数据 100ms 数据持久化
相关推荐
步步为营DotNet几秒前
.NET Aspire 在云原生微服务架构中的深度实践与剖析
云原生·架构·.net
江华森5 分钟前
《网络架构实战:从单机到云原生的全栈思考》博客系列
网络·云原生·架构
真实的菜8 分钟前
Redis 从入门到精通(六):集群模式(Cluster)—— 分布式架构、哈希槽与 Gossip 协议全解
redis·分布式·架构
喵了几个咪8 分钟前
技术复盘:基于 GoWind Admin 实现 Kratos 框架单体轻量化落地
前端·架构
light blue bird9 分钟前
3C 数码电子BOM 协同工作台组件
java·开发语言·jvm·windows·.net·桌面端
故渊at9 小时前
系列三:组件化与模块化进阶 | 第11篇 组件化项目规范与问题根治:依赖、资源、Manifest 与混淆的全链路管控
android·架构·mvvm·模块化·组件化
金融支付架构实战指南10 小时前
支付系统 ES 实战案例:从索引创建到真实业务查询
大数据·elasticsearch·搜索引擎·支付
goodluckyaa11 小时前
NVIDIAGPU 架构中的不变常量(宏观 → 微观)
架构·gpu算力
wenzhangli711 小时前
AI-IDE 关键技术解析:从自然语言到企业级智能开发平台的架构演进
ide·人工智能·架构
m0_7471245312 小时前
ARM架构基础知识扫盲
arm开发·架构