ES介绍

ElasticSearch作为一个广泛使用的搜索引擎,能够支撑数百个节点的集群,高可用,而且检索速度非常快。由于它受到的重视,刚开始接触它的人可能对其抱有很高的期望,认为它开箱即用,但其实还是需要对其原理有一定的了解和调优技巧的。

 

ElasticSearch存在开源版本和收费版本,开源版本在github上可以看到,收费版本没有源码,可以在一些云服务厂商购买。一般都需要至少一个ElasticSearch集群才能支持业务的需求。

而存在的场景问题是,ES集群在业务数据量很大的情况下,需要为平衡和满足数据存储,业务高峰的写入压力瓶颈,数据删除和同步等方面的需求做出调整。

ES最简单的目的就是用于检索,当然它经常跟Kibana结合,用于数据分析,因为集成了很多功能,包括机器学习,数据分析插件,所以它在商业智能领域也有很深入的应用。

ElasticSearch的数据结构

全文查询的存储、查询用到了倒排索引;原始文本以索引分隔;

存储的文件本身是一个个sharding的分片。由于跟日期关联紧密,默认的索引名中会带有日期。

集群有节点的备份;节点内有分片;

 

OES架构规划 es 架构_Elastic

 

 

目录结构:

 

OES架构规划 es 架构_数据_02

 

 

ES架构图

 

OES架构规划 es 架构_数据分析_03

 

其中 Discovery是节点发现的共识机制模块,Zen已经在7.X升级成了Zen2协议。当然可以看到索引、搜索、Mapping模块构成了数据处理的核心;

ES的运行环境和语言主要是Java,所以占用资源也会较大;在腾讯云上一个ES集群基础配置是三台2核4G,500G硬盘的主机,一主二从;

大数据量下的索引设计实现

在ES中,大的数据单个Lucene索引无法保存在一个文件,超出2^31字节(2G)的会生成新文件,读取时会造成性能下降。而且大块数据丢失会造成较大的问题。

基于此,对大索引的设计建议:

  1. 使用模板+Rollover+Curator动态创建索引。

使用效果:

index_2019-01-01-000001

index_2019-01-02-000002

  1. 滚动索引

解决大块数据丢失的情况

2.1 使用 Rollover 增量管理索引

目的:按照日期、文档数、文档存储大小三个维度进行更新索引。使用举例:

curl  --user elastic:xxxxxx -XPOST http://172.24.18.250:9200/logs_write/_rollover ‘{  "conditions": {    "max_age":   "7d",    "max_docs":  1000,    "max_size":  "5gb"  }}’

 

使用案例:

(1)维基百科和百度百科。

(2)The Guardian(国外新闻网站),用户行为日志(点击,浏览,收藏,评论)+社交网络数据(对某某新闻的相关看法),数据分析;

(3)Stack Overflow(国外的程序异常讨论论坛);

(4)GitHub(开源代码管理),搜索上千亿行代码。

(5)电商网站,检索商品。

应用场景:

(6)日志数据分析,logstash采集日志,ES进行复杂的数据分析(ELK技术,elasticsearch+logstash+kibana)

(7)BI系统,商业智能,Business Intelligence。比如说有个大型商场集团,BI,分析一下某某区域最近3年的用户消费金额的趋势以及用户群体的组成构成, ES执行数据分析和挖掘,Kibana进行数据可视化国内。

(9)国内:站内搜索(电商,招聘,门户,等等),IT 的 OA系统搜索(OA,CRM,ERP,等等),数据分析(ES热门的一个使用场景)

 

分布式协议理论与现实的鸿沟

在7.X之前,ES使用的是自己写的Zen协议,为了验证它的正确性,还使用了TLA+形式化语言进行验证。

其形式化语言是tla后缀的文件,长这样:

EXTENDS Naturals, FiniteSets, Sequences, TLC
CONSTANTS Lucene_addDocuments, Lucene_updateDocuments, Lucene_deleteDocuments
CONSTANTS ADD, RETRY_ADD, UPDATE, DELETE
CONSTANTS DocContent
CONSTANTS DocAutoIdTimestamp
CONSTANTS DuplicationLimit

Request(request_count)
    == [type: {ADD}, seqno: {1}, content: DocContent, autoTimestamp: {DocAutoIdTimestamp}]
    \cup [type: {RETRY_ADD}, seqno: 1..request_count, content: DocContent, autoTimestamp: {DocAutoIdTimestamp}]
    \cup [type: {UPDATE}, seqno: 1..request_count, content: DocContent]
    \cup [type: {DELETE}, seqno : 1..request_count]

 

在7.X的版本中,它又更新了自己的一致性协议,虽然吸取了很多学术论文的知识和经验,但是本身又超越了论文本身,在定制化协议上更进一步,甚至可以说是重新发明了一套协议。

 在官方文档中,对不使用Raft的原因解释道:

为什么不选择 Raft? [2]
我们经常被问到的一个问题是,为什么不简单地“插入”像 Raft 一样的标准分布式共识算法。有很多公认的算法,每种算法都有不同的利弊权衡。我们仔细评估了所有可以找到的文献,并从中汲取灵感。在我们早期的概念验证中,有一个概念便使用了非常接近 Raft 的协议。我们从这一经验中了解到,将其与 Elasticsearch 完全集成,需要做出非常巨大的改变。此外,许多标准算法还规定了一些对于 Elasticsearch 来说不是最佳选择的设计决策。例如:

标准算法通常是围绕操作日志构建的,而 Elasticsearch 的集群协调更多的是直接基于集群状态本身。相比基于操作可能达到的优化来说,集群协调可以更简单地对批处理(将相关操作合并到单个广播中)之类的操作进行重大优化。

标准算法在集群伸缩能力方面都相当受限,需要一系列步骤来完成许多维护任务,而 Elasticsearch 的集群协调可以在一个步骤中安全地执行任意的重配置。这通过避免不确定的中间状态简化了周围的系统。
标准算法通常过于关注安全性,而忽略了如何保证活动性的细节,也没有描述如果发现某个节点不健康时,集群该如何反应。Elasticsearch 的健康检测机制非常复杂,已经在该领域经过了多年的使用和优化,对于我们来说,维持其现在的运行状况十分重要。事实上,与保证系统的活动性相比,实现系统的安全性所需付出的成本要少得多。大多数的实现工作都集中在系统的活动性上。
项目的目标之一是,支持从运行 Zen Discovery 的 6.7 集群零中断滚动升级到运行新协调子系统的版本 7 集群。将任何标准算法调整为允许这种滚动升级的算法似乎都不可行。

基于ElasticSearch的管理平台

Kibana的网页界面如下,可以在这里进行数据的索引管理,数据分析,可视化

 

OES架构规划 es 架构_数据分析_04

 

 

也有其他开源项目:https://github.com/360EntSecGroup-Skylar/ElasticHD

支持自动根据SQL语句生成查询索引模板

 

OES架构规划 es 架构_数据_05

 

 

 

References

[1] https://cloud.tencent.com/developer/article/1122524 如何优雅的全量读取Elasticsearch索引里面的数据

[2] https://www.jianshu.com/p/b1724c49d7c9 Elasticsearch(ES)集群架构

[3]  Elasticsearch 索引设计实战指南

[4] https://www.elastic.co/blog/a-new-era-for-cluster-coordination-in-elasticsearch Elasticsearch 集群协调迎来新时代

[5] https://github.com/360EntSecGroup-Skylar/ElasticHD ElasticHD