搜索-Elasticsearch基础

Elasticsearch基本操作

查看集群信息

命令行curl或者浏览器查看es集群节点信息

curl http://172.19.152.20:8004/_cat/nodes

增删改查操作

update

curl -XPOST http://192.168.1.211:8030/index_test_002/index_test_002/0017a0cb-ad1d-4458-b86e-c8b8d2b7d3f6/_update -d '{"doc":{"content_time": "1539936484"}}' -H 'Content-Type:application/json'

search

curl -XPOST http://192.168.1.211:8030/index_test_002/index_test_002/_search -d '{"query": {"term": {"file_id": "b6a0d7ef-4cb2-460c-8b41-b4c6601830e2"}}}' -H 'Content-Type:application/json'

delete_by_query

curl -XPOST http://192.168.1.211:8030/index_test_002/index_test_002/_delete_by_query -d '{"query": {"term": {"file_id": "378da82b-2e35-49ad-aac3-621052350e1c"}}}' -H 'Content-Type:application/json'

查看各个索引库信息

查看所有index的信息 如文件数等

curl 'http://172.19.137.156:8030/_cat/indices/prod_index_2?v'

查看指定index的信息

GET _cat/indices/test?v

es的curl操作

查看es索引的mapping

curl -XGET "http://192.168.1.211:8030/index_dev_001/_mapping?pretty"

什么是Elasticsearch

Elasticsearch 是一个分布式、可扩展、实时的搜索与数据分析引擎

Elasticsearch 不仅存储文档,而且索引每个文档的内容使之可以被检索。在Elasticsearc 中,你对文档进行索引、检索、排序和过滤--而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。

分布式的实时文件存储,每个字段都被索引并可被搜索

分布式的实时分析搜索引擎

可以扩展到上百台服务器,处理PB级结构化或非结构化数据

Elasticsearch的特点

高可用

面向文档

Restful API

基于Apache Lucene™

实时

支持插件机制,分词插件、同步插件、Hadoop插件、可视化插件等。

Lucene的原理

全文检索的一般过程

索引创建 (Indexing)

搜索索引 (Search)

由于从字符串到文件的映射是文件到字符串映射的反向过程,于是保存这种信息的索引称为反向索引

搜索过程转换为合并链表的过程:

找既包含字符串“lucene”又包含字符串“solr”的文档:

相对于顺序搜索,全文检索的优势:

一次索引,多次使用

创建索引的过程

分词(Tokenizer)

语言处理(Linguistic Processor)

大小写,单词转换为词根(eg 复数变单数等)

将词传给索引组件

1.创建字典

2.对字典按字母进行排序

3.合并相同的词成为倒排表

合并相同的词(Term) 成为文档倒排(Posting List) 链表:

搜索索引的过程

用户输入查询语句

对查询语句进行词法分析,语法分析,及语言处理

1.语法分析-识别单词和关键字+形成语法树

2.语言处理

搜索索引,得到符合语法树的文档

根据得到的文档和查询语句的相关性,对结果进行排序

对结果进行排序

如何计算文档和查询语句的相关性呢?

1.找出词(Term) 对文档的重要性的过程称为计算词的权重(Term weight) 的过程。

Term Frequency (tf):即此Term在此文档中出现了多少次。tf 越大说明越重要。

Document Frequency (df):即有多少文档包含次Term。df 越大说明越不重要。

2.判断Term之间的关系从而得到文档相关性的过程,也即向量空间模型的算法(VSM)

所有此文档中词(term)的权重(term weight) 看作一个向量。

Document = {term1, term2, …… ,term N}

Document Vector = {weight1, weight2, …… ,weight N}

同样我们把查询语句看作一个简单的文档,也用向量来表示。

Query = {term1, term 2, …… , term N}

Query Vector = {weight1, weight2, …… , weight N}

通过两个向量的夹角--夹角越小,相关性越大

索引创建和搜索全过程:

Elasticsearch的基本概念

ES概念名称对应关系型数据库对应mongo

IndexDatabaseDatabase

TypeTableCollection

DocumentRow/RecordDocument

MappingSchema

node:即一个 Elasticsearch 的运行实例,使用多播或单播方式发现 cluster 并加入。

cluster:包含一个或多个拥有相同集群名称的 node,其中包含一个master node。

index:类比关系型数据库里的DB,是一个逻辑命名空间。

alias:可以给 index 添加零个或多个alias,通过 alias 使用index 和根据index name 访问index一样,但是,alias给我们提供了一种切换index的能力,比如重建了index,取名customer_online_v2,这时,有了alias,我要访问新 index,只需要把 alias 添加到新 index 即可,并把alias从旧的 index 删除。不用修改代码。

type:类比关系数据库里的Table。其中,一个index可以定义多个type,但一般使用习惯仅配一个type。

mapping:类比关系型数据库中的 schema 概念,mapping 定义了 index 中的 type。mapping 可以显示的定义,也可以在 document 被索引时自动生成,如果有新的 field,Elasticsearch 会自动推测出 field 的type并加到mapping中。

document:类比关系数据库里的一行记录(record),document 是 Elasticsearch 里的一个 JSON 对象,包括零个或多个field。

field:类比关系数据库里的field,每个field 都有自己的字段类型。

shard:是一个Lucene 实例。Elasticsearch 基于 Lucene,shard 是一个 Lucene 实例,被 Elasticsearch 自动管理。之前提到,index 是一个逻辑命名空间,shard 是具体的物理概念,建索引、查询等都是具体的shard在工作。shard 包括primary shard 和 replica shard,写数据时,先写到primary shard,然后,同步到replica shard,查询时,primary 和 replica 充当相同的作用。replica shard 可以有多份,也可以没有,replica shard的存在有两个作用,一是容灾,如果primary shard 挂了,数据也不会丢失,集群仍然能正常工作;二是提高性能,因为replica 和 primary shard 都能处理查询。另外,如上图右侧红框所示,shard数和replica数都可以设置,但是,shard 数只能在建立index 时设置,后期不能更改,但是,replica 数可以随时更改。但是,由于 Elasticsearch 很友好的封装了这部分,在使用Elasticsearch 的过程中,我们一般仅需要关注 index 即可,不需关注shard。

ES基本数据类型

核心数据类型(Core datatypes)

字符型(String datatype):string

数字型(Numeric datatypes):long:64位存储 , integer:32位存储 , short:16位存储 , byte:8位存储 , double:64位双精度存储 , float:32位单精度存储

日期型(Date datatype):date

布尔型(Boolean datatype):boolean

二进制型(Binary datatype):binary

Shards

一个分片是一个底层的工作单元 ,它仅保存了全部数据中的一部分

一个分片是一个lucene的实例

当你的集群规模扩大或者缩小时, Elasticsearch会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。

Replicas

副本是一个分片的精确复制,每个分片可以有零个或多个副本。

当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。

docker安装es 单机版

sudo docker run -d -p 9200:9200 --name="es" elasticsearch

sudo docker run -d -p 9200:9200 --name="es" hub.c.163.com/library/elasticsearch:5.5

// -Des 制定yml文件中的参数

sudo docker run -d --name="es" -p 9200:9200 -p 9300:9300 elasticsearch:2.3.5 -Des.cluster.name="elasticsearch_cluster" -Des.network.publish_host="192.168.11.131" -Des.node.name="node-master" -Des.node.master=true -Des.network.host="0.0.0.0"

docker搭建es集群

集群模式

Cluster需拥有相同的clutser.name

协同工作,分享数据,提供了故障转移和拓展的功能

节点之间是对等关系,master节点只是维护集群状态

便于横向拓展

用docker搭建elasticsearch集群

elasticsearch集群搭建example

单机组建es集群-组播

多机集群中的节点可以分为master nodes和data nodes,在配置文件中使用Zen发现(Zen discovery)机制来管理不同节点。Zen发现是ES自带的默认发现机制,使用多播发现其它节点。只要启动一个新的ES节点并设置和集群相同的名称这个节点就会被加入到集群中。

集群模式下

sudo docker-compose up -d

curl http://192.168.11.133:9200/_cat/nodes

返回:

192.168.11.132 14 96  0 0.00 0.02 0.09 di  - node-data-1

192.168.11.133  6 92 15 0.50 0.33 0.16 mdi * node-master

组播与单播

组播就是通过在你的网络中发送UDP的ping请求以发现节点,其它Elasticsearch会收到这些ping请求并且进行响应,这样随后就会形成一个集群。

在生产环境中,建议使用单播代替组播

discovery.zen.ping.unicast.hosts 集群节点列表

如果是发现其他服务器中的es服务,可以不指定端口[默认9300],如果是发现同一个服务器中的es服务,就需要指定端口了。

elasticsearch-.yml(中文配置详解)

es的使用

Python操作es示例

>>> from datetime import datetime

>>> from elasticsearch import Elasticsearch

# by default we connect to localhost:9200

>>> es = Elasticsearch()

# datetimes will be serialized

>>> es.index(index="my-index", doc_type="test-type", id=42, body={"any": "data", "timestamp": datetime.now()})

{u'_id': u'42', u'_index': u'my-index', u'_type': u'test-type', u'_version': 1, u'ok': True}

>>> es.get(index="my-index", doc_type="test-type", id=42)['_source']

{u'any': u'data', u'timestamp': u'2013-05-12T19:45:31.804229'}

ES能够代替NoSQL(eg mongodb)?

对读多写少的存储es是可以代替mongo的,特别是运行在SSD服务器上时

一般的用法是另外的数据库比如NOSQL里面有一份,然后实时同步到ES,这样一个用于键值查询,一个用于各种其他查询。

elasticsearch(lucene)可以代替NoSQL(mongodb)吗?

es search返回数据:

{'took': 3, 'timed_out': False, '_shards': {'total': 5, 'successful': 5, 'failed': 0}, 'hits': {'total': 1, 'max_score': 1.0, 'hits': [{'_index': 'hzz', '_type': 'xydd', '_id': '1', '_score': 1.0, '_source': {'document_id': 1, 'title': 'Hbase 测试数据', 'content': 'Hbase 日常运维,这是个假数据监控Hbase运行状况。通常IO增加时io wait也会增加,现在FMS的机器正常情况......'}}]}}

es的mapping

mapping不仅告诉ES一个field中是什么类型的值, 它还告诉ES如何索引数据以及数据是否能被搜索到

索引(indexing):

在Elasticsearch中存储数据的行为就叫做索引(indexing)

搜索(search):

简单搜索

DLS

带filter的DLS

全文搜索

高亮我们的搜索

filter 正如其字面意思“过滤”所说的,是起过滤的作用,任何一个document 对 filter 来说,就是match 与否的问题,是个二值问题,0和1,没有scoring的过程。

使用query的时候,是表示match 程度问题,有scroing 过程。

聚合(aggregations)

允许你在数据上生成复杂的分析统计。它很像SQL中的 GROUP BY 但是功能更强大

传统数据库对记录的查询只有匹配或者不匹配

es性能调优

搜索指标性能

1.使用分词插件,使用人工整理词库或者新词发现模块维护词库

性能调优

1.合理的分片策略

2.路由优化

3.GC调优

4.避免内存交换

5.控制索引的合并

<漫谈ElasticSearch>关于ES性能调优几件必须知道的事

参考资料:

Elasticsearch 简介

Lucene学习总结之一:全文检索的基本原理

Lucene实战

全文搜索引擎 Elasticsearch 入门教程--ruanyifeng

es权威指南

推荐阅读更多精彩内容