在现实生活中,大多数面向用户的系统,都应该提供一些基本的查询搜索功能,
这将更好帮助用户找到自己想要的数据,不论从性能还是查询能力,
都会比DB更强大,从而也是减轻DB压力的一种途径,
本文将对ES进行一些初探。
-
简介
ElasticSearch(下文称ES)是一款分布式且高可扩展的全文搜索和分析引擎,本身是基于Lucene进行开发,
同类的应该还有Solr,Hibernate Search等,
但ES足够简单易用,提供丰富的API,部署容易。
-
常用案例
-
这是一些常用的案例
1. 典型的电商网站,可以让用户搜索商品,类目等。
2. 日志查询及分析,ES有一套专门的日志收集,分析,聚合的技术栈:Elasticsearch/Logstash/Kibana。
3. 预警平台,比如商品价格预警,用户希望在某类某件商品价格降到某个价位时得到通知,可以利用ES的Percolator来实现。
...
-
基本概念
-
ES中有一些关键的抽象及概念,理解它们也是十分必要的。
-
Near Realtime(NRT)
ES是一个近似实时的搜索平台,也就是说,从你索引一个文档开始,到其能被搜索,延迟会很低(通常是1s)。
-
集群(Cluster)
一个集群由多个节点(Server)构成,共同对外提供索引和查询服务。集群默认以elasticsearch作为标识,
该标识将决定一个节点属于哪一个集群,通常开发和测试保持默认,生产环境再进行定义。
-
节点(Node)
节点是集群中的单个Server,可以存储数据,并提供索引和查询服务。同集群一样,节点也会用字符串来标识自己,
若局域网内多个节点以相同的集群名称配置启动,将会自动形成一个集群。
-
索引(Index)
索引就是一些具有相似属性的文档集合。一个索引也通过名称来唯一标识,可以类比为数据库中的Scheme。
-
类型(Type)
类型就是文档所属的类,可以类比为数据库中的表。
-
文档(Document)
文档是索引信息的基本单位,并以JSON格式进行表示。
-
分片(Shards)及备份(Replicas)
单个索引本质上可以存储大量数据(可能超出单个节点的硬件限制),比如,一个索引里包含了十亿个文档,
并占用了1TB磁盘空间,这将不利于单个节点提供查询服务。为了解决这种问题,
ElasticSearch具有将索引细分为多个分片(Shards)的能力。
当你创建索引时,可以定义想要的分片数。分片即是一个具有独立功能的"索引",可以位于集群中的任何节点上。
分片主要有两个原因:
1. 水平分割扩展容量。
2. 跨分片(本质是节点)分发和并行操作,因此提升性能和吞吐量。
分片如何被分布以及它的文档如何被聚合到搜索请求中,都被ElasticSearch隐藏起来,对用户完全透明。
在分布式网络环境中,故障任何时候都可能发生,通过分片实现容错机制是十分有用并被推荐的。为此,
ElasticSearch允许对索引分片进行备份,即备份分片。备份主要有两个原因:
1. 当分片失败时提供高可用,需要注意备份分片永远不会和其主分片分配在同一节点上。
2. 这将扩展集群的搜索吞吐量,因为所有搜索可以在备份分片上并行执行。
-
大致的总结就是
每个索引可以分割为多个分片,也可以有0个或多个备份,一旦备份,
每个索引将有主分片和备份分片,
分片数和备份数可以在索引被创建时定义,索引创建后,可以动态更新备份数,但不能更新分片数。
ElasticSearch默认将每个索引分成5个分片,作1个备份,也就是说,集群中至少有2个节点,
那么索引将有5个主分片,5个备份分片。如
-
两个节点分别有5个分片,粗线表示的是主分片,细线表示的是备份分片。
-
安装部署
-
ElasticSearch(1.5.2)的安装部署比较简单,只需JAVA环境(1.7以上),
将安装包解压缩,进入bin,执行elasticsearch即可,
这是自己使用的一个标准包,其中集成了
Bigdesk,Head,
IK分词器。
-
下面是一份简明的ES脚本
-
此外封装了一个简明的Java客户端工具。
-
一些常见的配置建议
-
节点类型
-
在配置集群中的节点时, 应该明确指定各节点的角色类型。如
1. node.mater:true & node.data:true: 既为master,也为data节点,负责集群协调工作和数据存储等
2. node.mater:true & node.data:false: 为master节点,负责集群协调工作等。
3. node.mater:false & node.data:true: 为data节点,负责索引数据和搜索等。
4. node.mater:false & node.data:false: 既不是master,也不是data节点,负责搜索负载均衡(从data节点抓取数据并作处理)。
-
启用mlockall
-
启用mlockall后,ES使用的内存将不会进入Swap分区,这将大大降低磁盘I/O带来的性能问题,
但需保证ES具有足够的内存,可通过下面的API查询是否启用mlockall:
-
discovery.zen配置集群发现机制
-
Zen discover作为ES集群中节点间进行发现和交流的协议,
可通过discovery.zen.*等属性进行配置,
单播和广播都作为发现协议的一部分
1. 广播是指集群中的节点向其他所有节点发送请求。
2. 单播是指在
discovery.zen.ping.unicast.hosts指定的主机列表之间进行通信。
-
为了开启单播,需要设置
discovery.zen.ping.multicast.enabled为
false。
对于单播,必须指定属性discovery.zen.ping.unicast.hosts(单播的主机列表),
discovery.zen.minimum_master_nodes
用于设置一个节点在操作集群时能看到的最小的maser节点数,建议设置为
N/2+1(N为master节点数)。
-
数据节点和主节点通过两种方式发现彼此:
1. 主节点ping集群中的所有节点,以验证它们是否状态正常。
2. 其他节点ping主节点,验证它们是否状态正常,或者是否须要启动选举进程。
-
小心删除所有索引
-
为了防止误操作删除掉所有索引,应该禁止该这种操作
-
限制Field数据缓存
-
Field数据缓存主要用于某个字段的排序和集合,应该作一定的限制,如
-
该值设置不合理,将影响查询和排序性能,或者ES对大量索引进行facet查询时内存溢出。
-
索引优化
-
索引相关的配置可见这里,根据实际生产环境可做相应变动。
-
索引分片刷新时间
-
当Document被建立之后,仅当索引分片刷新后,该文档才可被搜索,可通过index.refresh_interval分片刷新时间。
-
事务日志刷新
1. index.translog.flush_threshold_ops: 多少次操作后刷新事务日志,默认无限制。
2. index.translog.flush_threshold_size: 一旦日志文件超出该大小,将刷新日志,默认512m。
3. index.translog.flush_threshold_period: 当一段时间没有发生过刷新时,超过该时间将强制刷新一次。
4. index.translog.interval: 多久检查一次是否刷新事务日志,将随机取值
interval ~ interval * 2,默认5s。