高并发查询用 Elastic Search 合适吗?

 

与 SQL 数据库 / 数据仓库相比,作为搜索引擎的 Elastic Search 更适用于高并发查询。比如帐户明细查询,从几千万甚至上亿条历史数据中,查找一个帐户的几条到几千条明细数据。其主要特点是数据总量巨大、并发数量很多,且要求秒级的响应速度。SQL 体系的技术架构,包括关系数据库和 HADOOP 数据仓库,在同等资源下都很难达到这个要求。实际应用中,常常会把数据导出到 Elastic Search 里,利用搜索技术达到高并发的性能要求。从这个角度上看,ES 确实很适合用于高并发查询。

 

不过,遗憾的是,ES 不支持 JOIN 计算,这会带来很大的麻烦。例如,前面说过的帐户明细查询,其结果要包含网点名称、地址、电话等,这些字段一般都存储在网点表中,要对明细表和网点表做关联计算得到。由于 ES 不支持 JOIN,就只能将网点数据合并到明细表中,形成一个宽表,如下图:

..

很明显,这样做会使网点数据重复很多次,冗余数据要占用更多的磁盘空间。更麻烦的是,在网点数据需要变更时,会出现宽表刷新问题。比如,当网点发生合并、拆分、撤销或者改名时,就要把宽表中几千万甚至上亿条数据全部刷新,耗时非常长。刷新期间还要中断查询服务,影响客户体验。而且,除网点之外,通常要关联的数据表还会有很多个,都可能会出现变更的情况,会导致这个问题频繁发生。

另外还有个小问题,ES 集群重启很慢,每次程序升级都需要重启,在这期间也只能暂停查询服务。

从这个角度上再来看,ES 并不太适合有关联运算的高并发查询。

 

这种查询使用开源集算器 SPL 会更方便。SPL 内置了有序行存、分级索引预加载技术,可以达到甚至超过 ES 的查询性能,同时又可以实现关联计算,避免出现 ES 的宽表刷新问题。SPL 服务器是轻量级的,启动速度非常快,管理也很便捷。

比如用 SPL 实现高并发帐户查询、网点表关联的代码大致是下面的样子:

A1=detail.icursor (id,store_id,amt,detail_date,…;id=="101312",index_detail_id).fetch()

       // 利用有序行存和索引进行查询,id 可以改成传入参数

A2=file("store.btx").import@b(id,name,...).keys(id)

       // 加载网点表,也可以在初始化时加载,进一步提速

A3=A1.switch(store_id,A2)

       // 关联计算

return A3.new(id,store_id.store_id:store_id,store_id.store_name:store_name,…,amt,detail_date,…)

       // 引用关联字段,得到查询结果