每一个系统都拥有很多概念,这些概念是作者在设计与实现时为不同的模块或功能做的定义。概念本身只是一个名词,往往会跟随作者的喜好不同而不同,重要的是理解其设计的初衷以及要表达的实际内容,否则很快就会忘记其意义。作为专栏文章的第二篇,本文将从多个方面对Elasticsearch的核心概念进行整理,尽可能由浅入深的交代清楚每个概念,而相关的使用技巧会在后续博文中介绍。本文写作背景是Elasticsearch 5.5。
为了方便查阅,这里首先列出会涉及到的概念,读者可以根据需要选择性阅读。
1. 数据组织
1.1 逻辑组织
假设我们在一个业务系统中选择MySQL做数据存储,那么我们需要先创建一个database,再创建一组相关的table。几乎所有的数据存储系统都有类似的设计,这样做的一个基本目的在于对数据进行抽象分类,将描述同种特性的数据放在一起,可以更好的做压缩存储、查询优化等。另一方面,通过这样在逻辑层面对数据进行组织后,可以屏蔽底层的具体细节,方便在应用程序中进行操作。
Elasticsearch同样具有这样的概念,如下图所示,使用index和doc_type来组织数据。doc_type中的每条数据称为一个document,是一个JSON Object,相关的schema信息通过mapping来定义。mapping不仅仅包括数据类型的定义,还有很多其他元信息的设置,它们共同决定了数据如何被存储和索引。这四个概念实现了Elasticsearch的逻辑数据组织,假设有一批结构化或半结构化数据需要存储,我们会先对数据进行分类,设计相应的index与doc_type,再为每个doc_type设置相关的mapping信息。如果不指定mapping,Elasticsearch会使用默认值,并自动为你推导每个字段的类型,即支持schema free的特性。但是,这种灵活性也会带来一些问题,一方面会失去对数据的控制,即会越来越不清楚你的数据结构,另一方面,自动推导出来数据类型可能不是预期的,会带来写入和查询问题。所以,笔者建议,尽最大可能对schema加以约束。
通常情况下,我们都会拿Elasticsearch的这些概念跟关系型数据库对比来更好的理解,比如index等价于database,doc_type等价于table,mapping等价于db schema。但是,需要注意的是,对于关系型数据库而言,table与table之间是完全独立的,不同table的schema是完全隔离的,而Elasticsearch中的doc_type则不是。同一个index下不同doc_type中的字段在底层是合并在一起存储的,意味着假设两个doc_type中都有一个叫name的字段,那么这两个字段的mapping必须一样。基于这个原因,Elasticsearch官方从6.0开始淡化doc_type的概念,推荐一个index只拥有一个doc_type,并计划在8.x完全废弃doc_type。因此,在当前的index设计中,最好能遵循这个规则。
1.2 物理组织
Elasticsearch是一个分布式系统,其数据会分散存储到不同的节点上。为了实现这一点,需要将每个index中的数据划分到不同的块中,然后将这些数据块分配到不同的节点上存储。这里的数据块,就是shard。通过"分"的思想,可以突