2.1 前言
在上一篇文章中,我们已经完成了 SOLR 的源码环境搭建,成功运行了一个简单的实例,并初步浏览了源码目录结构。现在,我们将目光转向 SOLR 的整体架构,探索它如何将复杂的功能组织成一个高效的搜索系统。通过本篇,你将了解 SOLR 的核心组件是如何协作的,请求是如何从客户端到达服务器并返回结果的,以及源码中哪些关键类扮演了重要角色。这不仅是后续深入分析的基础,也是理解 SOLR 设计思想的起点。
SOLR 的架构设计兼顾了性能、扩展性和易用性。无论是单机部署还是分布式环境(SolrCloud),其核心思想都围绕着“高效索引”和“快速查询”展开。本文将从高层视图逐步深入到源码细节,带你一窥 SOLR 的全貌。
2.2 SOLR 的整体架构
2.2.1 高层视图
SOLR 的架构可以分为三个主要层次:
- 客户端层:通过 HTTP 请求(通常是 RESTful API)与 SOLR 交互,支持多种语言(如 Java 的 SolrJ、Python 的 pysolr 等)。
- 服务端层:SOLR 的核心运行时,包括嵌入式 Jetty 服务器、请求分发逻辑和核心组件。
- 存储层:基于 Lucene 的索引文件系统,负责持久化数据。
从功能上看,SOLR 的架构可以用下图简要表示(文字描述替代图形):
客户端请求(HTTP) → SolrDispatchFilter(请求入口) → CoreContainer(核心容器) → SolrCore(具体核心) → Lucene(索引与搜索)
2.2.2 核心概念解析
在深入源码之前,我们需要理解 SOLR 中的几个关键概念,它们贯穿整个架构:
- Core:一个独立的核心,包含自己的索引、配置(
solrconfig.xml和schema.xml)和数据。通常用于单机模式。 - Collection:分布式环境下的逻辑概念,一个 Collection 可以分布在多个节点上,包含多个 Shard。
- Shard:Collection 的分片,每个 Shard 是一个独立的索引单元。
- Replica:Shard 的副本,用于高可用性和负载均衡。
- SolrCloud:SOLR 的分布式模式,通过 ZooKeeper 管理集群状态。
这些概念在源码中以类和数据结构的形式体现,后文会逐一分析。
2.2.3 单机 vs 分布式
- 单机模式:一个 SOLR 实例运行多个 Core,所有数据存储在本地。
- 分布式模式(SolrCloud):多个 SOLR 节点组成集群,通过 ZooKeeper 协调分片和副本,数据分布存储。
本篇将以单机模式为主,逐步引入分布式概念,为后续专门的 SolrCloud 篇章做铺垫。
2.3 请求处理流程:从 HTTP 到响应
SOLR 的核心工作是处理客户端请求。无论是索引文档还是查询数据,SOLR 都通过 HTTP 接口接收请求,经过一系列组件处理后返回结果。以下是请求处理的高层流程:
- 客户端发送请求:如
http://localhost:8983/solr/mycore/update。 - 请求抵达服务器:Jetty 接收并交给 SOLR 的过滤器。
- 请求分发:根据路径(如
/update或/select)路由到对应处理器。 - 核心处理:调用 SolrCore 执行索引或查询操作。
- 结果返回:封装响应(如 JSON)返回客户端。
接下来,我们通过源码逐步剖析这一流程。
2.4 源码入口:SolrDispatchFilter
SolrDispatchFilter 是 SOLR 处理 HTTP 请求的起点,位于 solr/server/solr-webapp/webapp/WEB-INF/web.xml 中定义,作为 Servlet 过滤器拦截所有请求。
2.4.1 初始化
SolrDispatchFilter 的初始化发生在 SOLR 启动时:
| |
coreContainer:全局的CoreContainer实例,管理所有 Core。getSolrHome():读取 SOLR 的数据目录(默认solr/)。
2.4.2 请求处理
核心方法是 doFilter:
| |
HttpSolrCall:封装单个请求的处理逻辑。init():解析请求路径和参数。call():执行具体操作。
2.4.3 HttpSolrCall 的作用
HttpSolrCall 是请求的分发中枢。它根据 URL 路径(如 /mycore/select)决定调用哪个核心和处理器:
| |
coreName:从 URL 中提取的核心名称(如mycore)。path:请求路径(如/select)。SolrRequestHandler:具体的处理器(如查询或更新)。
2.5 CoreContainer:核心管理
CoreContainer 是 SOLR 的“大脑”,负责加载和管理所有 Core。
2.5.1 初始化
| |
solr.xml:定义 Core 的配置文件。cores:存储所有SolrCore实例。
2.5.2 获取 Core
| |
getCoreFromAnyList:从内存中查找 Core。
2.5.3 生命周期管理
CoreContainer 还负责 Core 的创建、销毁和重载,确保系统资源的高效利用。
2.6 SolrCore:核心执行单元
SolrCore 是 SOLR 的执行单元,每个 Core 独立管理自己的索引和配置。
2.6.1 结构
| |
solrConfig:配置文件solrconfig.xml的内存表示。updateHandler:处理索引更新。searcher:执行查询。
2.6.2 执行请求
execute 方法是核心逻辑:
| |
SolrQueryRequest:封装请求参数。SolrQueryResponse:封装响应数据。
2.7 请求处理示例:查询流程
以一个查询请求为例(http://localhost:8983/solr/mycore/select?q=title:Hello):
- 客户端发送请求:HTTP GET 请求到达 Jetty。
- SolrDispatchFilter 拦截:创建
HttpSolrCall,解析 URL。 - 路由到 Core:
CoreContainer返回mycore的SolrCore。 - 调用 SearchHandler:
1 2 3 4 5 6 7 8public class SearchHandler extends RequestHandlerBase { public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) { SolrParams params = req.getParams(); String q = params.get("q"); QueryResponseWriter writer = getResponseWriter(req); rsp.addResponse(writer.write(search(q, req))); } } - 返回结果:JSON 格式的查询结果。
2.8 分布式架构简介
在 SolrCloud 中,架构略有不同:
- ZooKeeper:存储集群状态(
clusterstate.json)。 - ShardHandler:分发请求到多个节点。
- CloudSolrClient:客户端与集群交互。
详细分析将在后续篇章展开。
2.9 总结
本篇从高层视图到源码细节,全面剖析了 SOLR 的架构。通过 SolrDispatchFilter、CoreContainer 和 SolrCore 的分析,我们理解了请求处理的核心流程。下一篇文章将深入探讨 索引构建与更新机制,带你走进 SOLR 的数据管理世界。
