简介
使用场景
存储
ElasticSearch天然支持分布式,具备存储海量数据的能力,其搜索和数据分析的功能都建立在ElasticSearch存储的海量的数据之上;ElasticSearch很方便的作为海量数据的存储工具,特别是在数据量急剧增长的当下,ElasticSearch结合爬虫等数据收集工具可以发挥很大用处
搜索
ElasticSearch使用倒排索引,每个字段都被索引且可用于搜索,更是提供了丰富的搜索api,在海量数据下近实时实现近秒级的响应,基于Lucene的开源搜索引擎,为搜索引擎(全文检索,高亮,搜索推荐等)提供了检索的能力。 具体场景:
- Stack Overflow(国外的程序异常讨论论坛),IT问题,程序的报错,提交上去,有人会跟你讨论和回答,全文检索,搜索相关问题和答案,程序报错了,就会将报错信息粘贴到里面去,搜索有没有对应的答案;
- GitHub(开源代码管理),搜索上千亿行代码;
- 电商网站,检索商品;
- 日志数据分析,logstash采集日志,ElasticSearch进行复杂的数据分析(ELK技术,elasticsearch+logstash+kibana);
数据分析
ElasticSearch也提供了大量数据分析的api和丰富的聚合能力,支持在海量数据的基础上进行数据的分析和处理。具体场景:
爬虫爬取不同电商平台的某个商品的数据,通过ElasticSearch进行数据分析(各个平台的历史价格、购买力等等);
架构
- Gateway是ES用来存储索引的文件系统,支持多种类型。
- Gateway的上层是一个分布式的lucene框架。
- Lucene之上是ES的模块,包括:索引模块、搜索模块、映射解析模块等
- ES模块之上是 Discovery、Scripting和第三方插件。Discovery是ES的节点发现模块,不同机器上的ES节点要组成集群需要进行消息通信,集群内部需要选举master节点,这些工作都是由Discovery模块完成。支持多种发现机制,如 Zen 、EC2、gce、Azure。Scripting用来支持在查询语句中插入javascript、python等脚本语言,scripting模块负责解析这些脚本,使用脚本语句性能稍低。ES也支持多种第三方插件。
- 再上层是ES的传输模块和JMX.传输模块支持多种传输协议,如 Thrift、memecached、http,默认使用http。JMX是java的管理框架,用来管理ES应用。
- 最上层是ES提供给用户的接口,可以通过RESTful接口和ES集群进行交互。
[[ 小提示:目前市场上开放源代码的最好全文检索引擎工具包就属于 Apache 的 Lucene了。但是 Lucene 只是一个工具包,它不是一个完整的全文检索引擎。Lucene 的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。目前以 Lucene 为基础建立的开源可用全文搜索引擎主要是 Solr 和 Elasticsearch。Solr 和 Elasticsearch 都是比较成熟的全文搜索引擎,能完成的功能和性能也基本一样。但是 ES 本身就具有分布式的特性和易安装使用的特点,而 Solr 的分布式需要借助第三方来实现,例如通过使用 ZooKeeper 来达到分布式协调管理。不管是 Solr 还是 Elasticsearch 底层都是依赖于 Lucene,而 Lucene 能实现全文搜索主要是因为它实现了倒排索引的查询结构。]]
核心概念
物理模型
集群(Cluster)
包含一个或多个具有相同 cluster.name 的节点.
- 集群内节点协同工作,共享数据,并共同分担工作负荷。
- 由于节点是从属集群的,集群会自我重组来均匀地分发数据.
- cluster Name是很重要的,因为每个节点只能是群集的一部分,当该节点被设置为相同的名称时,就会自动加入群集。
- 集群中通过选举产生一个mater节点,它将负责管理集群范畴的变更,例如创建或删除索引,添加节点到集群或从集群删除节点。master 节点无需参与文档层面的变更和搜索,这意味着仅有一个 master 节点并不会因流量增长而成为瓶颈。任意一个节点都可以成为 master 节点。我们例举的集群只有一个节点,因此它会扮演 master 节点的角色。
- 作为用户,我们可以访问包括 master 节点在内的集群中的任一节点。每个节点都知道各个文档的位置,并能够将我们的请求直接转发到拥有我们想要的数据的节点。无论我们访问的是哪个节点,它都会控制从拥有数据的节点收集响应的过程,并返回给客户端最终的结果。这一切都是由 Elasticsearch 透明管理的
节点(Node)
一个节点代表一个es所在jvm进程,通常情况我们会在一台物理机上部署1~n个es进程,每个进程叫做一个节点或实例。不过单个机器所能承载的节点数通常是有限的
- master: node.master:true 的节点,表示 有资格参与master竞选 的节点,主节点通常用来管理集群状态,节点发现,元数据信息管理等作用。 特别注意: 真正的主节点只有一个,其他的master node仅仅是具有选举权但并不起到主节点的作用。
- data: node.data:true 的节点,表示存储数据节点。数据节点用来存储索引的数据到磁盘,并不参与主节点选取,集群状态维护等工作,通常数据节点会选择性能比较好的机器(ssd,大内存等)部署。
- tribe: 该角色在6.x以及更高的版本被移除了,在5.x版本中该角色用来执行跨集群搜索/写入等路由功能
ingest: node.ingest:true 的节点,用来对请求进行过滤转换操作,支持Pipline配置,通常用在ETL的环节中。 - coordinate: 这个角色比较特殊,也十分重要,我们可以称之为 协调节点 因为每个节点都是潜在的协调节点,当一个节点不属于以上四种之一时,它也是一个协调节点,可以把它当成NGINX一样作为请求路由的功能。
索引(Index)
索引与关系型数据库实例(Database)相当。索引只是一个 逻辑命名空间,它指向一个或多个分片(shards),内部用Apache Lucene实现索引中数据的读写。es的索引可以理解为每个Lucene索引组成的集合,一组Lucene索引构成了一个完整的es索引。
分片(Shard)
分片是索引之下的概念,每个分片其实本质上就是一个Lucene索引,多个索引构成了一个完整的es索引。
分片又可以分为主分片和副本,主分片是一个完整索引的一部分数据,而副本是一个主分片的镜像。
注意同一个编号主分片和副本不可以出现在同一个机器上,这样不能满足容灾和副本负载的功能,没有意义。
可以这么说:主分片的作用是能够起到数据跨机器存储,降低单机存储的压力,而副本的作用是起到数据容灾和负载均衡的功能。其实这本质上和传统的分布式系统的分片概念是一样的,所以说es是一个带有特殊结构的分布式文件系统不为过。一个分片默认最大文档数量是20亿。
副本(replica)
ES默认为一个索引创建5个主分片, 并分别为其创建一个副本分片. 也就是说每个索引都由5个主分片成本, 而每个主分片都相应的有一个copy.
对于分布式搜索引擎来说, 分片及副本的分配将是高可用及快速搜索响应的设计核心.主分片与副本都能处理查询请求, 它们的唯一区别在于只有主分片才能处理索引请求.
段(Segment)
一个段是一个Lucene索引内部的分片,实际上段不是es原生的概念,而是Lucene的特性,每当Lucene写入一次数据并落盘时都会产生一个分段,分段是不可变的,只能读取和删除。
索引缓冲区(IndexBuffer)
当我们写入一条数据时,数据并不会直接写入底层文件中,而是会先放入某一个实例下的index buffer内,当index buffer触发策略同步索引时才会真正发起一次写入操作,底层Lucene则是会发起一次 segment commit, 产生一个新的段,此时数据可以被检索到。这个过程我们可以称之为 refresh
Index Buffer同步策略有2个:
- 当达到 index.refresh_interval的时长,执行一次refresh
- 当IndexBuffer写满时,触发一次 refresh。
策略1默认时间为1秒,策略2 IndexBuffer默认大小为当前es进程内存的10%。因此我们说es是准实时的搜索引擎,数据写入到能被查询到至少有1秒的延迟。
由此我们还可以得出结论:需要实时准确查询得到结果的业务(例如对账)不可以依赖es。
事务日志(TransLog)
用过Mysql、Redis和Hbase等分布式系统的同学对事务日志一定不陌生,这类日志通常也被称作:WAL(Write Ahead Log),即每次写入数据同时都会将写数据行为记录到一个日志中,这个日志包括了数据本身和操作(插入更新删除),作用是用来在节点发生宕机时对数据进行修复。es的事务日志叫做translog,每当一次写请求到来时es将记录这一次操作,当节点宕机后,es会根据commit point对数据进行恢复。
同时translog也是有大小限制的,每当translog达到一定大小或一定时间时会执行一次flush操作,强制将文件系统缓存中的数据同步到磁盘中(即产生一次磁盘IO),并清空日志。
数据模型
文档类型(Type)
相当于数据库中的table概念。每个文档在ElasticSearch中都必须设定它的类型。文档类型使得同一个索引中在存储结构不同文档时,只需要依据文档类型就可以找到对应的参数映射(Mapping)信息,方便文档的存取。改概念在高版本的ES中已废弃
**文档(Document) **
相当于数据库中的row, 是可以被索引的基本单位。例如,你可以有一个的客户文档,有一个产品文档,还有一个订单的文档。文档是以JSON格式存储的。在一个索引中,您可以存储多个的文档。请注意,虽然在一个索引中有多分文档,但这些文档的结构是一致的,并在第一次存储的时候指定, 文档属于一种 类型(type),各种各样的类型存在于一个 索引 中。
Mapping
相当于数据库中的schema,用来约束字段的类型,不过 Elasticsearch 的 mapping 可以自动根据数据创建
ES数据架构的主要概念与关系数据库Mysql对比