AdMaster技术专栏(四):ES社交搜索引擎,百亿数据秒级响应的秘密





本期技术分享家

AdMaster架构师:蒋善文


技术专栏的开篇,我曾全面介绍AdMaster底层数据处理平台——数据魔方(SocialMaster),这个集数据清洗、计算、存储和分析于一身,可实现秒级响应,并支持客户及数据分析师从内容、账号、活动等多个角度对舆情数据进行自由式探索分析的PAAS平台,是AdMaster提供实时、准确社交和洞察分析服务的根基。今天,我们的视线将转向为SocialMaster提供数据存储、中文检索及多维统计等后勤保障的技术解决方案——ES。


ES,全称ElasticSearch,是基于全文检索引擎架构Lucene,兼具全文检索、多维统计、数据仓储功能的分布式数据服务体系,作为支持实时搜索、生态完善的分布式全文搜索引擎,ES是目前企业级应用领域最稳定、可靠的实时统计查询技术解决方案。


在AdMaster的各社交及洞察分析产品线中,ES主要为社交舆情监测系统SocialMaster、轻量级社交数据管理助手SocialX,以及KOL选择评估系统提供技术支持。它强大的实时查询与高可用和可拓展的特点,能够支持海量数据实时预警和灵活的自定义维度统计,以实现实时的数据分析。



百亿数据秒级响应,

强大的数据查询引擎



相比其他技术解决方案,ES的优势在于它可以解决文本数据的大规模仓储中文分词问题,也可满足对海量数据进行近实时多维度查询统计的要求。ES不仅实时性较好,其扩容和数据管理性能也很高,可支持无限水平扩展,无惧业务激增的压力。


其他技术解决方案则只能部分满足上述需求且需要较高的成本,Solr在数据仓储方面的生态较弱;Hadoop栈的HBase,Hive实时性较差;其他SQL(关系型)、NoSQL类数据库,对倒排索引的支持表现一般,即使支持倒排索引,在中文分词方面也难以定制扩展,且扩容和维护的成本较高。


不过,跟算法一样,作为底层数据框架的ES,虽然技术非常成熟,但只有结合数据和产品,才能凸显价值。此外,由于技术在具体业务场景中的落地具有特殊性,因此在通用型ES解决方案基础上,如何做定制化开发,满足客户复杂的数据查询及分析需求,才是ES发挥价值的关键。


在社交和洞察分析领域,AdMaster对ES的定制化创新开发主要体现在社交化分词及支持高复杂度自定义查询层面。



精细化分词去噪,

高复杂度自定义查询一键返回结果


为保证前端数据服务有序、稳定开展,AdMaster搭建了由高配服务器组成的大规模集群,用于存储、清洗、分析及管理海量的社交数据,为社交数据查询创造了扎实的基础设施。


虽然ES的中文自动分词能力强大,但通用版本并不完全适合社交和洞察分析这么非业的领域。因此,为了让ES适用于社交及洞察业务场景,AdMaster在ES生态的组成部分做了定制开发。通过自定义词包,定制后的查询模板不仅能精准命中客户想要的数据,也大幅降低了噪音,提升了查询效率。



为了给全球知名的品牌客户提供更为专业的社交和洞察分析服务,助力其时刻了解真实的品牌声量及健康度,AdMaster巧妙利用ES处理海量数据的实时分析能力, 研发了舆情预警(触发器)功能。针对海量舆情数据,用户可以自定义规则、声量阈值来进行预警,便于及时了解最新舆情趋势,帮助客户实时洞察品牌负面报道并及时预警, 了解品牌负面来源, 维护社交口碑。此外,AdMaster的实时查询和自定义多维度统计功能,能帮助客户通过设置自定义规则实时查看舆情数据,提升品牌运营效率;通过对官方账号进行授权监控,品牌可实时掌握账号趋势,人群分析随查随用,360°了解目标用户,优化线上沟通方式。


总而言之,ES是目前分布式全文检索最领先的技术,它响应实时、生态成熟、技术稳定,是集数据存储、全文检索和多维统计于一身的完整方案。作为产品的数据中心,ES应用的差距主要体现在数据中心的规模、业务定制能力和实时性方面,它的价值也不仅限于ES本身,而是数据集群、产品研发、定制开发等多项工作的综合体现。


以ES为核心,保证数据源和数据的多样性、完整性、实时性、有效性,在原始数据上应用机器学习和数据挖掘等技术,提取计算有价值的信息,挖掘数据的潜在价值,在数据之上开发易用的,高效的,体验优秀的产品,为灵活高效维护ES开发搭建的监控报警平台,都是ES价值的重要组成部分。



结合业务场景提质增效,

不断优化ES性能


在ES的使用过程中,AdMaster对其性能进行了不断的优化,并总结出以下几个ES优化的基本点,供大家参考:

  1. 关闭交换分区,防止内存置换降低性能;
  2. 开启最佳压缩对于使用_source字段的index,可以把lucene适用的压缩算法替换成 DEFLATE,提高数据压缩率;
  3. Bulk批量写入写入数据时尽量使用下面的bulk接口批量写入,提高写入效率。每个bulk请求的doc数量设定区间推荐为1k~1w,具体根据业务场景选取适当的数量;
  4. 调整refresh_interval写入Lucene的数据,并不是实时可搜索的,ES必须通过refresh的过程把内存中的数据转换成Lucene的完整segment后,才可以被搜索。默认情况下,ES每一秒会refresh一次,产生一个新的segment,这样会导致产生的segment较多,从而segment merge较为频繁,系统开销较大。如果对数据的实时可见性要求较低,可以提高refresh的时间间隔,降低系统开销;
  5. Merge并发控制:ES的一个index由多个shard组成,而一个shard其实就是一个Lucene的index,它又由多个segment组成,且Lucene会不断地把一些小的segment合并成一个大的segment,这个过程被称为merge。默认值是Math.max(1,Math.min(4,Runtime.getRuntime().availableProcessors() / 2)),当节点配置的cpu核数较高时,merge占用的资源可能会偏高,影响集群的性能,可以调整某个index的merge过程的并发度;
  6. 查询时,使用query-bool-filter组合取代普通query:默认情况下,ES通过一定的算法计算返回的每条数据与查询语句的相关度,并通过_score字段来表征。但对于非全文索引的使用场景,用户并不care查询结果与查询条件的相关度,只是想精确的查找目标数据。此时,可以通过query-bool-filter组合来让ES不计算_score,并且尽可能的缓存filter的结果集,供后续包含相同filter的查询使用,提高查询效率;
  7. 按需控制index的分片数和副本数:
  • 对于数据量较小(100GB以下)的index,往往写入压力查询压力相对较低,一般设置3~5个shard,number_of_replicas设置为1即可(也就是一主一从,共两副本) 
  • 对于数据量较大(100GB以上)的index:一般把单个shard的数据量控制在(20GB~50GB) 让index压力分摊至多个节点。