Elasticsearch 分享 --- 基础篇
【理论部分】
一、什么是Elasticsearch?
首先Elasticsearch是一个基于Lucene的搜索服务器,而Lucene是一个基于java开发的全文检索引擎的架构。
下面是官网对Elaticsearch的介绍:
Actionable Insight at Your Fingers
Distributed, scalable, and highly available
Real-time search and analytics capabilities
Sophisticated RESTful API
我们可以看到上面描述es的一些特性:具备分布式能力和相应功能,实时搜索和分析,支持现在流行的RESTful 架构风格。而分布式让他对大数据也能很好的支持,对RESTful 的支持让任何语言都可以访问。
所以我对它的理解是:
一个采用Restful API标准的高扩展性和高可用性的实时数据分析的全文搜索工具。
二、Elasticsearch的用途
上面也提到了,elasticsearch的主语是全文搜索工具,所以他就是干全文搜索用的。
下面是一些使用案例:
i) Github
“Github使用Elasticsearch搜索20TB的数据,包括13亿的文件和1300亿行的代码”
这个不用介绍了吧,码农们都懂的,Github在2013年1月升级了他们的代码搜索,由solr转为elasticsearch,目前集群规模为26个索引存储节点和8个客户端节点(负责处理搜索请求),详情请看官方博客https://github.com/blog/1381-a-whole-new-code-search
ii) Mozilla
Mozilla公司以火狐著名,它目前使用 WarOnOrange
这个项目来进行单元或功能测试,测试的结果以 json的方式索引到elasticsearch中,开发人员可以非常方便的查找
bug。
Socorro是Mozilla
公司的程序崩溃报告系统,一有错误信息就插入到 Hbase和Postgres 中,然后从
Hbase中读取数据索引到elasticsearch中,方便查找。
三、Elasticsearch 名词解释
i) 在数据层面主要有:
- Index:Elasticsearch用来存储数据的逻辑区域,它类似于关系型数据库中的db概念。一个index可以在一个或者多个shard上面,同时一个shard也可能会有多个replicas。(必须小写)
- Document:Elasticsearch里面存储的实体数据,类似于关系数据中一个table里面的一行数据。
- Document type:为了查询需要,一个index可能会有多种document,也就是document type,但需要注意,不同document里面同名的field一定要是相同类型的。相当于数据库里的一个表。 (区分大小写,且里面的field也区分大小写)
- Document id : 唯一,相当于数据库主键。
- Mapping:存储field的相关映射信息,不同document type会有不同的mapping。
ii) 在服务层面主要有:
- Node: 一个server实例。
- Cluster:多个node组成cluster。
- Shard:数据分片,一个index可能会存在于多个shards,不同shards可能在不同nodes。
- Replica:shard的备份,有一个primary shard,其余的叫做replica shards。
【实践部分】
四、Elasticsearch 的安装部署启动
一些基本的认识我们都有了,下面就开始实践了,由于es一般都是运行在linux里的,我们现在就在linux下部署一个elasticsearch服务(特别需要注意的,elasticsearch1.x 和 2.x 有非常大的区别,我下面讲的都是2.x的):
1、环境
elasticesearch依赖java环境,需要jre7以上。
2、下载
在官网下载tar.gz格式压缩包
3、解压安装
elasticesearch只需要解压就行,解压到相应目录
[boss@localhost ~]$ mkdir elasticesearch
[boss@localhost ~]$ cd elasticesearch/
[boss@localhost elasticesearch]$ tar xzf elasticsearch-2.3.5.tar.gz
4、启动
启动的时候最好添加jvm参数 ./elasticsearch -Xms512m -Xmx512m
[boss@localhost elasticesearch]$ cd bin/
[boss@localhost bin]$ ./elasticsearch
5、问题
测试环境是在公司虚拟机上,jdk 1.7.0_45,启动报错,需要升级jdk,貌似是jvm的bug。
在官网上看到这么一句话需要java 8 update 20 for later, or java 7 update 55 or later version.否则有bug.,甚至导致数据丢失。
至于windows下的安装部署启动在这就不介绍了,具体请看另外一篇《Elasticesearch在Windows的安装运行》
关于elasticsearch集群:只要在相同是host下,且配置文件中的cluster.name相同的节点,就会组成一个集群
五、Elasticsearch 目录、配置信息解释
i) 安装的目录布局如下:
Type |
Description |
Default Location |
Setting |
home |
elasticsearch 安装目录 | path.home | |
bin |
二进制脚本,包括elasticsearch启动节点 | {path.home}/bin | |
conf |
配置文件路径,包含elasticsearch.yml | {path.home}/config | path.conf |
data |
在节点上每个索引/碎片的数据文件的位置。可以有多个目录。 | {path.home}/data | path.data |
work |
零时文件目录(工作目录) | {path.home}/work | path.work |
logs |
日志文件目录 | {path.home}/logs | path.logs |
如果有多个数据目录,可以允许使用数据分拆技术,将数据能够按照设置放在不同的磁盘上。这个分拆原来是很简单的,只是保证一个文件完整的存在一个地方,具体是如果选择存在那个磁盘上是通过 index.store.distributor来配置的:
- least_used(默认):总是选择可用空间最大的目录。
- random:随机选择的目录。选择一个特定的目录的概率,是与这个目录中可用空间量成正比。
注意,在相同的数据上没有多个副本,在这一点上,它的类似 raid 0。 虽然简单,但是它应该提供一个好的解决方案,对于不想使用 raid的人 。
ii) 配置文件
Elasticsearch的配置文件在conf目录下,有两个.yml文件,一个是elasticsearch.yml,另一个是logging.yml。
其中elasticsearch.yml是对elasticsearch的配置;logging.yml是对elasticsearch日志的配置,也就是对log4j的配置。
我们这里讲elasticsearch.yml,文件中都比较详细的英文解释,所以我就说说比较重要的几个配置:
cluster.name: elasticsearch天然具备集群能力,所以这里就有一个集群名称配置,默认为elasticsearch,最好修改下。
node.name: 节点名称,也就是集群中的各个节点的名称,也需要配置,方便以后管理和java api开发
network.host: 允许访问的host,可以是ipv4也可以是ipv6形式,在es2.x下如果不配,那么就只能localhost访问了。
http.port: http端口号,用于restful、插件的访问端口,默认9200,不能重复
transport.tcp.port: 通讯端口,java api 访问的就是这个端口,默认9300,不能重复
discovery.zen.ping.unicast.hosts: 这个是集群启动的时候,默认发现的主机列表,然后通过这里的host再去发现别的节点,需要至少配置一个,不然好像有点问题,我在集群搭建的时候就因为没配置遇到一些意外情况。
discovery.zen.minimum_master_nodes: 最小的master选举人数,默认为2,这种形式计算(total number of nodes /2+1)
discovery.zen.ping.multicast.enabled: 自动发现节点开关,如果为false,则新加入的节点不会被发现。
discovery.zen.ping.timeout: 自动发现超时时间。
六、Elasticsearch插件安装
1、head插件:
对于Elasticsearch这种为分布式集群而生的,没有一个管理工具的话,会无从下手,所以我们需要安装一些插件来辅助,经典的插件是 head插件,marvel插件。其中marvel插件是对开发者免费,另外好像要收费,而且我没安装成功过... 所以我们使用head插件。
在杭州的同事可以访问 http://10.10.100.104:9200/_plugin/head/ 来查看, 界面如下:
alpha-application为集群名称
集群健康值:分为绿、黄、红。绿是表示正常;黄色表示部分异常,可以搜索,但是增删改备份什么的会有异常,数据会丢失;红色表示连搜索也不行了。
上面一个集群有两个节点,分别是node-alpha-0、node-alpha-1。其中node-alpha-0为master。
上面有5个index,每个index都有5个分片。
2、analysis-ik插件:
首先得介绍一个概念:在检索数据中,有一个概念 analysis,中文为 分词 。
比如一句话 I want to a be a bird。 如果不分词,那么每个字母都是搜索的关键词。这样就无法搜索了。es默认有分词,但是它对英文分词支持很好,对中文就很烂了。
比如 “我国是发展中国家”,es 对他的分词就是每个汉字,这当然不行,理想的分词是 我国、是、发展、发展中、国家。
因此我们需要 ik 插件,ik插件对中文分词有很好的支持。
安装步骤:
2、因为下载的是源代码,使用maven编译,方法是在cd 到解压目录下 mvn package 编译
3、步骤和解压
target/releases/elasticsearch-analysis-ik-{version}.zip
到 your-es-root/plugins/ik
4、重启elasticsearch。这点很重要,我就因为没有重启折腾了一上午。
3、analysis-ik-pinyin插件:
说完了中文分词插件,不可避免的需要拼音插件了,analysis-ik-pinyin这个插件是我找了很久觉得比较好的中文拼音插件。
安装插件需要将elasticsearch-analysis-lc-pinyin的源码自己maven build出来,这样可以避免版本冲突
现在网上没有找到有关2.X的插件安装和配置介绍,我摸索了很久才完成,这里记录下:
编译安装:
首先是build源码,使用将目录切到相应目录,我的是:
cd F:\software\elasticsearch-analysis-lc-pinyin-dev_2.2.2\elasticsearch-analysis-lc-pinyin
然后执行maven build命令(当然,前提是你安装了maven,并配置好环境变量)
mvn package
然后就等待他的编译,完成时会在..\elasticsearch-analysis-lc-pinyin\target\releases目录下生产一个zip,我们只需将这个zip解压到elasticsearch的plugin目录下即可。
配置使用:
lc 2.x是不需要在elasticsearch.yml里配置的,我们只需要重启elasticsearch实例即可。
关键就是在于使用上mapping和DSL的配置。
由于elasticsearch 1.x和2.x改动很大,所以我这里直接贴2.x的mapping配置了:
curl -XPUT http://localhost:9200/addr
curl -XPOST http://localhost:9200/addr/std/_mapping -d'
{
"std": {
"properties": {
"detail_name": {
"type": "string",
"analyzer": "lc_index",
"search_analyzer": "lc_search",
"fields": {
"cn": {
"type": "string",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
},
"door_name": {
"type": "string",
"analyzer": "lc_index",
"search_analyzer": "lc_search",
"fields": {
"cn": {
"type": "string",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
}
}
'
主要问题是在于,1.x是 index_analyzer 为 lc_index ,但是2.x 没有了index_analyzer 这个参数。
接下来就和1.x差不多了。
4、sql插件:
这个插件可以让不熟悉curl命令的人使用sql语句查询。
5、elasticsearch-jdbc插件:
这是一个数据库(mysql/oracle...)和elasticsearch同步的插件,并且支持实时同步(但是不同步物理删除的数据)。
下载安装相应版本即可。
不过它的同步是通过脚本实现的,linux为.sh,windows下为.bat。
需要说明的是,该插件提供了mysql的样例,oracle的没有提供,下面是我写的oracle的脚本,由于不是很熟悉linux命令,有些参数没有使用到。
#!/bin/sh # This example is a template to connect to Oracle # The JDBC URL and SQL must be replaced by working ones. DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" bin=${DIR}/../bin lib=${DIR}/../lib JAVA_HOME="/opt/java/jdk1.8.0_101" echo ' { "type" : "jdbc", "jdbc" : { "url" : "jdbc:oracle:thin:@//***.***.***.***:1521/***", "connection_properties" : { "oracle.jdbc.TcpNoDelay" : false, "useFetchSizeWithLongColumn" : false, "oracle.net.CONNECT_TIMEOUT" : 10000, "oracle.jdbc.ReadTimeout" : 50000 }, "user" : "pboss", "password" : "******", "sql" : "select std_addr_id as \"_id\",std_addr_id as \"std_addr_id\", name as \"door_name\", detail_name as \"detail_name\" from addr_std_addr", "index" : "addr", "type" : "std", "elasticsearch" : { "cluster" : "alpha-application", "host" : "10.10.100.104", "port" : 9300 }, "max_bulk_actions" : 20000, "max_concurrent_bulk_requests" : 10, "index_settings" : { "index" : { "number_of_shards" : 1, "number_of_replica" : 0 } } } } ' | ${JAVA_HOME}/bin/java \ -cp "${lib}/*" \ -Dlog4j.configurationFile=${bin}/log4j2.xml \ org.xbib.tools.Runner \ org.xbib.tools.JDBCImporter
上面的url即 jdbc驱动的url,user 和password 是相应数据库的登录名密码。
上面的脚本是一次性同步,实时同步需要加如一些参数。
"interval": "1800", 这里是同步数据的频率 1800s,半小时,可以按需要设成 1s或其它 "schedule" : "0 0/60 0-23 ? * *", 同步数据任务 60分钟一次 "flush_interval" : "5s", 刷新间隔为5S
具体关于这个插件的使用,请看《elasticsearch-jdbc 插件说明》