两年前有机会接触过elasticsearch,可是未作深刻学习,只是工做中用到了。愈来愈发现es是个不错的好东西,因此花了点时间好好学习了下。在学习过程当中也发现了一些问题,网上大多资料都很零散,大部分都是实验性的demo,不少问题并无讲清楚也并无系统的讲完整一整套方案,因此耐心的摸索和总结了一些东西分享出来。html
毕竟当你用生产使用的标准来使用es时会有不少问题,这对你的学习提出来了新的标准。java
好比,使用elasticsearch servicewrapper进行自启动的时候难道就没发现它的配置中有一个小bug致使load不了elasticsearch jar包中的class吗。node
还有es不一样版本之间的差别巨大,好比,1.0中的分布式routing在2.0中进行了巨大差别的修改。本来routing是跟着mapping一块儿配置的,到了2.0却跟着index动态走了。这个调整的本质目的是好的,让同一个index的不一样type都有机会选择shard的片键。若是是跟着mapping走的话就只能限定于当前index的全部type。linux
es是个好东西,如今愈来愈多的分布式系统都须要用到它来解决问题。从ELK这种系统层的工具到电商平台的核心业务交易系统的设计都须要它来支撑实时大数据搜索分析。好比,商品中心的上千万的sku须要实时搜索,再到海量的在线订单实时查询都须要用到搜索。git
在一些DevOps的工具中都须要es来提供强大的实时搜索功能。值得花点时间好好研究学习下。github
做为电商架构师,因此没有什么理由不去学习和使用它来提升系统的总体服务水平。本篇文章将本身这段时间学习的经验总结出来分享给你们。算法
首先你须要几台linux机器,你跑虚机也行。你能够在一台虚拟机上完成安装和配置,而后将当前虚拟机clone出多份修改下IP、HWaddr、UUID即用,这样方便你使用,而不须要再重复的安装配置。chrome
1.我本地是三台Linux centos6.5,IP分别是,192.168.0.十、192.168.0.20、192.168.0.30。shell
(咱们先在192.168.0.10上执行安装配置,而后一切就绪以后咱们将这个节点clone出来修改配置,而后再配置集群参数,最后造成能够工做的以三个node组成的集群实例。)json
2.因为ElasticSearch是java语言开发的,因此咱们须要预先安装好java相关环境。我使用的是JDK8,直接使用yum安装便可,yum仓库有最新的源。
先查看你当前机器是否安装了java环境:
yum info installed |grep java*
若是已经存在java环境且这个环境不是你想要的,你能够卸载而后从新安装你想要的版本。(yum –y remove xxx)若是卸载不干净,你能够直接find 查找相关文件,而后直接物理删除。linux的系统都是基于文件的,只要能找到基本上均可以删除。
先看下有哪些版本:
yum search java
java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment(找到这个源)
而后执行安装:
yum –y install java-1.8.0-openjdk.x86_64
安装好以后查看java 相关参数:
java –version
预备工做咱们已经作好,接下来咱们将执行ElasticSearch的环境安装和配置。
你能够有几种方式安装。使用yum repository是最快最便捷的,可是通常这里面的版本应该是比较滞后的。因此我是直接到官网下载rpm包安装的。
elasticsearch官方下载地址:https://www.elastic.co/downloads/elasticsearch
找到你对应的系统类型文件,固然若是你是windows系统那就直接下载zip包使用就好了。这里我须要rpm文件。
你也能够安装本地yum 源,而后仍是使用yum命令安装。
我是使用wget 工具直接下载RPM文件到本地的。(若是你的包有依赖建议仍是yum方式安装。)
(若是你的wget命令不起做用,记得先安装:yum -y install wget)
而后等待下载完成。
这里有个东西须要提醒下,就是你是否要安装最新版本的elasticsearch,我的建议仍是安装稍微低一个版本的,我本地安装的是2.3.4的版本。为何要这样强调尼,由于当你安装了很高的版本以后有一个很大的问题就是中文分词器可否支持到这个版本。从2.3.5以后就直接到2.4.0的版本了,我当时安装的是2.3.5的版本后来发现一个问题就是ik中文分词器我得git clone下来编译后才能有输出部署文件。因此建议你们安装2.3.4的版本,2.3.4的版本中文分词器就能够直接在linux服务器里下载部署,很方便。
执行安装:
rpm -iv elasticsearch-2.3.4.rpm
而后等待安装完成。
不出什么意外,安装就应该完成了。咱们进行下基本的安装信息查看,是否安装以后缺乏什么文件。由于有些包里面会缺乏一些config配置。若是缺乏咱们还得补充完整。
为了方便查看安装涉及到的文件,你能够导航到根目录下 find。
cd /
find . –name elasticsearch
./var/lib/elasticsearch
./var/log/elasticsearch
./var/run/elasticsearch
./etc/rc.d/init.d/elasticsearch
./etc/sysconfig/elasticsearch
./etc/elasticsearch
./usr/share/elasticsearch
./usr/share/elasticsearch/bin/elasticsearch
基本上差很少了,你还得看下是否缺乏config,由于我安装的时候是缺乏的。
cd /usr/share/elasticsearch/
ll
drwxr-xr-x. 2 root root 4096 9月 4 01:10 bin
drwxr-xr-x. 2 root root 4096 9月 4 01:10 lib
-rw-r--r--. 1 root root 11358 6月 30 19:22 LICENSE.txt
drwxr-xr-x. 5 root root 4096 9月 4 01:10 modules
-rw-r--r--. 1 root root 150 6月 30 19:22 NOTICE.txt
drwxr-xr-x. 2 elasticsearch elasticsearch 4096 6月 30 19:32 plugins
-rw-r--r--. 1 root root 8700 6月 30 19:22 README.textile
大概看下你应该也是缺乏config文件夹的。咱们还得把这个文件夹建好,同时还须要一个elasticsearch.yml配置文件。要否则启动的时候确定是报错的。
mkdir config
cd config
vim elasticsearch.yml
找一下elasticsearch.yml配置贴上去,或者你用文件的方式传送也行。这些配置都是基本的,回头还须要根据状况调整配置的。有些配置在配置文件中是没有的,还须要到官方上去查找的。因此这里无所谓配置文件的全或者不全。关于配置项网上有不少资料,因此这个无所谓的。
保存下elasticsearch.yml文件。
你还须要一个logging.yml日志配置文件。es做为服务器后台运行的服务是确定须要日志文件的。这部分日志会被你的日志平台收集和监控,用来作为运维健康检查。logging.yml本质上是一个log4j的配置文件,这个应该你们都比较熟悉了。跟elasticsearch.yml相似,要么复制粘贴要么文件传送。
日志的输出在logs目录下,这个目录会被自动建立。可是我仍是喜欢建立好,不喜欢有不肯定因素,也许它就不会自动建立。
mkdir logs
最后须要设置下刚才咱们添加的文件的执行权限。要否则你的文件名字应该是白色的,是不容许被执行。
cd ..
chmod –R u+x config/
如今基本上安装算是完成了,试着cd到文件的启动目录下启动es,来检查下是否能正常启动。
不出意外你会收到一个 “java.lang.RuntimeException: don't run elasticsearch as root”异常。这说明咱们完成了第一步安装过程,下节咱们来看有关启动帐户的问题。
默认状况下es是不容许root帐户启动的,这是为了安全起见。es默认内嵌了groovy脚本引擎的功能,还有不少plugin脚本引擎插件,确实不太安全。es刚出来的时候还有groovy漏洞,因此建议在产线的es instance 关掉这个脚本功能。虽然默认不是开启的,安全起见仍是检查一下你的配置。
因此咱们须要为es配置独立的帐户和组。在建立es专用帐户以前先查看下系统里面是否已经有了es专用帐户。由于在咱们前面rpm安装的时候会自动安装elasticsearch组和用户。先查看下,若是你的安装没有带上专用组和用户而后你在建立。这样以避免你本身增长的和系统建立的搞混淆。
查看下组:
cat /etc/group
查看下用户:
cat /etc/passwd
基本上都建立好了。499的group在passwd中也建立了对应的elasticsearch帐号。
若是你系统里没有自动建立对应的组和帐号,你就动手本身建立,以下:
建立组:
groupadd elasticsearch_group
建立用户:
useradd elasticsearch_user -g elasticsearch_group -s /sbin/nologin
注意:此帐户是不具备登陆权限的。它的shell是在/sbin/nologin。
为了演示,在个人电脑上有两组elasticsearch专用帐户,我将删除“_group”和“_user”结尾的帐号,以rpm自动安装的为es的启动帐号(elasticsearch)。
接下来咱们须要作的就是关联es文件和elasticsearch帐号,将es相关的文件设置成elasticsearch用户为全部者,这样elasticsearch用户就能够没有任何权限限制的使用es全部文件。
导航到elasticsearch上级目录:
cd /usr/share
ll
chown -R elasticsearch:elasticsearch elasticsearch/
此时,你的elasticsearch文件的owner是elasticsearch。
为了测试启动es实例,咱们须要暂时的将elasticsearch的用户切换到/bin/bash。这样咱们就能够su elasticsearch,而后启动es实例。
su elasticsearch
cd /usr/share/elasticsearch/bin
./elasticsearch
启动完成,此时应该没发生任何异常。看下系统端口是否启动成功。
netstat –tnl
继续查看下HTTP服务是否启动正常。
curl –get http://192.168.0.103:9200/_cat
因为此时咱们并无安装任何辅助管理工具,如,plugin/head。因此用内置的_cat rest endpoit仍是挺方便的。
curl -get http://192.168.0.103:9200/_cat/nodes
192.168.0.103 192.168.0.103 4 64 0.00 d * node-1
能够看见,目前只有一个节点在工做,192.168.0.103,且它是一个data node。
(备注:为了节省时间,我暂时先使用一台103的干净环境做为安装和环境搭建演示,当搭建集群的时候我会clone出来和修改IP。)
es的系统自启动有一个开源的wrapper包可使用。若是你不使用这个wrapper也能够本身去写shell脚本,可是里面的不少参数须要你搞的很是清楚才行,在加上有些关键参数须要设置。因此仍是建议在elasticsearchwrapper包的基础上进行修改效率会高点,并且你还能在elasticsearch shell中看见一些es深层次的配置和原理。
(备注:若是你是.neter,你能够将servicewrapper理解成是开源.net topshelf。本质就是将程序包装成具备系统服务功能,你能够安装、卸载,也能够直接启动、中止,或者干脆直接前台运行。)
elasticsearchwrapper github首页,https://github.com/elastic/elasticsearch-servicewrapper
复制 git repository 地址到剪贴板,而后直接clone到本地。
git clone https://github.com/elastic/elasticsearch-servicewrapper.git
(你须要在当前linux机器上安装git客户端:yum –y install git,我安装的是默认1.7的版本。)
而后等待clone完成。
查看下clone下来的本地仓库文件状况。进入elasticsearchwrapper,查看当前git 分支。
cd /root/elasticsearch-servicewrapper
git branch
*master
ll
一切都很正常,说明咱们clone下来没问题,包括分支也是很清晰的。service文件就是咱们要安装的安装文件。
咱们须要将service文件copy到elasticsearch/bin目录下。
cp -R service/ /usr/share/elasticsearch/bin/
cd /usr/share/elasticsearch/bin/
service里的安装文件须要在elasticsearch/bin目录下工做。
cd service/
ll
./elasticsearch
参考github上elasticsearchwrapper使用说明。elasticsearch servicewrapper的功能仍是蛮多的,status、dump都是很好的检查和调试工具。
在安装以前,咱们须要暂时在前台运行es实例,这样能够查看一些log是否有异常状况。Parameter的各个参数写的很清楚,咱们这里使用console控制台输出启动es实例。
./elasticsearch console
此时你应该会收到一个Error的提示:
WrapperSimpleApp Error: Unable to locate the class org.elasticsearch.bootstrap.ElasticsearchF : java.lang.ClassNotFoundException: org.elasticsearch.bootstrap.ElasticsearchF
第一次看到这个我有点蒙,这个ElasticsearchF是个什么对象。命名有点特殊,再进一步查看Exception的信息,实际上是一个ClassNotFoundException异常。说明找不到这个ElasticSearchF类。
两种可能性,第一就是java elasticsearch相关包的问题,确实缺乏这个类。可是这个可能性很小,由于咱们以前直接运行elasticsearch是成功的。我当时用jd-gui翻了下es的包,确实没有这个类。
第二就是这里的配置错误,应该就个手误,确实没有ElasticsearchF这个类。
咱们查看下service/elasticsearch.conf配置文件里是否是有这个‘elasticsearchF’字符串。(wrapper包是使用当前目录下的elasticsearch.conf做为配置文件使用的)
grep –i elasticsearchf elasticsearch.conf
确实有这个字符串,咱们进行编辑保存,去掉最后的‘F’。
而后咱们在进行启动尝试。
./elasticsearch console
我不知道你是否是会和个人状况同样,提示相关命令都是不规范的。
这个运行链路基本上通过三个路径,第一个就是service/elasticsearch shell启动脚本,而后获取命令分析命令再启动exec下的相关java servicewrapper程序。
这个java servicewrapper程序,版本是3.5.14。根据上述思路,经过查看elasticsearch shell程序,它在接收到外部的命令以后会启动exec下的java servicewrapper程序。我想试着编辑了下elasticsearch shell文件,输出一些信息出来,查看下是否是获取相关路径或者参数之类的致使错误。(遇到问题不怕,至少咱们要一路跟下去,看下到底是怎么回事。)
vim ./elasticsearch
esc
:/console
找下console在哪里,而后加上调试文本信息,输出到界面上。
再运行,查看命令参数是否有问题。
查看了下,输出的参数基本都没有问题。一时无解。好奇心做怪,本想再进一步看下exec/elasticsearch-linux-x86-64.so文件的,后来发现打开根本就看不懂。因此就另寻其余方法,我找了windows版本servicewrapper,发现windows的elasticsearchservicewrapper是没有32位的servicewrapper的。我试着运行起来基本上也是报相同的错误,可是windows的wrapper的error信息比较多点,提示出错的缘由在哪里。
我想修改下日志的输出级别,看可否输出一些能够用的信息。编辑service/elasticsearch.conf wrapper包专用配置。
# Log Level for console output. (See docs for log levels)
wrapper.console.loglevel=TRACE
# Log Level for console output. (See docs for log levels)
wrapper.console.loglevel=TRACE
咱们将日志输出级别设置成trace,有两处须要设置,咱们再看输出信息。
是输出了一些有用的信息,能够查看log文件详情。
WrapperManager Debug: Received a packet LOGFILE : /usr/share/elasticsearch/logs/service.log
可是有关于error的信息仍是只有一条。
这里就告一段落。咱们的目的是为了使用console来运行,想查看下一些运行日志,可是跑不起来也无所谓,咱们继续执行安装操做。
(哪位博友若是知道问题在哪里的能够分享出来,我以为这个问题不是一个偶发性问题,应该都会遇到。我先抛出问题,至少能够服务未来的使用者。这里先谢谢了。)
其实,若是你不使用elasticsearch servicewrapper来包装而是本身去下载java serivcewrapper来包装elasticsearch也是能够的,实现起来也很方便。
咱们回到主题,既然咱们没法console运行,也看不了一些wrapper console执行时的状况,那咱们就只能进行安装了。
按照elasticsearch servicewrapper parameter参数指示,咱们执行安装。
./elasticsearch install
Installing the Elasticsearch daemon..
守护进程安装完成。咱们仍是前去系统目录下查看是否是安装成功(技术人员始终保持一个严谨的心态是有必要的。)前往/etc/init.d/目录下查看。
ll /etc/init.d/
-rwxrwxr--. 1 root root 4496 10月 4 01:43 elasticsearch
我这里设置过chmod u+x ./elasticsearch。别忘记设置文件的执行权限,这在咱们【2.1节】里将结果,这里就不重复了。
咱们开始编辑elasticsearch启动文件。
主要就是这段,填写好配置的es的专用帐户(elasticsearch【2.2.节】),还有相应的文件路径。这里先忽略MAX_OPEN_FILES、MAX_MAP_COUNT两个配置项,在后面【3.3.节】配置部分会讲解到。
将其添加到系统服务中,以便被系统自动启动。
chkconfig --add elasticsearch
chkconfig –list
已经添加好系统自启动服务列表中。
service elasticsearch start
启动es实例,等待端口启动完成,稍等片刻查看端口状况。
netstat –tnl
9300端口比9200端口先启动,由于9300端口是 cluster内部管理端口。9200是rest endpoint 服务端口。固然,这个时间延长不会很长。
端口都启动成功以后,咱们查看下可否正常访问es实例。
curl -get http://192.168.0.103:9200/
{
"name" : "node-1",
"cluster_name" : "orderSearch_cluster",
"version" : {
"number" : "2.3.4",
"build_hash" : "e455fd0c13dceca8dbbdbb1665d068ae55dabe3f",
"build_timestamp" : "2016-06-30T11:24:31Z",
"build_snapshot" : false,
"lucene_version" : "5.5.0"
},
"tagline" : "You Know, for Search"
}
咱们仍是使用_cat rest endpoint来查看。
curl -get http://192.168.0.103:9200/_cat/nodes
192.168.0.103 192.168.0.103 4 61 0.00 d * node-1
若是你能够在本机访问,可是在外部浏览器中没法访问,极可能是防火墙的设置问题,你能够去设置下防火墙。
vim /etc/sysconfig/iptables
重启网络服务,以便加载防火墙设置项。
service network restart
而后再尝试看可否外部访问,若是不行你就telnet端口下。
由于访问不了还有一个缘由是和elasticsearch.yml一个配置项有关系。见【3.1.1节】。
重启机器,查看es实例是否会自动启动。
shutdown –r now
稍等片刻,而后尝试链接机器。
若是没出什么意外,都应该正常的,端口也启动成功了。说明咱们完成了es实例自启动功能,它如今做为linux系统服务被自动管理。
安装成服务以后,elasticsearch servicewrapper和咱们就没有太多关系了。由于它的parameter都是围绕者咱们基于servicewrapper来使用的。
为了很好的管理集群,咱们须要相应的工具,head是比较流行和通用的,并且是免费的。固然还有不少好用的其余工具,如,Bigdesk、Marvel(商用收费)。plugin的安装都大同小异,咱们这里就使用通用的head工具。
先看下,head给咱们带来的清晰的集群节点管理视图。
这是有三个节点的es集群实例。它是一个二维矩阵排列,最上面横向是索引,最左边是节点,交叉的地方是索引的分片信息和分片比例。
安装head插件仍是比较方便的,你也能够直接copy文件的方式使用。在elasticsearch的home目录下有一个plugins目录,它是全部插件的目录,全部的插件都会在这个文件夹查找和加载。
咱们看下安装head插件方法。在elasticsearch/bin 目录下有一个plugin可执行文件,它是专门用来安装插件用的程序。
./plugin -install mobz/elasticsearch-head
插件的查找路径有几个elasticsearch官网是一个,github是一个。这里会先尝试在github上查找,稍等片刻,等待安装完成。咱们尝试访问head插件地址rest地址/_plugin/head。
看到这个界面基本安装成功了,node-1默认是master节点。
chrom中有不少可使用的elasticsearch客户端插件,便于开发和维护,建议直接使用chrom中的插件。只要搜索下elasticsearch关键字就会出来不少。
有两个比较经常使用,也比较好用,EalsticSearch Toolbox、Sense(自动提示dsl编辑工具)。chrom插件都是那么的酷,使用起来都很赏心悦目。
elasticsearch toolbox 能够很方便的查询和导出数据。
sense可让你编辑elasticsearch dsl 特定语言会有启动提示帮助,这样编写起复杂的dsl效率会高并且不易出错。其余的工具我也没用过,感受均可以尝试用用看。
(备注:若是你没法访问chrom商店中心就须要特殊处理下,这里就不解释了。)
在一些特殊的状况下你可能没法直接使用plugin来帮你管理或者查看集群状况。此时你能够直接使用elasticsearch自带的rest _cat查看集群状况,好比,你可能发现_plugin/head有一些节点没有上来,可是你又不肯定发生了什么状况,你就可使用/_cat/nodes来查看全部node的状况。有时候确实有的节点没有启动起来,可是大多数状况下都是各自为政(脑裂),你可能须要让他们从新选举或者加快的选举过程。
http://192.168.0.20:9200/_cat/nodes?v (查看nodes状况)
_cat rest端点带有一个v的参数,这个参数是帮助你阅读的参数。_search rest端点带有pretty参数,这个参数是帮助查询数据阅读的。每个端点基本上都有各自的辅助阅读参数。
http://192.168.0.20:9200/_cat/shards?v(查看shards状况)
http://192.168.0.20:9200/_cat/ (查看全部能够cat的功能)
你能够查看系统 aliases别名、segments片断(看下每一个片断的提交版本一致性)、indices索引集合等等。
当咱们完成了对一台机器的安装以后,接下来就须要搭建分布式系统。分布式系统就须要多节点机器,按照es分布式集群搭建最佳实践,你至少须要三个节点。因此咱们将已经安装完成的这个机器clone出来两台,一共三台组成能够工做的三个节点的分布式系统。
首先clone当前安装完成的机器,192.168.0.103,clone好以后启动起来修改几个配置便可。(由于你是clone出来的,因此配置已经重复,好比,网卡地址、IP地址)
编辑网卡配置文件:
vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth3
HWADDR=00:0C:29:CF:48:23
TYPE=Ethernet
UUID=b848e750-d491-4c9d-b2ca-c853f21bf40b
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
BROADCAST=192.168.233.255
IPADDR=192.168.0.103
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DEVICE 是网卡标示,根据你本地的网卡标识修改为对应的便可,能够经过ifconfig查看。HWADDR网卡地址,随意修改下,保证在你的网段内不重复便可。UUID也是和HWADDR同样修改。
IP地址修改为你本身以为合适的IP,最好参考你当前物理机器的相关配置。GATEWAY网关地址要参考你物理机器的网关地址,若是你的虚拟机使用的是桥接模式的网络链接,这里就须要设置,要否则网络就链接不上。
重启网络服务:
service network restart
稍等片刻,ssh从新链接,而后ifconfig看下网络相关参数是否正确,最后再ping一下外部网址和你当前物理机器的IP,保证网络都是通畅的。
最后咱们须要修改下linux的系统时间,这是为了防止服务器时间不一致,致使不少细微的问题,好比,es集群master选举的时间戳问题、log4j输出的日志的记录问题等等。在分布式系统中,时钟很是重要。
date -s '20161008 20:47:00'
时区的话若是你须要也能够设置,这里暂时不须要。
根据你本身的须要,你clone几台机器。按照默认的方式咱们大概约定为,192.168.0.十、192.168.0.20、192.168.0.30,这三台机器将组成一个es分布式集群。
集群的各个节点咱们已经准备好了,咱们接下来准备配置集群,让这三个节点能够链接在一块儿。这里涉及的配置比较简单,只是完成集群的一个基本经常使用功能,若有特殊的需求能够自行查看elasticsearch官网或者百度,这方面的资料已经很丰富了。
这里的一些配置咱们其实已经受益于elasticsearch servicewrapper简化了不少。
从这里开始,咱们将对三台机器进行配置,192.168.160.十、192.168.160.20、192.168.160.30。
在elasticsearch的config目录下都是配置文件。导航到 cd /usr/share/elasticsearch/config目录。
这里有两个须要提醒下,第一个就是IP访问限制,第二个就是es实例的默认端口号9200。IP访问限制能够限定具体的IP访问服务器,这有必定的安全过滤做用。
# Set the bind address to a specific IP (IPv4 or IPv6):
#
network.host: 0.0.0.0
若是设置成0.0.0.0则是不限制任何IP访问。通常在生产的服务器可能会限定几台IP,一般用于管理使用。
默认的端口9200在通常状况下也有点风险,能够将默认的端口修改为另一个,这还有一个缘由就是怕开发人员误操做,链接上集群。固然,若是你的公司网络隔离作的很好也无所谓。
#
# Set a custom port for HTTP:
#
http.port: 9200
transport.tcp.port: 9300
这里的9300是集群内部通信使用的端口,这个也能够修改掉。由于链接集群的方式有两种,经过扮演集群node也是能够进入集群的,因此仍是安全起见,修改掉默认的端口。
(备注:记得修改三个节点的相同配置,要否则节点之间没法创建链接工做,也会报错。)
紧接着修改集群节点IP地址,这样可让集群在规定的几个节点之间工做。elasticsearch,默认是使用自动发现IP机制。就是在当前网段内,只要能被自动感知到的IP就能自动加入到集群中。这有好处也有坏处。好处就是自动化了,当你的es集群须要云化的时候就会很是方便。可是也会带来一些不稳定的状况,如,master的选举问题、数据复制问题。
致使master选举的因素之一就是集群有节点进入。当数据复制发生的时候也会影响集群,由于要作数据平衡复制和冗余。这里面能够独立master集群,剔除master集群的数据节点能力。
固定列表的IP发现有两种配置方式,一种是互相依赖发现,一种是全量发现。各有优点吧,我是使用的依赖发现来作的。这有个很重要的参考标准,就是你的集群扩展速度有多快。由于这有个问题就是,当全量发现的时候,若是是初始化集群会有很大的问题,就是master全局会很长,而后节点之间的启动速度各不同。因此我采用了靠谱点的依赖发现。
你须要在192.168.0.20的elasticsearch中配置成:
# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when new node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#
discovery.zen.ping.unicast.hosts: [ "192.168.0.10:9300" ]
让他去发现10的机器,以此内推,完成剩下的30的配置。
(备注:网上有不少针对不一样场景的发现配置,你们能够就此抛砖引玉,对这个主题感兴趣的能够百度不少资料的。)
而后你须要配置下集群名称,就是你当前节点所在集群的名称,这有助于你规划你的集群。只有集群名称同样才能组成一个逻辑集群。
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
#
cluster.name: orderSearch_cluster
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: node-2
以此类推,完成另外两个节点的配置。cluster.name的名称必须保持同样。而后分别设置node.name。
这里有一个小小的经验分享下,就是我在使用集群的时候,由于我是虚拟化出来的机器因此常常会关闭和重启集群。有时候发现集群master宣酒会有一个问题就是,若是你的集群关闭的方式不对,会直接影响下个master选举的逻辑。
我查了下选举的大概逻辑,它会根据分片的数据的先后新鲜程度来做为选举的一个重要逻辑。(日志、数据、时间都会做为集群master全局的重要指标)
由于考虑到数据一致性问题,固然是用最新的数据节点做为master,而后进行新数据的复制和刷新其余node。
若是你发现有一个节点迟迟进不了集群,能够尝试重启下es服务,让集群master从新全局。
在linux系统中,要想使用最大化的系统资源须要向操做系统去申请。因为elasticsearch须要在index的时候用到大量的文件句柄资源,在原来linux默认的资源下可能会不够用。因此这里就须要咱们在使用的时候事先设置好。
这个配置在《ElasticSearch 可扩展的开源弹性搜索解决方案》一书中做为重点配置介绍,可想而知仍是有很多人踩到过的坑。
这个配置在elasticsearch service wrapper中帮咱们配置好了。
vim /etc/init.d/elasticsearch
这个配置会被启动的时候设置到es实例中去。
这个时候试着重启三台机器的es实例,看能不能在_plugin/head中查看到三台机器的集群状态。(记得访问安装了head插件的那台机器,我这里是在10机器上安装的)
红色的就是你设置的node.name节点名称,他们在一个集群里工做。
此时集群应该能够工做了,咱们还须要配置中文分词器,毕竟咱们使用的中文,elasticsearch的自带的分词器对中文分词支持的不太适合本土。
我是使用的ik分词器,在github上的地址:https://github.com/medcl/elasticsearch-analysis-ik
先别急的clone,咱们先来看下ik分词器所支持的elasticsearch对应的版本。
咱们使用的elasticsearch版本为2.3.4。因此咱们要找对应的ik版本,要否则启动的时候就直接报加载不了对应版本的ik插件。切换到release版本列表,找到对应的版本而后下载下来。
你能够直接下载到Linux机器上,也能够下载到你的宿主机器上而后复制到虚拟机上。若是你的elasticsearch版本是最新的,你可能就须要下载ik源码下来编译以后再部署。
固然你可使用git+maven的方式安装,详细的安装步骤能够参见:https://github.com/medcl/elasticsearch-analysis-ik
这也比较简单,我这里就不重复了。安装好以后重启es实例。
能够这样规划一个集群。master能够两台,这两个节点都是做为commander统筹集群层面的事务,取消这两台的data权利。而后在规划出三个节点的data集群,取消这三个节点的master权利。让他们安心的作好数据存储和检索服务。这是最小的粒度集群结构,能够基于这个结构进行扩展。
这样作有一个好处,就是职责分明,能够最大限度的防止master节点有事data节点,致使不稳定因素发生。好比,data节点的数据复制,数据平衡,路由等等,直接影响master的稳定性。进而可能会发生脑裂问题。
咱们进入最后一个环节,全部的东西都准备好了,咱们是否是应该操做操做这个强大的搜索引擎了。come on。
说到集群,就会有相应的问题随之而来,高可用、高并发、大数据、横向扩展等等。那么elasticsearh的集群大概是个什么原理。
首先client的在接入集群的时候为了保证高可用不是采用 vip漂移实现高可用,相似keepalived 这种。elasticserach在客户端链接的时候使用配置多个IP的方式来首先客户端sdk的负载。这已是分布式系统常见的作法了。只有相似DB、cache这样中心化的集群须要使用,觉得是它们的使用特色决定了。(数据一致性)
elasticsearch的全部节点均可以处理请求,节点越多并发QPS越高,相应的TPS会降低,可是降低的性能不是根据节点的正比例来的。(它使用quorum(法定人数)算法,保证可用性。)因此节点的复制不是咱们想固然的那样。
链接es集群的方式有两种,性能高点的就是直接将client扮演成cluster node进去集群,同时取消本身的data权利。这一般都是用来作二次开发用的,你能够github clone下来源码添加本身的场景而后进入集群,可能你会干预选举,也可能会干预sharding,也可能会干预集群平衡。
elasticsearch 使用本身定义的一套DSL语言,使用restful方式使用,根据不一样的rest end point来使用。好比,_search、_cat、_query等等。这些都是指点的rest端点。而后你能够post dsl到elasticsearch服务器处理。
elasticsearch search dsl:https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html
elasticsearch dsl api:http://elasticsearch-dsl.readthedocs.io/en/latest/
例:
POST _search
{
"query": {
"bool" : {
"must" : {
"query_string" : {
"query" : "query some test"
}
},
"filter" : {
"term" : { "user" : "plen" }
}
}
}
}
可读性很强,在经过chrome插件Sense辅助编写,会比较方便。
可是通常都不会这么作,通常都是使用sdk链接集群。直接使用dsl的大可能是在测试数据的时候或者在调试的时候。看sdk输出的dsl是否正确。就跟调试SQL差很少。
.NET程序有开源包nest,直接在Nuget上搜索安装便可。
官网地址:https://www.elastic.co/guide/en/elasticsearch/client/net-api/1.x/nest-connecting.html
使用pool高可用的方式链接集群。
var node1 = new Uri("http://192.168.0.10:9200");
var node2 = new Uri("http://192.168.0.20:9200");
var node3 = new Uri("http://192.168.0.30:9200");
var connectionPool = new SniffingConnectionPool(new[] { node1, node2, node3 });
var settings = new ConnectionSettings(connectionPool);
var client = new ElasticClient(settings);
此时使用client对象就是软负载的,它会根据必定的策略来均衡的链接后台三个node。(多是平均的、多是权重的,具体没研究)
java 的话我是使用jest。咱们建立一个maven项目,而后添加jest 相应的jar包maven引用。
<dependencies>
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.3.5</version>
</dependency>
</dependencies>
JestClientFactory factory = new JestClientFactory();
List<String> nodes = new LinkedList<String>();
nodes.add("http://192.168.0.10:9200");
nodes.add("http://192.168.0.20:9200");
nodes.add("http://192.168.0.30:9200");
HttpClientConfig config = new HttpClientConfig.Builder(nodes).multiThreaded(true).build();
factory.setHttpClientConfig(config);
JestHttpClient client = (JestHttpClient) factory.getObject();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.queryStringQuery("中华人名共和国"));
searchSourceBuilder.field("name");
Search search = new Search.Builder(searchSourceBuilder.toString()).build();
JestResult rs = client.execute(search);
System.out.println(rs.getJsonString());
{
"took": 71,
"timed_out": false,
"_shards": {
"total": 45,
"successful": 45,
"failed": 0
},
"hits": {
"total": 6,
"max_score": 0.6614378,
"hits": [
{
"_index": "posts",
"_type": "post",
"_id": "1",
"_score": 0.6614378,
"fields": {
"name": [
"王清培"
]
}
},
{
"_index": "posts",
"_type": "post",
"_id": "5",
"_score": 0.57875806,
"fields": {
"name": [
"王清培"
]
}
},
{
"_index": "posts",
"_type": "post",
"_id": "2",
"_score": 0.57875806,
"fields": {
"name": [
"王清培"
]
}
},
{
"_index": "posts",
"_type": "post",
"_id": "AVaKENIckgl39nrAi9V5",
"_score": 0.57875806,
"fields": {
"name": [
"王清培"
]
}
},
{
"_index": "class",
"_type": "student",
"_id": "1",
"_score": 0.17759356
},
{
"_index": "posts",
"_type": "post",
"_id": "3",
"_score": 0.17759356,
"fields": {
"name": [
"王清培"
]
}
}
]
}
}
返回的数据横跨多个索引。你能够经过不断的debug来查看连接IP是否是会启动切换,是否是会起到可用性的做用。
索引开发通常步骤比较简单,首先创建对应的mapping映射,配置好各个type中的field的特性。
mapping是es实例用来在index的时候,做为各个字段的操做依据。好比,username,这个字段是否要索引、是否要存储、长度大小等等。虽然elasticsearch能够动态的处理这些,可是出于管理和运维的目的仍是建议创建对应的索引映射,这个映射能够保存在文件里,以便未来重建索引用。
POST /demoindex
{
"mappings": {
"demotype": {
"properties": {
"contents": {
"type": "string",
"index": "analyzed"
},
"name": {
"store": true,
"type": "string",
"index": "analyzed"
},
"id": {
"store": true,
"type": "long"
},
"userId": {
"store": true,
"type": "long"
}
}
}
}
}
这是一个最简单的mapping,定义了索引名称为demoindex,类型为demotype的mapping。各个字段分别是一个json对象,里面有类型有索引是否须要。
这个在sense里编辑,而后直接post提交。
{
"acknowledged": true
}
经过查看建立好的索引信息确认是不是你提交的mapping设置。
每次都经过手动的建立相似的mapping始终是个低效率的事情,elasticserach支持创建mapping模板,而后让模板自动匹配使用哪一个mapping定义。
PUT log_template
{
"order": 10,
"template": "log_*",
"settings": {
"index": {
"number_of_replicas": "2",
"number_of_shards": "5"
}
},
"mappings": {
"_default_": {
"_source_": {
"enable": false
}
}
}
}
建立一个log类型的索引mapping。咱们设置了两个基本的属性, "number_of_replicas": "2" 复制分数, "number_of_shards": "5" 分片个数。mappings里面设置了source字段默认不开启。
当咱们提交全部以“log_xxx”名字格式的索引时将自动命中这个mapping模板。
能够经过_template rest端点查看已经存在的mapping模板,或者经过head插件的右上角的”信息”里面的”模板”菜单查看。
{ "mq_template" : { "order" : 10, "template" : "mq*", "settings" : { "index" : { "number_of_shards" : "5", "number_of_replicas" : "2" } }, "mappings" : { "_default_" : { "_source_" : { "enable" : false } } }, "aliases" : { } }, "log_template" : { "order" : 10, "template" : "log_*", "settings" : { "index" : { "number_of_shards" : "5", "number_of_replicas" : "2" } }, "mappings" : { "_default_" : { "_source_" : { "enable" : false } } }, "aliases" : { } }, "error_template" : { "order" : 10, "template" : "error_*", "settings" : { "index" : { "number_of_shards" : "5", "number_of_replicas" : "2" } }, "mappings" : { "_default_" : { "_source_" : { "enable" : false } } }, "aliases" : { } } }
这一般用于一些业务不想关的存储中,好比日志、消息、重大错误预警等等均可以设置,只要这些重复的mapping是有规律的。
在es对数据进行分片的时候是采用hash取余的方式进行的,因此你能够传递一个固定的key,那么这个key将做为你固定的路由规则。在建立mappings的时候能够设置这个_routing参数。这在1.0的版本中是这样的设置的,也就是说你当前type下的全部document都是只能用着这个路由key进行。可是在es2.0以后routing跟着index元数据走,这样能够控制单个index的路由规则,在提交index的时候能够单独制定_routing参数,而不是直接设置mappings上。
在2.0以后已经再也不支持mappings配置_routing参数了。
在1.0里,好比,你能够将userid做为routing key,这样就能够将当前用户的全部数据都在一个分片上,当查询的时候就会加快查询速度。
{
"mappings": {
"post": {
"_routing": {
"required": true,
"path":"userid"
},
"properties": {
"contents": {
"type": "string"
},
"name": {
"store": true,
"type": "string"
},
"id": {
"store": true,
"type": "long"
},
"userId": {
"store": true,
"type": "long"
}
}
}
}
}
这个_routing是设置在mapping上的,做用于全部type。会使用userid做为sharding的key。可是在2.0里,是必须明确指定routing path的。
在你添加好mappings以后,建立当前索引的时候必须指定&routing=xxx,参数。这有个很大的好处就是你能够根据不一样的业务维度自由调整分片策略。
孰能生巧,分布式的东西仍是有不少比较特殊和挑战的地方,尤为是他的分布性,同时还要解决不少一致性问题、可用性问题等等。我对elasticsearch的使用也只是个简单的皮毛而已,它的分布式特性深深的吸引了我,期待下篇文章更加深刻的分享。好比,routing的内部原理,复制平衡算法等等。这篇文章是我对elasticsearch使用的一个简单的总结,但愿能对各位博友有点帮助,谢谢阅读,谢谢支持。
参考书籍《ElasticSearch 可扩展的开源弹性搜索解决方案》、《ElastcSearch权威指南》。