Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档。为了方便大家理解,我们将Elasticsearch里存储文档
数据和关系型数据库 MySQL存储数据的概念进行一个类比。
ES里的Index可以看做一个库,而Types相当于表Documents 则相当于表的行。这里Types的概念已经被逐渐弱化,Elasticsearch 6.X中,一个index下已经只能包含一个type,Elasticsearch 7.X中,Type的概念已经被删除了。
幂等性:GET,PUT,DELETE具有幂等性,多次操作结果一样。如图,PUT两次,第二次显示索引已经存在
索引已经创建好了,接下来我们来创建文档,并添加数据。这里的文档可以类比为关系型数据库中的表数据,添加的数据格式为JSON格式
在Postman中,向ES服务器发POST请求: http://127.0.0.1:9200/shopping/_doc
1.条件查询:
2.请求体中查询:
学习资料:https://www.bilibili.com/video/BV1hh411D7sb?p=29&spm_id_from=pageDriver&vd_source=448c4278f465153c0ee1bf76577b40ba
一个集群就是由一个或多个服务器节点组织在一起,共同持有整个的数据,并一起提供索引和搜索功能。一个 Elasticsearch集群有一个唯一的名字标识,这个名字默认就是"”elasticsearch”。这个名字是重要的,因为一个节点只能通过指定某个集群的名字,来加入这个集群。
集群中包含很多服务器,一个节点就是其中的一个服务器。作为集群的一部分,它存储数据,参与集群的索引和搜索功能。
一个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的时候赋予节点。这个名字对于管理工作来说挺重要的,因为在这个管理过程中,你会去确定网络中的哪些服务器对应于Elasticsearch集群中的哪些节点。
一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做"elasticseanch”的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做"elasticsearch”的集群中。
一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母),并且当我们要对这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。
能搜索的数据必须索引,这样的好处是可以提高查询速度,比如:新华字典前面的目录就是索引的意思,目录可以提高查询速度。
Elasticsearch索引的精髓:一切设计都是为了提高搜索的性能。
在一个索引中,你可以定义一种或多种类型。
一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。不同的版本,类型发生了不同的变化
一个文档是一个可被索引的基础信息单元,也就是一条数据
比如:你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON (Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。
在一个index/type 里面,你可以存储任意多的文档。
相当于是数据表的字段,对文档数据根据不同属性进行的分类标识。
mapping是处理数据的方式和规则方面做一些限制,如:某个字段的数据类型、默认值、分析器、是否被索引等等结构信息。这些都是映射里面可以设置的,其它就是处理ES里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。
一个索引可以存储超出单个节点硬件限制的大量数据。比如,一个具月10亿乂白蚁掂的索引占据1TB的磁盘空间,而任一节点都可能没月这忏人的儆工间。蚁有平T点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch 提供了将索引划分成多份的能力,每一份就称之为分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。
类似mysql分表。
分片很重要,主要有两方面的原因:
1)允许你水平分割/扩展你的内容容量。
2)允许你在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量。
至于一个分片怎样分布,它的文档怎样聚合和搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的,无需过分关心。
被混淆的概念是,一个Lucene索引我们在 Elasticsearch称作分片。一个Elasticsearch 索引是分片的集合。当 Elasticsearch 在索引中搜索的时候,他发送查询到每一个属于索引的分片(Lucene索引),然后合并每个分片的结果到一个全局的结果集。
在一个网络Ⅰ云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片(副本)。
复制分片之所以重要,有两个主要原因:
1):在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要( original/primary)分片置于同一节点上是非常重要的。
2):扩展你的搜索量/吞吐量,因为搜索可以在所有的副本上并行运行。
总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你事后不能改变分片的数量。默认情况下,Elasticsearch中的每个索引被分片1个主分片和1个复制;这意味着,如果你的集群中至少有两个节点,你的索引将会有1个主分片和另外1个复制分片(1个完全拷贝),这样的话每个索引总共就有2个分片,我们需要根据索引需要确定分片个数。
将分片分配给某个节点的过程,包括分配主分片或者副本。如果是副本,还包含从主分片复制数据的过程。这个过程是由master节点完成的。
我们的集群现在是拥有一个索引的单节点集群。所有3个主分片都被分配在 node-1 。
通过插件查看集群状态
当前我们的集群是正常运行的,但是在硬件故障时有丢失数据的风险。
在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。
当集群中只有一个节点在运行时,意味着会有一个单点故障问题——没有冗余。幸运的是,我们只需再启动一个节点即可防止数据丢失。当你在同一台机器上启动了第二个节点时,只要它和第一个节点有同样的cluster.name配置,它就会自动发现集群并加入到其中。但是在不同机器上启动节点的时候,为了加入到同一集群,你需要配置一个可连接到的单播主机列表。之所以配置为使用单播发现,以防止节点无意中加入集群。只有在同一台机器上运行的节点才会自动组成集群。
如果启动了第二个节点,我们的集群将会拥有两个节点的集群︰所有主分片和副本分片都已被分配。
Node 1和 Node2上各有一个分片被迁移到了新的Node3节点,现在每个节点上都拥有2个分片,而不是之前的3个。这表示每个节点的硬件资(CPU,RAM,IO)将被更少的分片所共享,每个分片的性能将会得到提升。
分片是一个功能完整的搜索引擎,它拥有使用一个节点上的所有资源的能力。我们这个拥有6个分片(3个主分片和3个副本分片)的索引可以最大扩容到6个节点,每个节点上存在一个分片,并且每个分片拥有所在节点的全部资源。
保存:保存数据只能由主分片处理,副本只能读取数据。(图中绿色为主分片,紫色为副本)
查询:
数据写流程:
在客户端收到成功响应时,文档变更已经在主分片和所有副本分片执行完成,变更是安全的。有一些可选的请求参数允许您影响这个过程,可能以数据安全为代价提升性能。这些选项很少使用,因为Elasticsearch已经很快,但是为了完整起见,请参考下面表格:
**新索引默认有1个副本分片,这意味着为满足规定数量应该需要两个活动的分片副本。但是,这些默认的设置会阻止我们在单一节点上做任何事情。为了避免这个问题,要求只有number_of replicas 大于1的时候,规定数量才会执行。
**
Elasticsearch使用一种称为倒排索引的结构,它适用于快速的全文搜索。
见其名,知其意,有倒排索引,肯定会对应有正向索引。正向索引(forward index) ,反向索引( inverted index)更熟悉的名字是倒排索引。
所谓的正向索引,就是搜索引擎会将待搜索的文件都对应一个文件D,搜索时将这个ID和搜索关键字进行对应,形成K-V对,然后对关键字进行统计计数
多线程操作的时候,可能会出现顺序紊乱,导致数据不对。例如 x = 3;
用户A,把数据加二
用户B,把数据减一
如果两者并发操作,顺序打乱,则最后的结果不正确。
解决办法:乐观锁,增加版本号控制
我们在使用IK分词器时会发现其实有时候分词的效果也并不是我们所期待的,有时一些特殊得术语会被拆开,比如上面得中文“一个学生”希望不要拆开,怎么做呢?其实K插件给我们提供了自定义分词字典,我们就可以添加自己想要保留得字了。
在IK分词器的config文件夹中创建一个dic结尾的文件
在添加的.dic文件中,test.dic中写入分词规则:如图,“我是一个三好学生”
接下来修改配置文件