1、搜索引擎架构概览:理解搜索引擎的基本工作原理
各位同学,咱们今天聊聊搜索引擎的骨架。说白了,搜索引擎就是个“信息搬运工”——把网页数据抓过来,整理好,等你来问。我做了这么多年SRE,见过太多人一上来就调参数、搞优化,结果连数据是怎么流进去的都没搞明白。嗯,这章咱们就把地基打牢。
1.1 搜索引擎的四大核心流程
搜索引擎的工作,可以拆成四个步骤:爬虫、索引、检索、排序。我习惯把这四个环节比作“采、存、找、排”。
1.1.1 爬虫(Crawler)—— 信息采集员
爬虫的任务很简单:顺着链接去抓网页。但这里有个坑——爬虫不是乱爬的。它得遵守robots协议,还得控制抓取频率,不然容易被封。我在项目中遇到过,某个爬虫配置了每秒1000个请求,结果对方服务器直接把我们IP拉黑了。嗯,后来我们加了限流和重试机制。
1.1.2 索引(Indexing)—— 信息整理师
抓回来的网页是原始数据,不能直接拿来搜。索引的作用就是建立倒排索引。你想想看,一本书的目录是按页码排的,但倒排索引是按关键词排的——每个词后面跟着一堆文档ID。这样搜索“搜索引擎”时,直接查这个词对应的文档列表就行,不用翻遍全书。
核心概念:倒排索引
简单说,就是“词 → 文档”的映射。比如:
“搜索引擎” → [doc1, doc3, doc7]
“性能监控” → [doc2, doc5, doc9]
搜索“搜索引擎 性能监控”时,取两个列表的交集,就是[doc2, doc5, doc7]?不对,得看具体实现。我习惯用位图或跳表来加速求交。
1.1.3 检索(Retrieval)—— 信息查找员
用户输入查询后,检索模块负责从索引里找出相关文档。这里有个关键点:不是所有匹配的文档都要返回。比如你搜“Elasticsearch 部署”,结果返回了10万条,用户根本看不完。所以检索模块通常会做两件事:
- 剪枝:只保留Top N个候选
- 打分:用BM25、TF-IDF等算法算相关性
我曾经踩过一个坑:检索时没做剪枝,结果内存直接爆了。嗯,后来我们加了max_window_size限制。
1.1.4 排序(Ranking)—— 信息推荐官
排序是搜索引擎的“面子工程”。用户看到的搜索结果好不好,全看排序算法。常见的排序策略有:
- 相关性排序:基于文本匹配度
- 时效性排序:新闻类搜索常用
- 个性化排序:根据用户历史行为调整
我个人习惯在排序阶段加入业务规则。比如电商搜索,价格、销量、评价都得加权。你想想看,用户搜“手机”,结果第一页全是几百块的老人机,那体验得多差。
1.2 核心组件:ELK + Cerebro
讲完原理,咱们看看实际落地用的工具。ELK(Elasticsearch、Logstash、Kibana)是搜索引擎领域的“三驾马车”,再加上Cerebro做集群管理,基本能覆盖大部分场景。
1.2.1 Elasticsearch —— 存储与检索核心
Elasticsearch(简称ES)是搜索引擎的“心脏”。它负责:
- 存储数据:以文档形式存到分片里
- 建立索引:自动生成倒排索引
- 处理查询:分布式搜索,合并结果
部署ES时,我建议注意以下几点:
- 内存分配:ES的堆内存不要超过32GB,否则JVM指针压缩失效
- 磁盘类型:SSD是标配,机械盘扛不住高并发
- 节点角色:master、data、ingest节点要分开,别混用
避坑指南
我曾经把master和data节点混在一起,结果一次GC把集群搞崩了。嗯,从那以后我坚持角色分离。
1.2.2 Logstash —— 数据管道
Logstash负责采集、转换、输出数据。它的工作流是:
- 输入:从文件、Kafka、TCP等来源读取数据
- 过滤:用grok、mutate等插件解析数据
- 输出:写入ES、文件或其他目标
举个例子,采集Nginx日志:
input {
file {
path => "/var/log/nginx/access.log"
start_position => "beginning"
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "nginx-access-%{+YYYY.MM.dd}"
}
}
这里有个小技巧:grok正则写不好,性能会暴跌。我习惯先用grokdebugger调试,确认无误再上线。
1.2.3 Kibana —— 可视化面板
Kibana是ES的“脸面”。它提供:
- 数据探索:用Discover模块查原始数据
- 仪表盘:拖拽生成图表
- 监控:查看集群健康状态
部署Kibana时,我建议不要暴露公网。你想想看,如果Kibana被攻击,整个ES集群的数据都可能泄露。嗯,我们一般用Nginx做反向代理,加个Basic Auth。
1.2.4 Cerebro —— 集群管理利器
Cerebro(以前叫Kopf)是ES的“控制台”。它让你:
- 查看分片分布:哪个节点负载高,一目了然
- 执行操作:reroute分片、修改配置
- 监控指标:节点CPU、内存、磁盘使用率
我个人习惯用Cerebro做分片均衡。比如某个节点磁盘快满了,手动把分片移到其他节点。但要注意:reroute操作要谨慎,搞不好会触发集群重平衡,影响线上服务。
1.3 部署与配置实战
理论讲完了,咱们动手部署一套。假设你有三台服务器(node1、node2、node3),操作系统是CentOS 7。
1.3.1 安装Elasticsearch
# 下载并安装
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.0-linux-x86_64.tar.gz
tar -xzf elasticsearch-7.17.0-linux-x86_64.tar.gz
# 修改配置(config/elasticsearch.yml)
cluster.name: my-search-cluster
node.name: node-1
path.data: /data/elasticsearch/data
path.logs: /data/elasticsearch/logs
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["node1:9300", "node2:9300", "node3:9300"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
# 启动
./bin/elasticsearch -d
这里有个坑:ES不能用root用户启动。我刚开始做时不知道,直接报错。嗯,后来创建了elastic用户,并授权目录权限。
1.3.2 安装Logstash
# 下载并安装
wget https://artifacts.elastic.co/downloads/logstash/logstash-7.17.0-linux-x86_64.tar.gz
tar -xzf logstash-7.17.0-linux-x86_64.tar.gz
# 创建配置文件(config/nginx.conf)
input { ... }
filter { ... }
output { ... }
# 启动
./bin/logstash -f config/nginx.conf
我建议先测试配置文件:./bin/logstash -f config/nginx.conf --config.test_and_exit。不然配置错了,启动半天才发现,浪费时间。
1.3.3 安装Kibana
# 下载并安装
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.17.0-linux-x86_64.tar.gz
tar -xzf kibana-7.17.0-linux-x86_64.tar.gz
# 修改配置(config/kibana.yml)
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://localhost:9200"]
# 启动
./bin/kibana &
启动后访问http://node1:5601,如果看到Kibana界面,说明部署成功。
1.3.4 安装Cerebro
# 下载并安装
wget https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro-0.9.4.tgz
tar -xzf cerebro-0.9.4.tgz
# 修改配置(conf/application.conf)
hosts = [
{
host = "http://localhost:9200"
name = "my-search-cluster"
}
]
# 启动
./bin/cerebro &
访问http://node1:9000,输入ES地址,就能看到集群状态了。
1.4 本章小结
这一章咱们把搜索引擎的骨架搭起来了。你想想看,从爬虫到排序,从ES到Cerebro,每个环节都有它的作用。我建议你亲手部署一遍,遇到问题别怕,踩坑才是成长的捷径。
下一章,咱们会深入性能监控指标,看看怎么用Prometheus和Grafana盯住集群的“心跳”。嗯,到时候见。