1.1 目的
Elasticsearch是一个基于Lucene的实时分布式的搜索与分析引擎,是当前主流的企业级搜索引擎。提供了一个分布式服务,可以快速的近乎于准实时的存储、查询和分析超大数据集,可以快速的检索并提升用户的检索体验。
2.1 技术架构
ES数据操作
黑-1/黑-2: 前端/业务中心通过ES-SDK插件对ES表对像进行CRUD操作
PorlarDB到ES数据同步
Ø 蓝-1/蓝-2部分: 通用方案通过edas上的dts组件针对单表或简单join表从porlardb同步全量或是增量数据至ES,以供业务侧查询,全量同步择时进行,会影响业务,增量准时间处理。
Ø 红-1/红-2部分: 宽表方案,业务中心如需使用宽表,则在porlardb中建立和es中同结构的宽表,业务中心自身订阅binlog日志,通过binlog日志触发生成相应的数据至对应的宽表中,DTS组件配置对该宽表的增量同步至ES
Ø 红-1/红-3: 非宽表方案,业务中心定时或自身订阅binlog日志,直接生成相应的数据吐至ES中(按实际的增量业务量可以业务中心和porlardb之间追加kafka解耦)
2.2 管理功能
ES运维:
https://help.aliyun.com/document_detail/90391.html?spm=a2c4g.11186623.6.665.57572ff7FnTKQ7
EDAS内组件ES本身提供了较多的管理运维功能,如下图,针对ES的运维功能通过EDAS的ES控制台操作
ES组件集群示例图
数据入ES后,可能过ES自带的查询工具kibana作检索查询
2.3 部署架构
2.3.1 ES集群规格评估
ES默认的主分片数为5个,副本数为1个,因此如ES跨3个可用区部署中,当其中一个可用区或两个可用区不可用时,剩下的可用区需要继续提供服务,因此索引的副本个数至少为2
阿里云ES的单机规格在一定程度上限制了集群的能力,本文根据测试结果和使用经验给出如下建议:
- 集群最大节点数:
集群最大节点数 = 单节点CPU * 5
。 - 单节点最大数据量。
使用场景不同,单节点最大承载数据量也会不同,具体如下:
- 数据加速、查询聚合等场景:
单节点最大数据量 = 单节点存储空间(G) * 10
。 - 日志写入、离线分析等场景:
单节点最大数据量 = 单节点存储空间(G) * 50
。 - 通常情况:
单节点最大数据量 = 单节点存储空间(G) * 30
。
集群规格参考列表如下。
规格 |
最大节点数 |
单节点最大磁盘(查询) |
单节点最大磁盘(日志) |
单节点最大磁盘(通常) |
2核4G |
10 |
40 GB |
200 GB |
100 GB |
2核8G |
10 |
80 GB |
400 GB |
200 GB |
4核16G |
20 |
160 GB |
800 GB |
512 GB |
8核32G |
40 |
320 GB |
1.5 TB |
1 TB |
16核64G |
50 |
640 GB |
2 TB |
2 TB |
2.3.2 Shard评估
ES 6.x版本的索引默认包含5个主shard,1个副shard;
基于以上问题,下文对shard规划提供了一些建议。这些建议仅供参考,实际业务中还需根据需求进行调整:
- 建议在分配shard前,对ES进行数据测试。当数据量很大时,要减少写入量的大小,降低ES压力,建议选择多主1个副本;当数据量较小,且写入量也比较小时,建议使用单主多副本或者单主一副本。
- 建议一个shard的存储量保持在30G以内(最优),特殊情况下,可以提升到50G以内。如果评估结果超过该容量,建议在创建索引之前,合理进行shard分配,后期进行reindex,虽然能保证不停机,但是比较耗时。
说明对于评估数据量低于30GB的业务,也可以使用1主多备的策略进行负载均衡。例如20GB的单索引,在5个数据节点中,可以考虑1主4副本的shard规划。
- 对于日志分析或者超大索引场景,建议单个shard大小不要超过100GB。
- 建议shard的个数(包括副本)要尽可能等于数据节点数,或者是数据节点数的整数倍。
说明主分片不是越多越好,因为主分片越多,ES性能开销也会越大。
- 建议单个节点上同一索引的shard个数不要超5个。
- 建议单个节点上全部索引的shard的数量不要超过100个(可以提升ES的性能开销)。
- 建议按照1:5的比例添加独立的协调节点(2个起),CPU:Memory为1:4或1:8。例如10个8核32G的数据节点,建议配置2个8核32G的独立协调节点。
3 关键设计
3.1 关联查询设计
大原则: 设计时尽可能使用扁平的文档模型
3.1.1 应用层做关联
数据归属于不同的索引中,从某一索引中查询出关联字端后从其它索引继续查询出相关数据,应用层对多个索引中查询出来数据作整合,适用于查询出数据量较小的情况,结构相对清晰,但要多次查询
3.1.2 ES中宽表化处理
按业务需求整合porlardb中多表中的关键字段整合成宽表存储至ES中,在ES中查询即不需要关联查询,但需要前期数据整合处理
3.1.3 嵌套对象(nested)
Ø 冗余度大,查询只能返回符合条件的整个文档,不能部分返回嵌套文档中的数据,但查询时无需关联操作
注意点:
u 单个索引中最大允许拥有50个nested类型的数据。
u 单个文档中所有nested类型json对象数据的总量是10000。
3.1.4 Join文档存储
Ø 每个索引只允许一个Join类型Mapping定义,父文档和子文档必须在同一个分片上编入索引,当进行删除、更新、查找子文档时候需要提供相同的路由值。
Ø 一个文档可以有多个子文档,但只能有一个父文档。
Ø 可以为已经存在的Join类型添加新的关系,当一个文档已经成为父文档后,可以为该文档添加子文档。
Ø 一个索引中只能有一个join类型字段,join 类型可以是一种父文档对应多种子文档,子文档可以作为父文档,关联关系需在导入数据前提前建立并确认正确
Eg: "info": {
"type": "join",
"relations": {
"one": ["two-1","two-2"],
" two-1": " three-1"
}
}
Ø 子文档数据量要明显多于父文档的数据量,存在1 对多量的关系,子文档更新频繁的场景
u 索引时,主分片的数量一经定义就不能改变
u routing是一个可变值,默认是文档的_id
3.1.5 Nested与Join简单比对
对比 |
Nested |
Json |
优点 |
文档独立存储,读取性能高 |
父子文档可以独立更新,互不影响 |
缺点 |
更新父或子文档时要更新整个文档 |
为维护join关系,要占用部分内存,读取性能较差 |
应用场景 |
子文档偶尔更新,查询频繁 |
子文档更新频繁 |
3.2 数据同步参考
3.2.1 阿里云组件
3.2.1.1 DTS同步(binlogs准时实同步-单表操作)
因目前DTS不支持DRDS(Porlardb)直接同步到ElasticSearch,因为同步会配置各个分库分表的数据分别同步到ES的同一个type下作归集。
业务组如需选用DTS则提交各分库账号,分库表名至DBA侧统一添加
注: DTS同步不会作下划线和驼峰的转换,因此如数据库表中字段是以下划线区分,同步至ES中字段名仍是下划线,如果读取的实体类字段名为驼峰,可添加注解作转换,但存数据时仍和实体字段名一致,可能会存在不一致情况,如数据入ES有多个源: DTS,Dataworks,业务代码,注意保持三者字段名是一致的。
3.2.1.2 DataWorks同步(定时任务最小五分钟-单表操作)
需有更新SQL控制,局限性:
Ø 表中需要有modify字段为更改时间戳,包括新增、更新、删除(逻辑删除)
Ø 非准实时(触发机制非binlog方式)
DRDS-Reader:
https://help.aliyun.com/knowledge_detail/74310.html?spm=a2c4g.11186631.2.1.48974c072XoEBC
ElasticSearch-Write:
https://help.aliyun.com/knowledge_detail/74362.html?spm=a2c4g.11186631.2.18.3a474c0782SNCw
样例及说明
略
3.2.2 开源组件
3.2.2.1 Canal/Canal adapter
https://github.com/alibaba/canal/tree/master/client-adapter
该方案的优点
1、 可支持并发,github源码方便调整,支持sql条件导出,并有对应的es6,es7版本,方便版本适配
该方案的缺点
1、 相关功能需依据具体的迁入表结构作更详细的功能验证,如相关迁入表对应的分词,查询建议名段等
2、 插件分页逻辑需调整优化下,目前代码内部直接是limit分页,改动量小
简单验证(550万记录数),调整插件的分页逻辑后大概可以提高百分之十五速度
原方式:sql + " LIMIT " + offset + "," + size;
调整后方式: SELECT * FROM xxx WHERE ID > =(select id from xxx limit 1000000, 1) limit 20;
3.2.2.2 logstash
Logstash是es组件套餐中用来同步数据的,本身支持全量的从mysql同步至es
该方案的优点:
1、 本身和es属同一家产品,与es无缝对接
2、 支持SQL方式指定同步数据
3.2.2.3 datax
该方案的优点
1、 执行效率高,可支持并发
该方案的缺点
1、 目前并不支持es6.0版本以上的写入,需添加相关的插件支持
方案建议
选择方案一/方案二,基于方案一主要是组件方式,需在阿里云上购买