1:elasticsearch结构
elasticsearch数据库>索引库>类型>文档
相当于
mysql 数据库(对应索引)>表(对应类型)>数据(对应文档)
2:新建索引库
设置mapping设置索引type类型结构 > 类似设置mysql表数据结。
如下:新建mapping,索引-bloag索引,type表-hello,_mappings -设置mappings,里面定义了3个字段
新建索引并且设置mappings和分片副本数量
PUT /bloag1
{
"settings": {
"number_of_shards" : 3,
"number_of_replicas" : 1
},
"mappings":{
"properties": {
"id": {
"type": "long"
},
"name": {
"type": "keyword"
},
"age": {
"type": "long"
},
"msg": {
"type": "text"
}
}
}
}
POST /blog/hello/_mappings
{
"hello":{
"properties":{
"id":{
"type":"long",
"store":true
},
"title":{
"type":"text",
"store":true,
"index":true,
"analyzer":"standard"
},
"content":{
"type":"text",
"store":true,
"index":true,
"analyzer":"standard"
}
}
}
}
根据索引添加数据
POST /blog1/hello/0
{
"id":0,
"title":"库里加冕NBA历史三分王",
"content":"库里加冕NBA历史三分王具体内容"
}
搜索
1:terms搜索,搜索包含下面,可以搜索多个,不过只能一个一个字搜索
POST /blog1/hello/_search
{
"query":{
"terms": {
"title": [
"香","8"
]
}
}
}
2:query_string搜索
注意:搜索的内容是英文的话,会根据空格隔开,然后搜索,中文搜索,启用了es默认分词器,会一个字一个字的拆开搜索,对此我们要下载分词器插件进行搜索,比如ik,把ik下载下来,直接赋值下来放到我们的es的plugins目录下,重启es就行,然后使用分词器的时候,我们新建mappings的时候可以设置分词器, ik分词器有两种类型,ik_smart,ik_max_word两种类型,后面一种搜索颗粒比较细。
1:新建mappings
POST /blog/hello/_mappings
{
"hello":{
"properties":{
"id":{
"type":"long",
"store":true
},
"title":{
"type":"text",
"store":true,
"index":true,
"analyzer":"ik_max_word"
},
"content":{
"type":"text",
"store":true,
"index":true,
"analyzer":"ik_max_word"
}
}
}
}
2:搜索
POST /blog1/hello/_search
{
"query":{
"query_string": {
"default_field": "title",
"query": "锣8套房的三"
}
}
}
聚合查询
1:根据age求平均值,最大值,总和
aggs 表示使用聚合函数,
size:0 表示不查出数据,直接查出聚合结果
POST /bloag/_search
{
"size": 0,
"aggs": {
"age1": {
"avg": {
"field": "age"
}
},
"age2":{
"max": {
"field": "age"
}
},
"age3":{
"sum": {
"field": "age"
}
}
}
}
2:根据name名称进行分组,求出每个分组的年龄平均值,然后进项order排序。
GET /bloag/_search
{
"size": 0,
"aggs": {
"group_by_name": {
"terms": {
"field": "name",
"order": {
"age": "desc"
}
},
"aggs": {
"age": {
"avg": {
"field": "age"
}
}
}
}
}
}
3:原理
提升写入性能
1:用bulk接口批量写入
- 可以节省重复创建连接的网络开销
- 要通过测试才能知道最佳的一次批处理量,并不是越大越好,太大了会占用内存
- 并且bulk有个处理队列,过慢的index会导致队列满而丢弃后面的请求
2:配置慢一点的刷新频率
- es是准实时系统,新写入的分段需要被刷新才被完全创建,才可用于查询
- 慢的刷新频率可以使降低分段合并的频率,分段合并十分耗资源
- 默认刷新频率是1s,对index修改index.refresh interval即可立即生效
3:初始化性质的大量写入
- 比如reindex或是导入基础数据这种一次性批量索引操作
- 可以配置成不刷新,并且把副本数也配置成0,完了之后再设置成正常值
- 每一次写入都要等所有副本都报告写入完成才算完成,副本数量越多写入越慢
4:关闭操作系统的swapping
- 操作系统会自动把不常用的内存交换到磁盘(虚拟内存)
- es是运行于ivm的,这个操作可能会导致gc.
5:使用内部id
- 默认是指明文档id的,这样的话es需要先判断一下这个id的文档是否已经存在,以做一些合并或者更新操作
- 如果用自生成的id,则可以跳过这个步骤节省开支
6:合理设置分片和副本数量
- 分片数量影响到分段数量,分片少的话允许的分段数也会少,从而会增加分段合并的频率,消耗性能
- 如果写入规模巨大,要控制index的规模(按月、按周、按天适当分,或自动滚动)
,同时根据集群节点数量设置合适的分片数,使得每个分片的数据量有限 - 副本数量越多,写入越慢
7:理设置字段mapping
- 不需要分析的字段就不要分析
1:分片和副本优化
:分片大小限制
建议你多关心这条限制: ElasticSearch推荐的最大JVM堆空间是30~32G, 所以把你的分片最大容量限制为30GB, 然后再对分片数量做合理估算. 例如, 你认为你的数据能达到200GB, 我们推荐你最多分配7到8个分片.
单机的服务内存,一般设置是分片内存存储大小的2.8倍(在一个副本的情况下),一个副本就相当于两倍,还有其他开销。
:分片规则
一个好的方案是根据你的节点数量按照1.5~3倍的原则来创建分片.
例如,如果你有3个节点, 则推荐你创建的分片数最多不超过9(3x3)个.
注意:
分片es分片规则会尽量的把分片跟副本平均分配到每个节点上。
分片的时候,分片副本不会在本节点上,只会在其他节点上,这样避免了,节点挂掉,丢失数据,实现高可用。
当一个节点挂掉时,主节点会重新把分片跟副本储存在其他节点上,集群最少两个节点
2:es选举方式
1:Elasticsearch选举master的时候, 当加入一个节点, 如果之前的Elasticsearch集群已经正常的在运行, 那么此时这个节点的加入会选择接受之前的master, 然后自己连接master并加入这个master构成的集群。
2:如果是整个master集群刚开始初始启动的时候,这时候情况就会不同,就会出现选举master的过程。 这时候的选举可能选到了自己作为master, 也有可能是接受其他节点的master。
总结
搜索引擎原理
反向索引又叫倒排索引,是根据文章内容中的关键字建立索引。
搜索引擎原理就是建立反向索引。
Elasticsearch 在 Lucene 的基础上进行封装,实现了分布式搜索引擎。
Elasticsearch 中的索引、类型和文档的概念比较重要,类似于 MySQL 中的数据库、表和行。
Elasticsearch 也是 Master-slave 架构,也实现了数据的分片和备份。选举模式,主从复制(只有在新建索引和type的时候用到,添加数据的时候,直接添加到某个节点。)
Elasticsearch 一个典型应用就是 ELK 日志分析系统。
4:elasticsearch集群
配置文件添加:修改config>elasticsearch.yml文件
注意:网络互通
# =================es集群配置==============
#
# 配置es集群的名称,es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群
cluster.name: my-application
#
# 节点名称
node.name: node-1
#
#指定该节点是否有资格被选举成为node
node.master: true
#
#指定该节点是否存储索引数据,默认为true
node.data: true
#
# 设置绑定的IP地址,还有其他节点和该节点交互的IP地址,本机ip
network.host: 127.0.0.1
#
# 指定http端口
http.port: 9201
#
# 设置节点间交互的tcp端口,默认9300
transport.tcp.port: 9301
#
# 设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点
# 因为另外两台节点的端口自会设置为9301和9302,所以写入两台es的完整地址
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
#
# 初始化主节点,在启动集群时,指定一个指定node-1为主节点
cluster.initial_master_nodes: node-1
#
# 如果需要使用head,那么需要解决跨域问题,使head插件可以访问es
http.cors.enabled: true
http.cors.allow-origin: "*"