"有赞搜索系统"就是一款面向公司内部的一款产品,其部分应用NoSQL的存储。可以帮助应用合理高效的支持检索和多维过滤功能,有赞搜索平台目前支持了大大小小一百多个检索业务,服务于近百亿数据。

除了传统的搜索应用提供高级检索和大数据交互能力,,有赞搜索平台还需要为其他比如商品管理、订单检索、粉丝筛选等海量数据过滤提供支持,对于他们来说,如何扩展平台以支持多样的检索需求是一个巨大的挑战。

有赞搜索平台应用的是Elasticsearch 是一个高可用分布式搜索引擎,一方面技术相对成熟稳定,另一方面社区也比较活跃。

有赞平台的架构1.0版本:

在2015年他们主要运行行频和粉丝索引,数据通过 Canal 从 DB 同步到 Elasticsearch,架构图如下(架构图摘自原文)

有赞系统架构 有赞框架_有赞系统架构

通过这种方式,在业务量较小时,可以低成本的快速为不同业务索引创建同步应用,适合业务快速发展时期,但相对的每个同步程序都是单体应用,不仅与业务库地址耦合,需要适应业务库快速的变化,如迁库、分库分表等,而且多个 canal 同时订阅同一个库,也会造成数据库性能的下降。

另外 Elasticsearch 集群也没有做物理隔离,有一次有赞在促销活动就因为粉丝数据量过于庞大导致 Elasticsearch 进程 heap 内存耗尽而 OOM,使得集群内全部索引都无法正常工作

架构2.0版本:

2.0版本就是为了解决数据量过于庞大导致 Elasticsearch 进程 heap 内存耗尽而 OOM的问题,其大致架构图:(图摘自原文):

有赞系统架构 有赞框架_Elastic_02

这种架构,数据总线将数据变更消息同步到 mq,同步应用通过消费 mq 消息来同步业务库数据,借数据总线实现与业务库的解耦,引入数据总线也可以避免多个 canal 监听消费同一张表 binlog 的虚耗。

架构3.0版本:

3.0版本就是对2.0版本的一些针对性的调整,例如:

  1. 通过开放接口接收用户调用,与业务代码完全解耦;
  2. 增加 proxy 用来对外服务,预处理用户请求并执行必要的流控、缓存等操作;
  3. 提供管理平台简化索引变更和集群管理 这样的演变让有赞搜索系统逐渐的平台化,已经初具了一个搜索平台的架构

架构图如下(图摘自原文):

有赞系统架构 有赞框架_缓存_03

 

Proxy层:

作为对外服务的出入口,proxy 除了通过 ESLoader 提供兼容不同版本 Elasticsearch 调用的标准化接口之外,也内嵌了请求校验、缓存、模板查询等功能模块。

请求校验主要是对用户的写入、查询请求进行预处理,如果发现字段不符、类型错误、查询语法错误、疑似慢查询等操作后以 fast fail 的方式拒绝请求或者以较低的流控水平执行,避免无效或低效能操作对整个 Elasticsearch 集群的影响。

缓存和 ESLoader 主要是将原先高级搜索中的通用功能集成进来,使得高级搜索可以专注于搜索自身的查询分析和重写排序功能,更加内聚。我们在缓存上做了一点小小的优化,由于查询结果缓存通常来说带有源文档内容会比较大,为了避免流量高峰频繁访问导致 codis 集群网络拥堵,在 proxy 上实现了一个简单的本地缓存,在流量高峰时自动降级。

这里提一下模板查询,在查询结构(DSL)相对固定又比较冗长的情况下,比如商品类目筛选、订单筛选等,可以通过模板查询(search template)来实现,一方面简化业务编排DSL的负担,另一方面还可以通过编辑查询模板 template,利用默认值、可选条件等手段在服务端进行线上查询性能调优。

有赞也对未来的发展做了规划他们将来会有更多的版本面世,下来的4.0版本,要解决共享集群应对不同生产标准应用的问题,他们希望进一步将平台化的搜索服务提升为云化的服务申请机制,配合对业务的等级划分,将核心应用独立部署为相互隔离的物理集群,而非核心应用通过不同的应用模板申请基于 k8s 运行的 Elasticsearch 云服务。应用模板中会定义不同应用场景下的服务配置,从而解决不同应用的生产标准差异问题,而且云服务可以根据应用运行状况及时进行服务的伸缩容。