• 搜索域设计


    [toc]

    ### 背景

    需要泛化的平台化数据检索系统

    ### 目标

    * **服务化**:
    * 业务域不再感知具体es地址端口,不需要了解集群版本,配置,部署,高可用
    * **支持索引拆分**:
    * 索引->"分库分表"级拆分,业务域不需要知道规则和逻辑,只需设置自动拆分和手动拆分
    * 支持开启基于日期的冷热拆分
    * **限流熔断**
    * 统一限流(业务端)和熔断(es集群)

    ### 功能

    #### 一.一个接入口

    前:

    order-elasticsearch.pagoda.com.cn:9200

    product-elasticsearch.pagoda.com.cn:9200

    vip-elasticsearch.pagoda.com.cn:9200

    后:

    search.pagoda.com.cn

    所有接入域只有此入口,鉴权(其中包括索引权限隔离)和路由都由搜索域自己完成;对集群的扩容、迁移、拆分等操作对业务域是无感的,节省业务域对接,部署,运维等等人时成本;与此同时搜索域可以方便地统一做流量控制

    #### 二.多协议

    客户端访问集群的方式无需调整,无缝替,所以需要继承es的原生server协议

    #### 三.水平扩容&拆分索引

    * 冷热隔离索引
    * 路由,根据请求中的类目/关键字检索进行路由,使多索引后提高性能
    * es.index => es.index1 / es.index2
    * 拆分规则:
    * 按partition key取模拆分(比如 mod 拆分个数 => index${余数})
    * 按partition key划段拆分(比如 0~100 / 100~500 / 500~)
    * 按partition key取白名单拆分(比如 1、3、5 => index1 / 其余 =>index2)
    * 按多个partition key组合拆分(比如白名单+取模,1、2 => index1 / 其余取模)

    #### 四.熔断限流

    * 熔断
    * 检测请求失败率,高时熔断?
    * 限流
    * 自动限制索引的操作,比如A索引的写操作
    * 资源空闲期,自动调度流量分配,提高搜索集群的资源利用率?

    #### 五.高可用

    * 服务:
    * 故障流量自动迁移:
    * client方式:通过client探测故障(不做处理)
    * 非client方式:通过nginx代理探测故障并剔除
    * 故障处理:
    * 监测后统计,并告警
    * 搭配外活工具
    * es:
    * 集群多活:
    * A集群数据备份到B集群
    * 故障转移:
    * 服务探测es集群失败率,异常失败率时切换到从集群(初期可以只告警,然后人工干预)

    #### 六.可运维

    * 监控运行数据

    * 提供管理命令/api/界面 对es集群和索引数据进行变更

    ### 模块设计

    #### 一.总体架构

    支持原生server协议

    转换query到目标dsl发送到集群(之所以不是透传,主要是考虑到之后引擎升级可能产生与现有query不兼容的语法)

    不封装transport协议

    架构图:

    #### 二.组件划分

    ##### 1.config mgr

    * 配置管理,集成现有的如Apollo

    ##### 2.httpserver

    1. backqueue

    请求队列,扩大系统吞吐量

    2. protocol analyzer

    客户端协议解析和转化

    ###### 问题:

    * 异步io,在高吞吐的中间件支持异步调用是必要的,可以使用netty或者akka等异步通信框架
    * 并发模型,io和业务处理异步化
    * 上下文管理,多线程处理之后需要考虑请求中的特殊标记在线程间传递(可以通过改造线程池实现,参考es的设计)
    * 连接管理,服务端超时、客户端超时
    * 负载均衡,上游业务流量的负载均衡
    * 失败探测,平滑上下线、失败节点探测摘除、自动发现新节点
    * 权限验证,不同业务操作资源隔离

    ##### 3.esclient

    负责与 es 集群交互.两种方案,统一es集群版本;存在多个es集群版本

    1. es response analyzer
    2. result merger
    3. connection poola

    ###### a.统一es集群版本:

    原生的low level http client / high level http client

    ###### b.存在多个es集群版本

    http client封装,控制DSL拼接,方便client 连接池的管理和监控

    ##### 4.query parser

    解析查询

    ###### a.解析

    ###### b.校验

    * 查询数据size过大也要校验不通过,拒绝访问,比如:{'query': {‘match_all’:{}}, ‘start’: 100000, ’size’:10000} 属于非法查询
    * 拆分索引必须携带partition key

    ##### 5.query optimize

    优化查询

    ###### a.慢查询分析

    一个实际场景来分析:某外部业务通过scroll低频查询es,遍历近5min内的客户数据,{'query': {‘bool’:{‘must’:[{’term’:{’shop_id’:1}},{‘range’:{‘follow_time’:{‘gt’:now-5min,’lt’:now}}}]}}, ‘start’: 0, ’size’:10}。此类查询存在大量占用filter cache的风险,这里就可以将其range优化为一个script查询,避免其被cache住(es禁用filter cache只能全局生效,不能单请求设置)。

    ###### b.关键字检索优化

    * 提高匹配度

    比如将单个 50% match 条件优化为 match_phrase 和 50% match 的组合

    * ...

    ###### c.封装DSL

    优化完成,最后需要将条件组合为具体的DSL

    ##### 6.query router

    路由转发,组合拆分索引需要result merger 模块,可以实现子索引并行查询,大大提升了查询速率

    1. 路由es客户端
    2. 冷热索引路由
    3. 拆分索引路由

    ##### 7.query cache

    本地缓存

    ##### 8.其他模块

    1. admin server:监听管理端口,接收运维操作指令
    2. monitor mgr:监控告警
    3. statistic mgr:数据统计,可以通过管理端口对外保护统计数据采集接口

    因为相信,所以看见.
  • 相关阅读:
    Java8 lambda表达式10个示例
    我和阿里云RDS的故事
    Spring Mvc 传递参数要controller出现了400,日期参数全局处理,格式化yyyy-MM-dd 和yyyy-MM-dd HH:mm:ss
    剑指Offer_36_两个链表的第一个公共结点
    剑指Offer_35_数组中的逆序对
    剑指Offer_34_找出字符串中第一个只出现一次的字符
    剑指Offer_33_丑数
    剑指Offer_32_把数组排成最小的数
    剑指Offer_31_整数中1出现的次数(从1到n整数中1出现的次数)
    剑指Offer_30_连续子数组的最大和
  • 原文地址:https://www.cnblogs.com/zeenzhou/p/14437259.html
Copyright © 2020-2023  润新知