ElasticSearch 安装

jopen 9年前

大数据之elasticsearch集群搭建与基本使用-渗透人员入门  

我也开始玩集群了,写此文章来纪念


一、安装手册

第一步:安装java 7(最低版本java 7)

第二步:安装及配置elasticsearch(下载最新版)

wget https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.5.1.tar.gz

tar zxvf elasticsearch-1.5.1.tar.gz

cd elasticsearch-1.5.1


修改二进制文件,指定JAVA_HOME 

(1)elasticsearch

vim bin/elasticsearch

修改

JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64(替换为实际的JAVA安装目录)


(2)plugin

vim bin/plugin

修改

JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64(替换为实际的JAVA安装目录)


修改配置文件

vim config/elasticsearch.yml

做如下修改

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

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

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

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

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

#bootstrap.mlockall: true  设置为true来锁住内存。因为当jvm开始swapping时es的效率会降低,所以要保证它不swap,因为发现开启这个选项会莫名的错误,所以选择了关闭,依靠把ES_MIN_MEM和ES_MAX_MEM两个环境变量设置成同一个足够大的值来保证机器有足够的内存分配给es。

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

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

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

discovery.zen.ping.multicast.enabled: false 设置是否打开多播发现节点,默认是false,开启单播模式

discovery.zen.ping.unicast.hosts: ["xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx"]  设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点

内存调整

vim bin/elasticsearch.in.sh

修改

if [ "x$ES_MIN_MEM" = "x" ]; then


    ES_MIN_MEM=256m #调整为机器内存的一半


fi


if [ "x$ES_MAX_MEM" = "x" ]; then


    ES_MAX_MEM=1g#调整为机器内存的一半 


fi



第三步:下载并安装插件 (插件非常多,以下列出我喜欢的,可以有选择性的安装)


(1) marvel

远程安装方式:

 bin/plugin -i elasticsearch/marvel/latest

本地安装方式:

wget https://download.elasticsearch.org/elasticsearch/marvel/marvel-latest.zip

bin/plugin -i marvel -u file:/home/elasticsearch-1.5.1/marvel-latest.zip 

在启动后,可以通过以下方式查看elasticsearch运行情况

http://xxx.xxx.xxx.xxx:8765/_plugin/marvel/ 



(2) elasticsearch service [非常喜欢]

https://github.com/elastic/elasticsearch-servicewrapper

将service文件放置在elasticsearch bin 目录下

mv elasticsearch-servicewrapper-master/service/ bin/

配置bin/service/elasticsearch.conf

vim bin/service/elasticsearch.conf 

按需作如下修改

set.default.ES_HOME=/home/elasticsearch-1.5.1 #替换为实际的elasticsearch路径

wrapper.java.command=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java #替换为实际的java二进制文件路径


(3). ElasticHQ [非常喜欢]

 http://www.elastichq.org/

bin/plugin -i royrusso/elasticsearch-HQ -u file:/home/elasticsearch-1.5.1/royrusso-elasticsearch-HQ-603ae9e.zip 


在启动后,可以通过以下方式查看elasticsearch运行情况

http://xxx.xxx.xxx.xxx:8765/_plugin/HQ/


(4) elasticsearch-head [比较喜欢]

https://github.com/mobz/elasticsearch-head

bin/plugin -i mobz/elasticsearch-head -u file:/home/elasticsarch-1.5.1/elasticsearch-head-master.zip


在启动后,可以通过以下方式查看elasticsearch运行情况

http://xxx.xxx.xxx.xxxx:8765/_plugin/head 



第四步:启动elasticsearch

bin/service/elasticsearch  start|stop|console|install|remove


start 在后台运行elasticsearch

stop 停止elasticsearch

console 在前台运行elasticsearch

install elasticsearch自启动

remove elasticsearch取消自启动


二、基本操作


首先我们批量导入示例数据——莎士比亚全集

(参照http://kibana.logstash.es/content/v3/10-minute-walk-through.html kibana 3指南10分钟入门

wget http://www.elasticsearch.org/guide/en/kibana/3.0/snippets/shakespeare.json

curl -XPUT http://localhost:8765/_bulk --data-binary @shakespeare.json

more shakespeare.json 察看存储内容

{"index":{"_index":"shakespeare","_type":"act","_id":0}}

{"line_id":1,"play_name":"Henry IV","speech_number":"","line_number":"","speaker":"","text_entry":"ACT I"}

{"index":{"_index":"shakespeare","_type":"scene","_id":1}}


接下来我们来通过与熟悉的关系数据库来对比elasticsearch的数据组成

(1)数据组成:元数据+实际数据

相当于察看数据库的模式定义

http localhost:8765/shakespeare/

返回

{

    "shakespeare": {

        "mappings": {

            "act": {

                "properties": {

                    "line_id": {

                        "type": "long"

                    }, 

                    "line_number": {

                        "type": "string"

                    }, 

                    "play_name": {

                        "type": "string"

                    }, 

                    "speaker": {

                        "type": "string"

                    }, 

                    "speech_number": {

                        "type": "long"

                    }, 

                    "text_entry": {

                        "type": "string"

                    }

                }

            }, 

            "line": {

                "properties": {

                    "line_id": {

                        "type": "long"

                    }, 

                    "line_number": {

                        "type": "string"

                    }, 

                    "play_name": {

                        "type": "string"

                    }, 

                    "speaker": {

                        "type": "string"

                    }, 

                    "speech_number": {

                        "type": "long"

                    }, 

                    "text_entry": {

                        "type": "string"

                    }

                }

            }, 

            "scene": {

                "properties": {

                    "line_id": {

                        "type": "long"

                    }, 

                    "line_number": {

                        "type": "string"

                    }, 

                    "play_name": {

                        "type": "string"

                    }, 

                    "speaker": {

                        "type": "string"

                    }, 

                    "speech_number": {

                        "type": "long"

                    }, 

                    "text_entry": {

                        "type": "string"

                    }

                }

            }

        }, 

        "settings": {

            "index": {

                "creation_date": "1429691321987", 

                "number_of_replicas": "1", 

                "number_of_shards": "5", 

                "uuid": "rrCmsKKcSDyLSpLFVnQnbg", 

                "version": {

                    "created": "1040299"

                }

            }

        }

    }

}


我们用熟悉的关系数据库来进行对比,映射关系如下

 elasticsearch RDBS

 indices 索引 databases数据库

 types 类型 tables表

 documents文档 rows行

 fields 字段 columns列

   


示例中,索引名为shakespeare(等同于数据库名为shakespeare)

类型有3个:act, line, scene (等同于表名为act, line, scene)

字段组成(等同于表的结构)

 字段名 字段类型

 line_id long

 line_number string

 play_name string

 speaker string

 speech_number long

 text_entry string

  

(2)简单检索 

示例1:通过index+type+文档_id来察看内容

格式:host:port/index_name/type_name/_id

http localhost:8108/shakespeare/line/2

结果如下:

{

    "_id": "2", 

    "_index": "shakespeare", 

    "_source": {

        "line_id": 3, 

        "line_number": "", 

        "play_name": "Henry IV", 

        "speaker": "", 

        "speech_number": "", 

        "text_entry": "Enter KING HENRY, LORD JOHN OF LANCASTER, the EARL of WESTMORELAND, SIR WALTER BLUNT, and others"

    }, 

    "_type": "line", 

    "_version": 1, 

    "found": true

}

elasticsearch的数据由两部分组成:文档元数据(例如_id)与文档数据

名字 说明

_index 类似RDBS的“数据库”概念

_type 类似RDBS的“表”概念

_id 文档的唯一编号

_source 字段里的内容为文档数据(真实存储的数据),我们可以使用如下方法只读取实际数据

http localhost:8108/shakespeare/line/2/_source

结果如下:


{

    "line_id": 3, 

    "line_number": "", 

    "play_name": "Henry IV", 

    "speaker": "", 

    "speech_number": "", 

    "text_entry": "Enter KING HENRY, LORD JOHN OF LANCASTER, the EARL of WESTMORELAND, SIR WALTER BLUNT, and others"

}



示例2:指定字段field进行搜索,例如搜索play_name字段为Romeo and Juliet

http localhost:8108/shakespeare/_search?q=play_name:"Romeo and Juliet"

结果如下(截取部分):

{

    "_shards": {

        "failed": 0, 

        "successful": 5, 

        "total": 5

    }, 

    "hits": {

        "hits": [

            {

                "_id": "86748", 

                "_index": "shakespeare", 

                "_score": 3.3792284, 

                "_source": {

                    "line_id": 86749, 

                    "line_number": "", 

                    "play_name": "Romeo and Juliet", 

                    "speaker": "JULIET", 

                    "speech_number": 19, 

                    "text_entry": "Exeunt"

                }, 

                "_type": "line"

            }, 


(3)复杂搜索

Elasticsearch支持丰富而灵活的查询语言——Query DSL。 在学习之前,我们可以先熟悉一下Lucene查询语法(其实和使用google搜索引擎区别不大)


支持AND,OR,NOT

查询语句"apache AND lucene"的意思是匹配含apache且含lucene的文档。

查询表达式"apache OR lucene"能够匹配包含“apache”的文档,也能匹配包含"lucene"的文档,还能匹配同时包含这两个Term的文档。

查询表达式“lucene NOT elasticsearch”就只能匹配包含lucene但是不含elasticsearch的文档


支持+, -符号

例如:希望搜索到包含关键词lucene,但是不含关键词elasticsearch的文档,可以用如下的查询表达式:"+lucene -elasticsearch"。


支持指定字段名进行搜索(类似RDBS按列名搜索)

例如:查询title域中包含关键词elasticsearch的文档,查询表达式如下:title:elasticsearch


支持通配符

 ? (匹配单个字符)

* (匹配多个字符)

注意默认的通配符不能是关键词的首字母


支持~整数符号

一个~符号,后面紧跟一个整数,~后面的整数表示短语中可接收的最大的词编辑距离(短语中替换一个词,添加一个词,删除一个词)

"writer~2"能够搜索到含writer和writers的文档。

title:"mastering elasticsearch"~2能够搜匹配title域中含"mastering elasticsearch"的文档与包含"mastering book elasticsearch"的文档


支持^符号进行加权boost设置

一个^符号后面接一个浮点数表示权重。如果权重小于1,就会降低关键词的重要程度。同理,如果权重大于1就会增加关键词的重要程度。默认的加权值为1


支持区间搜索

price:[10.00 TO 15.00查询price域的值在10.00到15.00之间的所有文档。

price:[10.00 TO 15.00}查询price域中价格在10.00(10.00要能够被搜索到)到15.00(15.00不能被搜索到)之间的文档


特殊字符需转义

+, -, &&, || , ! , (,) , { } , [ ] , ^, " , ~, *, ?, : , \, /


更多,Lucene原理 (打分算法,TF-IDF算法一定会在搜索中出境)



我们可以看到elasticsearch支持丰富的数据查询方式,结果展示方式(按什么方式来排序结果,使用什么图形来展示统计结果)

(1)关键词查询term

(2)短语查询phrase

(3)区间range

(4)布尔Boolean

(5)模糊fuzzy

(6)跨度span

(7)通配符wildcard

(8)地理位置spatial

(9) 统计aggregation ——这个功能非常非常赞,比如说生成各种统计图表

(10)prospective search



搜索语句支持通过URI提交(上面的例子演示的_search?q= 注意,使用这种方式的要遵循url编码,官方参考) ,也支持通过request body提交,简直就是HTTP RESTFULL最佳实践,官方参考


我们用熟悉的SQL语句来对比

实例1:

curl -XPOST 'http://localhost:8108/shakespeare/line/_search?pretty' -d '

{

"query":{ "match_all": {} },

"sort": {"line_id": {"order": "desc" }},

"size": 1,

"from": 10

}'

等同于

use shakespeare;

select * 

from line

order by line_id desc

limit 10,1

实例2:

curl -XPOST 'http://localhost:8108/shakespeare/line/_search?pretty' -d ' 

{

"query":{ 

"bool":{

"must":[

{"match_phrase": {"text_entry":"question"}},

{"match_phrase": {"text_entry":"not to be"}}

]

}

}

}'

结果


  "took" : 253,

  "timed_out" : false,

  "_shards" : {

    "total" : 3,

    "successful" : 3,

    "failed" : 0

  },

  "hits" : {

    "total" : 2,

    "max_score" : 4.0433946,

    "hits" : [ {

      "_index" : "shakespeare",

      "_type" : "line",

      "_id" : "34229",

      "_score" : 4.0433946,

      "_source":{"line_id":34230,"play_name":"Hamlet","speech_number":19,"line_number":"3.1.64","speaker":"HAMLET","text_entry":"To be, or not to be: that is the question:"}

    }, {

      "_index" : "shakespeare",

      "_type" : "line",

      "_id" : "1397",

      "_score" : 4.0004296,

      "_source":{"line_id":1398,"play_name":"Henry IV","speech_number":152,"line_number":"2.4.392","speaker":"FALSTAFF","text_entry":"blackberries? a question not to be asked. Shall"}

    } ]

  }

}

等同于

use shakespeare;

select * 

from line

where text_entry like "%question%" and text_entry like "%not to be%"

Search APIs

Match Query APIs


三、更多的细节


1. 主要配置详解

默认配置 含义

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

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

node.master: true 指定该节点是否有资格被选举成为master 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的,默认为192.168.0.1。

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传输时的数据,默认为true,压缩。

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

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

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

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 添加删除节点或负载均衡时并发恢复线程的个数,默认为2。

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 设置是否打开多播发现节点,默认是false。

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



查询时的慢日志


来自: http://danqingdani.blog.163.com/blog/static/1860941952015315104819711/