elasticsearch设计的理念就是分布式搜索引擎,底层实现还是基于Lucene的,核心思想是在多态机器上启动多个es进程实例,组成一个es集群。
es的索引数据存储结构:
es中,存储数据的基本单位就是索引,一个索引就像数据库。而type就相当于每一张表,一个index里面可以有多个type,而mapping就相当于表的结构定义,定义了什么字段类型等,你往index的一个type里添加一行数据就叫做一个document,每一个document有多个filed,每一个filed就代表这个document的一个字段的值。
分片:
在一个搜索里存储的数据,潜在的情况下可能会超过单个节点的硬件的存储限制,为了解决这个问题,elasticsearch便提供了分片的功能,它可以将索引划分为多个分片,当你创建一个索引的时候,你就可以简单的定义你想要的分片的数量,每一个分片本身是一个全功能的完全独立的索引,可以部署到集群中的任何一个节点。
备份:
在一个网络情况下,故障可能会随时发生,有一个故障恢复机制是必须的,为了达到这个目的,ES允许你制作一个或多个拷贝放入一个叫做复制分片或短暂的复制品中。复制可为es分布式系统提供高可用性和高并发处理能力。
es的数据写入、读取和检索过程
数据写入过程
- 客户端向coordinating node (协调节点)发送请求
- 协调节点对document进行路由,将请求转发给对应的node
- node上的primary shard处理请求,然后将数据同步到replica node
4.协调节点监听3过程,在primary node和所有的replica node都搞定之后,返回写入结果到客户端
数据读取过程
查询,GET某一条的数据,写入某个document,这个document会自动给你分配一个全局的唯一ID,同时跟住这个ID进行hash路由到对应的primary shard上面去,当然也可以手动的设置ID
- 客户端发送任何一个请求到任意一个node,成为协调节点
- 协调节点对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮训算法,在primary shard 以及所有的replica中随机选择一个,让读请求负载均衡
- 接受请求的node,返回document给协调节点
- 协调节点返回结果给客户端
搜索数据过程
- 客户端发送一个请求给协调节点
- 协调节点将搜索的请求转发给所有的shard对应的primary shard 或replica shard
- query phase:每一个shard 将自己搜索的结果(其实也就是一些唯一标识),返回给协调节点,有协调节点进行数据的合并,排序,分页等操作,产出最后的结果
- fetch phase ,接着由协调节点,根据唯一标识去各个节点进行拉去数据,最总返回给客户端
采坑ES版本问题
在ES使用过程中我遇到了几个版本兼容的问题,在这里列出。
以下两个问题为ES2和ES5之后的兼容问题,ES2.x版本使用类型String, 5.x以后使用类型text + keyword。
– @Field注解不生效
虽然项目启动不会失败,但是会报Error:No type specified for field
解决:为每个Field添加Type。
教训:我之前是注意到了这个Error的,但是项目启动成功,所以没有在意,但就是这个藏在启动日志中的Error,导致我排查错误始终找不到原因。所以:不能放过任何错误日志!!
@Field(type = FieldType.String, searchAnalyzer = "ik_max_word",analyzer = "ik_smart")
private String tags;
/**
* 写了index没有写type
* 结果为 整个Document初始化索引失败(没有索引)
* ↓默认不会阻止发布
* 会报failed to load elasticsearch nodes : org.elasticsearch.index.mapper.MapperParsingException: No type specified for field [testLong]
* ↓显示调用putMapping会阻止发布(建议初始化时显示调用)
* ElasticsearchTemplate elasticsearchTemplate.putMapping(QuestionAnswerRecord.class);
* 如插入:
* 整个Document都会按照默认规则建立index
* 查询not_analyzed不会生效!not_analyzed不会生效!not_analyzed不会生效!
*/
–创建Mapping出错
ES2.x版本使用类型String, 5.x以后使用类型text + keyword。
"type": "string",
"index": "not_analyzed" //keyword使用
https://stackoverflow.com/questions/47452770/no-handler-for-type-string-declared-on-field-name
SpringBoot和ES版本冲突问题
可以指定es版本来解决?
es依赖log4j版本,5.2的es对应log4j2.7以下
ES 5.x IK插件安装
https://github.com/medcl/elasticsearch-analysis-ik
在bin目录下(centos加./)
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v5.6.0/elasticsearch-analysis-ik-5.6.0.zip
elasticsearch 外网访问9200端口访问
系统centos6.5
可以访问127.0.0.1:9200,但不能访问 公网IP:9200
后面ip就是127.0.0.1的局域网ip,如何解决?
修改配置文件 config/elasticsearch.yml
network.host: 0.0.0.0