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 8
public 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 的数据管理世界。