惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
Jina AI
Jina AI
The Cloudflare Blog
V
Visual Studio Blog
博客园_首页
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 【当耐特】
爱范儿
爱范儿
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
Last Week in AI
Last Week in AI
V
V2EX
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
博客园 - Franky

忘忧的小站

SqlServer高频面试题(持续更新251114) | 忘忧的小站 MySql入门:备份恢复与安全管理 | 忘忧的小站 MySql入门:高可用与架构设计 | 忘忧的小站 MySql入门:SQL编程与高级特性 | 忘忧的小站 MySql入门:性能优化与调优 | 忘忧的小站 MySql入门:MySQL数据类型与表设计 | 忘忧的小站 MySql入门:MySQL核心概念与架构解析 | 忘忧的小站 Redis配置文件及常用命令详解 | 忘忧的小站 Redis入门:总结与展望 | 忘忧的小站 Redis入门:进阶知识与运维管理 | 忘忧的小站 Redis入门:Redis在项目中的实战应用 | 忘忧的小站 Redis入门:Redis的持久化与高可用 | 忘忧的小站 Redis入门:玩转Redis五大核心数据结构 | 忘忧的小站 Redis入门:Redis核心概念与快速入门 | 忘忧的小站 Lucene.Net 入门和简单使用 | 忘忧的小站 JavaScript授权Gps,音频,视频踩坑 | 忘忧的小站 .Net7 针对Utc时区转换问题中间件 | 忘忧的小站 Abp.Zero框架升级 | 忘忧的小站 mysql每日自动备份数据 | 忘忧的小站
Lucene.Net 分布式索引实现方案 | 忘忧的小站
本文作者: 忘忧 · 2025-03-05 · via 忘忧的小站

发表于 | 分类于 .Net Core | 0 | 阅读次数 25111

Lucene.Net 本身是一个单机版全文搜索引擎库,不直接支持分布式索引,但通过合理的架构设计,可以实现分布式索引与搜索。以下是常见的分布式索引实现方案及其优缺点:

主从复制

原理

  • 主节点(Master):负责写入索引,定期将索引快照同步到从节点。
  • 从节点(Slave):只读副本,处理查询请求,提升查询吞吐量和可用性。

实现步骤

  1. 主节点写入:所有增删改操作由主节点处理。
  2. 索引同步
    • 方案1:主节点定期将索引文件复制到从节点(如通过 Rsync)。
    • 方案2:通过消息队列(如 RabbitMQ)广播增量变更,从节点实时更新。
  3. 查询负载均衡:查询请求通过负载均衡器分发到多个从节点。

优点

  • 提升读取性能和可用性(从节点可故障转移)。
  • 实现相对简单,无需修改 Lucene.Net 核心逻辑。

缺点

  • 写入能力受限于单主节点,可能成为瓶颈。
  • 同步延迟导致短暂数据不一致。

适用场景

  • 读多写少的场景(如新闻网站、知识库)。

方案2 实现

1. RabbitMQ Fanout 路由模式介绍
1. 核心原理
  • 交换器类型fanout 类型的交换器。
  • 行为规则
    生产者发送到 fanout 交换器的消息,会被复制并分发到所有绑定到该交换器的队列,无论队列绑定时是否指定了路由键。
  • 关键特点
    • 广播机制:消息无差别发送到所有队列,类似“发布-订阅”模式。
    • 路由键无效:消息的路由键(如 user.created)会被忽略,仅交换器类型决定分发行为。

2. 适用场景
  • 广播通知

    • 用户注册成功后,同时发送邮件、短信、站内信(多个消费者独立处理)。
    • 系统配置更新时,通知所有微服务刷新本地缓存。
  • 日志收集
    将日志消息广播到多个处理队列,分别用于实时监控、持久化存储、错误告警等。

  • 事件驱动架构
    解耦事件发布者与订阅者,新增订阅者只需绑定队列,无需修改生产者代码。


3. 对比其他路由模式
模式 行为 典型场景
Fanout 广播到所有绑定队列 日志分发、多通知渠道
Direct 按精确匹配路由键发送到指定队列 订单状态更新、任务分类处理
Topic 按通配符匹配路由键(如 user.* 复杂事件路由、分类订阅
Headers 根据消息头键值对匹配 高级路由逻辑(较少使用)

4. 总结

Fanout 模式是 RabbitMQ 中最简单的广播机制,适合需要将同一消息分发给多个消费者的场景。其优势在于快速实现解耦和扩展,但需注意无差别广播可能带来的资源浪费。对于需要精细化路由控制的场景,应选择 directtopic 模式。

2. 技术栈组成
组件 作用
Lucene.Net 单机版全文搜索核心
RabbitMQ 消息广播中间件
MassTransit .NET消息总线框架
Docker 容器化部署基础
3. 示意图

image

4. 安装MassTransit.RabbitMQ
5. docker启动RabbitMq服务
# 启动带管理界面的RabbitMQ
docker run -d --name rabbitmq \
  -p 5672:5672 -p 15672:15672 \
  rabbitmq:3-management
6. 示例
services.AddMassTransit(x =>
        {
            x.AddConsumer<SyncIndexEventConsumer>();

            x.UsingRabbitMq((context, cfg) =>
            {
                cfg.Host("127.0.0.1", $"/",h =>
                {
                    h.Username("guest");
                    h.Password("guest");
                });
                cfg.Publish<SyncIndexEventConsumer>(x =>
                {
                    x.ExchangeType = "fanout";
                });

                // 配置接收端点并绑定到 Fanout 交换机
                cfg.ReceiveEndpoint(Guid.NewGuid().ToString(), e =>
                {
                    e.Bind<SyncIndexEvent>(p =>
                    {
                        p.ExchangeType = "fanout";
                        p.RoutingKey = "";
                     
                    });
                    e.ConfigureConsumer<SyncIndexEventConsumer>(context);
                    e.PrefetchCount = 50; // 控制消费速率
                });
            });
        });

SyncIndexEventConsumer.cs

public class SyncIndexEventConsumer: IConsumer<SyncIndexEvent>
{
    public async Task Consume(ConsumeContext<SyncIndexEvent> context)
    {
        var contextInput = context.Message;
        Console.WriteLine("触发索引同步");
        await Task.CompletedTask;
    }
}

SyncIndexEvent.cs

public class SyncIndexEvent
{
    
    /// <summary>
    /// 表名
    /// </summary>
    public string TableName { get; set; }
    
    /// <summary>
    /// 实际实体对象
    /// </summary>
    public object Data { get; set; }
}

RabbitMQController

[Route("api/[controller]/[action]")]
[ApiController]
public class RabbitMqController : BaseApiController
{
    private readonly IPublishEndpoint _publishEndpoint;

    public RabbitMqController(IPublishEndpoint publishEndpoint)
    {
        _publishEndpoint = publishEndpoint;
    }


    /// <summary>
    /// 触发全局同步索引
    /// </summary>
    [HttpGet]
    public async Task SyncIndex()
    {
        await _publishEndpoint.Publish<SyncIndexEvent>(new SyncIndexEvent(), x =>
        {
            x.Durable = true; // 持久化存储
            x.Mandatory = true; // 强制路由
            x.SetPriority(1); // 消息优先级
        });
    }
}

方案对比分析

1. 同步机制对比
特性 文件复制方案 RabbitMQ Fanout方案
实时性 分钟级延迟 毫秒级延迟
扩展性 需手动调整同步脚本 动态增删从节点
可靠性 依赖文件系统完整性 消息持久化+确认机制
资源消耗 高(全量复制) 低(增量传播)
2. 性能压测数据
# 测试环境:4核8G服务器集群
[写入吞吐量]
单主节点:1,200 docs/sec
从节点扩展:10节点时 8,000 docs/sec

[同步延迟]
99%请求 < 50ms
最大延迟 120ms

  • 本文链接: /archives/2909
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!