Posted by:
努力记

努力记,通过记录,计划,让自己的努力可以触碰彩虹!

8,893

Elasticsearch:搜索引擎

  • 2014-06-21
  • 暂无评论

ElasticSearch 是开源搜索平台领域的一个新成员。 ElasticSearch(简称 ES) 是一个基于 Lucene 构建的开源,分布式,RESTful 搜索引擎。 设计用于云计算中,能够达到搜索实时、稳定、可靠和快速,并且安装使用方便。 支持通过 HTTP 请求,使用 JSON 进行数据索引。
中文介绍:http://www.elasticsearch.cn/
作者的介绍:https://speakerdeck.com/kimchy/the-road-to-a-distributed-search-engine
Lucene实现实时搜索的原理:http://es-cn.medcl.net/guide/concepts/scaling-lucene/building-blocks/index.html

elasticsearch

 

对比:
Solr也是基于Lucene构建的搜索引擎
相对于目前的应用需求而言,ES能更快更方便的实现到所需的技术方案
特点:
1.更快、更自由的执行搜索
2.安装简单方便
3.可以简单的通过HTTP 使用JSON索引数据
4.分布式,可以实现对集群的搜索,且非常方便的部署集群
5.实现简单的多租户
6.全文检索(这个是支持搜索引擎的功能,总的来说,就算没这个功能,ES也能作为一款Nosql来使用了)

自由和面向文档的模式

搜索引擎的数据模型属于模式自由以及数据库是面向文档的,以目前#nosql的发展趋势来看,使用这种数据模型来构建应用程序已经被证明是非常高效的。

elasticsearch 的模型基于 JSON, 事实上,在近些年,它俨然已经成为数据呈现的一个标准,此外,通过JSON,可以非常简单的表示半结构化的数据,同样的,大多数编程语言都会优先支持JSON数据的解析.

模式映射(Schema Mapping)

elasticsearch是无模式的,你随便往里面扔一个JSON格式的文档,然后ES就可以自动的进行索引。输入的内容如果是数字或者是时间类型,ES也自动的检测出来,并做相应的处理。

但是,众所周知,搜索引擎是非常复杂的,索引文档中的字段是可以设置BOOST值来影响打分的,另外还可以使用不同的分析器(Analyzer)用来控制怎么分词,比如有些字段是需要进行分词的,但是有些则不一定,如此等等。elasticsearch允许你完全控制这些规则,最终将一个JSON文档映射到搜索引擎里面。并且可以按索引(Index)和按类型(Type)2种级别来进行设置.。

获取数据(GETting Some Data)

每个索引的文档都必须要有一个唯一标识(在类型级别),在很多时候这是非常有用的,比如你想更新或者删除某一个索引文档,或者只是想拿一条索引数据看看。获取数据真是简单的不能再简单了,你只需用告诉es指定文档的索引、类型、和id就可以拿回实际的索引文档了(就是你建索引的时候的JSON文档)。

搜索(Search)

处理查询只需要一个简单的请求,里面隐藏了很多复杂的es提供的基于分布式的操作。可以简单的使用 Lucene通用的语法,或者使用基于JSON格式QueryDSL(DSL:领域特定语言)来构造搜索各种请求(更加灵活,方便构造复杂查询)。

搜索可不仅仅就是查询就结束了,方面/层面(facets),高亮,自定义脚本等等都是支持的。

多租户(Multi Tenancy)

单个索引既然已经有了,那为什么还会需要不止一个索引呢,其实,有很多原因需要支持多索引,比如,对日志索引可以按周来分别存放,或者是对不同的索引进行不同的设置(比如,一个使用内存作为存储,一个使用文件系统来存储)。

当有了多个索引之后,我们就想要能够跨索引来进行搜索(或者其他操作)。

 设置(Settings)

能够进行配置本身就是一把双刃剑,我们想要的是能够打开就能尽快运行,中间无需任何配置,并且当有需要的时候能够控制应用程序的几乎所有方面。

elasticsearch 从构建之初就这种理念,所以几乎所有事情都是可配和可插拔的,此外,每个索引(index)都有其独立的配置,用来覆盖主配置(master settings)。举例来说,一个索引可以配置为使用内存存储,10个分片和1个副本,而另外一个索引可以是使用文件系统存储,1个分片和10个副本。所有的索引级别(index)的设置都是可以在创建索引的时候通过YAML或者JSON格式来进行指定的。

分布式(Distributed)

elasticsearch的一个最主要的功能就是对分布式的支持,索引能够分拆为多个分片,每个分片可以有0个或者多个副本,集群中的每个数据节点,都可以承载一个或者多个分片,并且充当协调和处理各种操作分发到合适的分片上去。再平衡(Rebalancing)和路由(routing)这一切都是自动进行的。

时间之门(Gateway)

也许有一天,整个集群会崩溃(谁也无法保证因为什么原因),或者是因为特殊需要而进行关停,大多数情况,我们是需要让集群恢复到最后的一个状态的,并且让服务重新run起来 ,elasticsearch提供了一个叫做gateway的模块,允许你来做这件事情,你可以想想时间机器和搜索的结合。

集群的状态信息(包括事务日志)可以通过每个本地存储(默认模式)来重建,或共享存储(如NFS或者Amazon S3),当使用共享存储,集群状态信息会异步的复制过去。

此外,当使用共享存储来做持久化,索引信息可以完全的存放在内存里面,就算做整个集群的关闭再恢复也不会有问题。

 

概念

1.cluster

代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说 的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通 信和与整个es集群通信是等价的。

2.shards

代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。

3.replicas

代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当个某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。

4.recovery

代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。

5.river

代表es的一个数据源,也是其它存储方式(如:数据库)同步数据到es的一个方法。它是以插件方式存在的一个es服 务,通过读取river中的数据并把它索引到es中,官方的river有couchDB的,RabbitMQ的,Twitter的,Wikipedia 的。

6.gateway

代表es索引的持久化存储方式,es默认是先把索引存放到内存中,当内存满了时再持久化到硬盘。当这个es集群关闭再 重新启动时就会从gateway中读取索引数据。es支持多种类型的gateway,有本地文件系统(默认),分布式文件系统,Hadoop的HDFS和 amazon的s3云存储服务。

7.discovery.zen

代表es的自动发现节点机制,es是一个基于p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。

8.Transport

代表es内部节点或集群与客户端的交互方式,默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、memcached、zeroMQ等的传输协议(通过插件方式集成)。

 

ES本身并不需要多少的配置,主要就修改2个配置文件

http://www.elasticsearch.cn/guide/reference/setup/configuration.html

logging.yml 很明显这个是日志的配置文件,使用的是log4j来记录日志的elasticsearch.yml:

cluster.name: elasticsearch
配置es的集群名称,默认是elasticsearch,es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。

node.name: “Franz Kafka”
节点名,默认随机指定一个name列表中名字,该列表在es的jar包中config文件夹里name.txt文件中,其中有很多作者添加的有趣名字。

node.master: true
指定该节点是否有资格被选举成为node,默认是true,es是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master。

node.data: true
指定该节点是否存储索引数据,默认为true。

index.number_of_shards: 5
设置默认索引分片个数,默认为5片。

index.number_of_replicas: 1
设置默认索引副本个数,默认为1个副本。

path.conf: /path/to/conf
设置配置文件的存储路径,默认是es根目录下的config文件夹。

path.data: /path/to/data
设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开,例:
path.data: /path/to/data1,/path/to/data2

path.work: /path/to/work
设置临时文件的存储路径,默认是es根目录下的work文件夹。

path.logs: /path/to/logs
设置日志文件的存储路径,默认是es根目录下的logs文件夹

path.plugins: /path/to/plugins
设置插件的存放路径,默认是es根目录下的plugins文件夹

bootstrap.mlockall: true
设置为true来锁住内存。因为当jvm开始swapping时es的效率会降低,所以要保证它不swap,可以把ES_MIN_MEM和ES_MAX_MEM两个环境变量设置成同一个值,并且保证机器有足够的内存分配给es。同时也要允许elasticsearch的进程可以锁住内存,linux下可以通过`ulimit -l unlimited`命令。

network.bind_host: 192.168.0.1
设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0。
network.publish_host: 192.168.0.1
设置其它节点和该节点交互的ip地址,如果不设置它会自动判断,值必须是个真实的ip地址。

network.host: 192.168.0.1
这个参数是用来同时设置bind_host和publish_host上面两个参数。

transport.tcp.port: 9300
设置节点间交互的tcp端口,默认是9300。

transport.tcp.compress: true
设置是否压缩tcp传输时的数据,默认为false,不压缩。

http.port: 9200
设置对外服务的http端口,默认为9200。

http.max_content_length: 100mb
设置内容的最大容量,默认100mb

http.enabled: false
是否使用http协议对外提供服务,默认为true,开启。

gateway.type: local
gateway的类型,默认为local即为本地文件系统,可以设置为本地文件系统,分布式文件系统,hadoop的HDFS,和amazon的s3服务器,其它文件系统的设置方法下次再详细说。

gateway.recover_after_nodes: 1
设置集群中N个节点启动时进行数据恢复,默认为1。

gateway.recover_after_time: 5m
设置初始化数据恢复进程的超时时间,默认是5分钟。

gateway.expected_nodes: 2
设置这个集群中节点的数量,默认为2,一旦这N个节点启动,就会立即进行数据恢复。

cluster.routing.allocation.node_initial_primaries_recoveries: 4
初始化数据恢复时,并发恢复线程的个数,默认为4。

cluster.routing.allocation.node_concurrent_recoveries: 2
添加删除节点或负载均衡时并发恢复线程的个数,默认为4。

indices.recovery.max_size_per_sec: 0
设置数据恢复时限制的带宽,如入100mb,默认为0,即无限制。

indices.recovery.concurrent_streams: 5
设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5。

discovery.zen.minimum_master_nodes: 1
设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)

discovery.zen.ping.timeout: 3s
设置集群中自动发现其它节点时ping连接超时时间,默认为3秒,对于比较差的网络环境可以高点的值来防止自动发现时出错。

discovery.zen.ping.multicast.enabled: false
设置是否打开多播发现节点,默认是true。

discovery.zen.ping.unicast.hosts: ["host1", "host2:port", "host3[portX-portY]“]
设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。

下面是一些查询时的慢日志参数设置
index.search.slowlog.level: TRACE
index.search.slowlog.threshold.query.warn: 10s
index.search.slowlog.threshold.query.info: 5s
index.search.slowlog.threshold.query.debug: 2s
index.search.slowlog.threshold.query.trace: 500ms

index.search.slowlog.threshold.fetch.warn: 1s
index.search.slowlog.threshold.fetch.info: 800ms
index.search.slowlog.threshold.fetch.debug:500ms
index.search.slowlog.threshold.fetch.trace: 200ms

 

插件:

Elasticsearch有很多官方和第三方开发的插件,以分词、同步、数据传输、脚本支持、站点、其它这几个类别进行划分

http://www.searchtech.pro/elasticsearch-plugins

2款管理插件(通过github进行插件安装,非常方便)

  • mobz/elasticsearch-head
  • lukas-vlcek/bigdesk

插件安装:在bin目录下:plugin -install lukas-vlcek/bigdesk
通过http接口访问插件:http://xxxxx:port/_plugin/xxxx

Mapping:
EC中通过定义Map来确定索引结构,并且一旦确定只能添加不能修改

方便理解,将elasticsearch 跟 MySQL 中定义资料格式的角色关系对照表如下:

MySQL  
elasticsearch
database 
index
table
 type
table schema 
mapping
row
document
field 
  field

添加Mapping:PUT  index/type _mapping json数据格式定义

在生产环境中为了实现平滑过度多个索引,可以通过索引别名的方式进行处理
添加别名:POST _aliases actions.add{alias:'',index:''}

删除旧别名:POST _aliases action.remove{alias:'',index:''}

删除索引:DELETE ''

Analyzer:

全文搜索引擎会用某种算法对要建索引的文档进行分析, 从文档中提取出若干Token(词元), 这些算法称为Tokenizer(分词器), 这些Token会被进一步处理, 比如转成小写等, 这些处理算法被称为Token Filter(词元处理器), 被处理后的结果被称为Term(词), 文档中包含了几个这样的Term被称为Frequency(词频)。 引擎会建立Term和原文档的Inverted Index(倒排索引), 这样就能根据Term很快到找到源文档了。 文本被Tokenizer处理前可能要做一些预处理, 比如去掉里面的HTML标记, 这些处理的算法被称为Character Filter(字符过滤器), 这整个的分析算法被称为Analyzer(分析器)。

http://www.cnblogs.com/buzzlight/p/elasticsearch_analysis.html

 

查询:

ElasticSearch是基于lucene的开源搜索引擎,它的查询语法关键字跟lucene一样,如下:

    - 分页:from/size
    - 字段:fields
    - 排序:sort
    - 查询:query
    - 过滤:filter
    - 高亮:highlight
    - 统计:facet
    - 分析:analyzer


back up ↑

无觅相关文章插件,快速提升流量