搜索系统设计(下)

431 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

对搜索结果排名

  • Twitter搜索排序策略
  • 存储设计

搜索关键字,自己新发布的推特搜索不出来,而排在前面的总是哪些热度很高的推特。

推特搜索排序策略

推文热度值:

○ 点赞数、收藏数、评论数、 阅读数

○ 热度值 = 点赞数+收藏数+评论数+阅读数

社交关系:

○ 是否是你关注

○ 是否是大V

时效性:

○ 人气数 = 热度+社交关系+时效性

○ 在存储时,将计算出来的“人气数” 和索引一起存储,在搜索时根据人气数对搜索结果排序

存储设计

快速获取搜索结果(搜索速度优化)

建立实时索引:将最近1周内的最新的推文建立索引库存储在内存,从内存中查询索引比从磁盘快很多。

实时索引建立过程

  • 用户发布的新推会被发送到分词服务器。tweets的文本被分词
  • 按hash分割,tweets 被分发到各索引服务器,每个索引服务器负责一部分数据,将 tweets 实时建立索引
  • 同时,另外有个一个更新服务,它推送 tweets 的动态变化信息(如点赞次数、转发次数),动态更新索引

查询过程

  • 搜索请求

    用户搜索请求首先到达搜索前端服务器(Blender),解析请求

  • 执行计算

    Earlybird服务执行相关性计算并排序。并将排序好的tweet 列表返回给Blender

  • 返回结果

    Blender 合并各Earlybird返回的列表,并执行一些重排序(Reranking), 然后返回给用户

Twitter巧妙在于保存2%热度最高、最可能被检索的 tweets 在内存,并保存16%的 tweets 在 SSD。

批量索引建立流程

聚合:基于Tweet ID一起加入多个数据源

打分:根据推特的特征提取(转发次数,点赞次数,评论次数)打分,分数越高

分区存储:将数据划分为小块存储在HDFS

唯一tweet_id 生成

雪花算法(Snowflake)

  • Twitter 的分布式自增ID算法,经测试 SnowFlake 每秒可以产生 26 万个自增可排序的 ID
  • Twitter 的 SnowFlake 生成 ID 能够按照时间有序生成
  • 在分布式系统内不会产生 ID 碰撞(由DataCenter 和 WorkerID 做区分)并且效率较高

传统方式

  • 时间戳 + N 位随机数

    分布式系统内会产生 ID 碰撞

  • UUID

    入库性能差,因为UUID无序

推特搜索和电商搜索的区别

电商系统中的搜索

支持商品属性筛选, 如:品牌,具体参数

支持各种维度的排序,包括支持人气、销量、信用、价格、发货地等属性的排序

对数据的实时性要求高,体现在价格和库存两个方面

支持范围查找,价格区间范围搜索

对数据准确性要求高,不能丢失商品

整体架构

目前电商使用多的搜索引擎基于分布式实时引擎ES,ES构建在开源社区最稳定成熟的索

引库 Lucence 上。

  • 支持高可用, 可水平扩展
  • 并有自动容错和自动伸缩的机制
  • 支持还实现了 ES 与 MySQL 和 Hadoop 的无缝集成

索引构建过程

  • 实时增量的更新索引通过 kafka 实现
  • 全量索引存储在 HDFS

ES-Hadoop(Elasticsearch for Apache Hadoop):无缝打通 ES 和Hadoop 两个非常优秀的框架,在 Hadoop 和 Elasticsearch 之间起到桥梁的作用,完美把 Hadoop 的批处理优势和ES强大的全文检索引擎结合。既可以把 HDFS 的数据导入到 ES 做分析,也可以将 ES 数据导到HDFS备份

主流的搜索引擎对比

搜索引擎基础,一个开放源代码的全文检索引擎工具包

Solr:传统的搜索应用中表现好,不支持实时搜

支撑大规模分布式部署

实时搜索能力强,适合互联网场景

github使用ES做代码搜索

维基百科使用ES做词条搜索

4 Scale优化

4.1 热点榜单功能

热度值 = 点赞数 + 收藏数 + 评论数 + 阅读数

推特这种高并发实时计算的排行榜,db不适合,db扛不住。这么大的并发量,高并发实时的排行榜天然适合用缓存。

Redis 有序集合 Sorted Set

Sorted Set 不能重复,拥有一个权重 score 从大到小排序。

每条推特是个member ,每条推特的热度值是一个 score。

Zadd:向一个有序集合中加入一个或者多个元素及其分数

zadd key value1 member1 

取出范围内的数据

zrevrange key start end

更新 Score

  • 实时更新

    实时更新对系统压力大

  • 每隔一段时间更新

4.2 容错能力-副本机制

每个索引有一或多个分片,每个分片存储不同数据。分片可分为:

  • 主分片(primary shard)

  • 复制分片(replica shard)

    复制分片是主分片的拷贝

往主分片服务器存放数据时,会对应实时同步到备用分片服务器。

查询时,所有(主、备)都进行查询。

副本机制的作用

  • 故障转移

    提高系统容错,当某节点某个分片损坏或丢失时可以从副本中恢复,有主分片的节点挂了,一个副本分片就会晋升为主分片

  • 提高查询效率

    副本分片也提供查询能力,会自动对搜索请求进行负载均衡