知光搜索系统
本问仅用于自己记忆想到什么写什么详情可去xhs 程序员流年自行了解一、为什么用es而不是mysql1. 底层索引结构不同MySQL 使用 B 树适合事务和精确查询但做全文检索时 LIKE 会导致全表扫描数据量稍大就会拖垮数据库。ES 基于 Lucene 的倒排索引将文本分词后建立反向映射查询复杂度接近 O(1)海量文本检索能稳定在毫秒级。2. 业务排序需求复杂我们的搜索不是简单的关键词匹配还需要结合‘发布时间’、‘点赞数’进行综合排序。ES 原生支持 function_score可以在 BM25 相关性得分上动态叠加业务权重。同时我们利用 log1p 算法压缩点赞数防止历史爆款永久霸榜这些在 MySQL 中需要大量自定义 SQL 且性能极差。3. 分布式与扩展性ES 天生支持分片集群水平扩展简单。配合 search_after 游标分页彻底解决了传统 offset 深翻页的性能抖动问题。相比 SolrES 的社区生态更活跃与 Spring Boot 和 Canal 的集成链路也更成熟降低了研发和运维成本。总结来说MySQL 负责‘写’和强一致ES 负责‘读’和复杂检索。这是典型的 CQRS 读写分离架构既保障了核心链路的稳定又提供了极致的搜索体验。二、search_after解决“深分页性能抖动”痛点传统的 from size 分页如翻到第 100 页from2000ES 需要把前 2000 条数据都查出来扔掉只留最后 20 条。翻得越深越慢甚至会卡死。解法游标分页。原理不告诉 ES“跳过多少条”而是告诉它“从哪一条开始往后找”。就像看书不用从第一页翻起而是用书签夹在第 100 页下次直接接着读。效果无论翻到第几页性能都是恒定的 O(1)彻底解决深分页卡顿。三、function_score BM25融合“相关性”与“业务热度”痛点ES 默认的 BM25 算法只懂文字匹配。比如搜“Java”一个 3 年前没人看的帖子和一个昨天刚发的热门帖子可能得分一样。这不符合用户“想看高质量内容”的诉求。解法业务加权。原理在 BM25文字匹配分的基础上加上业务分点赞数、浏览量。公式最终得分 文字匹配分 (点赞数权重 浏览数权重)。效果即使文字匹配度稍低高质量内容也能排在前面提升用户体验。四、log1p 算法解决“历史爆款霸榜”痛点如果直接用“点赞数”加权一个百万赞的老帖会永远霸占第一新帖根本没有出头之日马太效应。解法对数压缩Log1p。原理log1p(x) 函数会让曲线变平缓。点赞 10 → 得分约 2.3 ln(10) 2.3点赞 100 → 得分约 4.6差距拉大 ln(100) 4.6点赞 1000 → 得分约 6.9差距缩小点赞 10000 → 得分约 9.2差距微乎其微效果削弱绝对数值的碾压。让 100 赞和 1000 赞的差距变小新内容只要有一定热度就有机会排在老爆款前面保证流量流动性。五、completion suggester实现“低延迟前缀联想”痛点用户在搜索框输入“知光”时希望立刻弹出“知光介绍”、“知光下载”等提示。如果用普通搜索延迟太高几百毫秒用户体验差。解法前缀自动补全。原理ES 专门的一种数据结构FST只存前缀。输入“知”直接查出以“知”开头的标题速度极快几毫秒。效果实现“边输边出词”丝滑流畅。