[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:数据统计,可以通过管理端口对外保护统计数据采集接口