Elasticsearch 是一个分布式,RESTful 模式的高速搜索引擎,它使用标准的 RESTful APIs 和 JSON,同时提供支持如 java,python,php 等的多种语言。下文将 Elasticsearch 简称 ES。
一个简单的 curl 查询数据的示例如下:
- curl -XGET 'localhost:9200/sedoctorfeedback/feedback/_search?pretty&q=119'
ES 使用诸如 XPUT,XDELETE,XPOST,XGET 等 RESTful 模式完成数据的增删改查操作。本例意思是找到 sedoctorfeedback 索引里 type 为 feedback 的数据,查询条件是 119,这是全文搜索,fulltext。查询结果如下:
- { "took" : 29,
- "timed_out" : false,
- "_shards" : { "total" : 5,
- "successful" : 5,
- "failed" : 0
- },
- "hits" : { "total" : 1,
- "max_score" : 1.386767,
- "hits" : [ { "_index" : "sedoctorfeedback",
- "_type" : "feedback",
- "_id" : "119",
- "_score" : 1.386767,
- "_source" : { "id" : 119,
- "content" : "google地图无法正常显示",
- "contacttype" : "QQ",
- "contact" : "702865206",
- "questiontype" : 4,
- "seversion" : "5.0.1.9",
- "ieversion" : "6",
- "osversion" : "win_xp_32",
- "img" : 0,
- "joindate" : "2012-03-14T00:00:00.000+08:00",
- "addtime" : "2012-03-14T15:29:34.000+08:00",
- "qid" : "",
- "extension1" : "",
- "extension2" : "",
- "extension3" : ""
- }
- } ]
- }
- }
同样,可以使用 php 查询数据,若使用 php 语法代码如下:
- <?php$params = array();$params['hosts'] = array ( '127.0.0.1:9200', // IP + Port);require 'vendor/autoload.php';$client = new Elasticsearch\Client($params);$params = array( 'index' => 'sedoctorfeedback', 'type' => 'feedback', 'id' => 119,
- ); try { $resp = $client->get($params);
- } catch (Exception $ex) { $resp = $ex->getMessage();
- }
- var_dump($resp);
执行 php 程序返回结果和上例相同。
我们的目的是将 mysql 数据同步到 ES, 通过 php 查询 ES。需要安装以下依赖
先检查系统有没有 jdk, 一般 centos 会自带 jdk,检查如下
- $ rpm -qa | grep jdk
- java-1.7.0-openjdk-1.7.0.101-2.6.6.4.el6_8.x86_64
- java-1.7.0-openjdk-devel-1.7.0.101-2.6.6.4.el6_8.x86_64
centos 自带的是 1.7 版本的 jdk, 这个不能用,笔者就在这里栽了坑。这时需要先将系统自带的 jdk 删掉, 如下
- rpm -e --nodeps java-1.7.0-openjdk-1.7.0.101-2.6.6.4.el6_8.x86_64
到 () 选择 jdk 版本。在选择版本之前先看自己的 linux 是 32 位还是 64 位的,使用 uname -a 查看系统版本。
- $ uname -a
- Linux gz01v.brow.corp.qihoo.net 2.6.32-220.4.2.el6.x86_64 #1 SMP Tue Feb 14 04:00:16 GMT 2012 x86_64 x86_64 x86_64 GNU/Linux
可知笔者系统是 64 位的,因此选择了如下 jdk
下载得到 jdk-8u121-linux-x64.rpm 安装包,将该文件放到 / home/chenxiaolong 目录,并赋予可执行权限。使用 rpm 安装,命令及过程如下
- [root@gz03v /home/chenxiaolong]# rpm -ivh jdk-8u121-linux-x64.rpm Preparing... ########################################### [100%]
- 1:jdk1.8.0_121 ########################################### [100%]Unpacking JAR files... tools.jar... plugin.jar... javaws.jar... deploy.jar... rt.jar... jsse.jar... charsets.jar... localedata.jar...[root@gz03v /home/chenxiaolong]# java -versionjava version "1.8.0_121"Java(TM) SE Runtime Environment (build 1.8.0_121-b13)Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)[root@gz03v /home/chenxiaolong]# javac -versionjavac 1.8.0_121
至此,已成功的安装了 jdk 1.8 版本。RPM 安装会自动将 java javac 加入环境变量。
ES 的安装比较简单,首先到官网下载。笔者在 () 下载的是 2.3.2 版本,因为后面使用 elasticsearch-jdbc 也是要 2.3.2 版本。另外使用的 php 必须是 5.3.9 或以上版本,因为 5.3.8 及以下版本存在两个 bug,致使 php 无法使用 ES。详情见()。需要说明的是,不同的 elasticsearch php api 需要对应的 php 版本。ES 5.0 版本需要对应的 php 5.6.6 及以上版本,ES 2.0 需要 php 5.4.0 及以上版本,ES 1.0 需要 php 5.3.9 及以上版本。不同版本的 ES,使用 composer 安装的依赖包版本也不同,需要与 ES 的版本对应
在官网下载得到 elasticsearch-2.3.2.tar.gz,将该文件包放到 / home/chenxiaolong 目录,解压文件
- [root@gz03v /home/chenxiaolong]# tar zxvf elasticsearch-2.3.2.tar.gz elasticsearch-2.3.2/README.textile
- elasticsearch-2.3.2/LICENSE.txt
- elasticsearch-2.3.2/NOTICE.txt
- elasticsearch-2.3.2/modules/
- elasticsearch-2.3.2/modules/lang-groovy/
- elasticsearch-2.3.2/modules/reindex/
- elasticsearch-2.3.2/modules/lang-expression/
- ······此处省略······
解压后得到目录 elasticsearch-2.3.2,cd 到解压后的 bin 目录下,启动 ES
- [root@gz03v /home/chenxiaolong]# cd elasticsearch-2.3.2/bin/
- [root@gz03v /home/chenxiaolong/elasticsearch-2.3.2/bin]# ./elasticsearch
- Exception in thread "main" java.lang.RuntimeException: don't run elasticsearch as root.
- at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:93)
- at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:144)
- at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:270)
- at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:35)
- Refer to the log for complete error details.
报错是因为 ES 不允许使用 root 账户使用,切换到 chenxiaolong 账户,启动 ES。
- [root@gz03v /home/chenxiaolong/elasticsearch-2.3.2/bin]# su chenxiaolong[chenxiaolong@gz03v ~/elasticsearch-2.3.2/bin]$ ./elasticsearchlog4j:ERROR setFile(null,true) call failed.
- java.io.FileNotFoundException: /home/chenxiaolong/elasticsearch-2.3.2/logs/elasticsearch.log (权限不够)
出现以上错误是因为权限不够,切换到 root 账户,将目录的属主改成 chenxiaolong, 并赋予权限 755,再切换回 chenxiaolong。执行./elasticsearch-2.3.2/bin/elasticsearch 启动 ES。
- [root@gz03v / home / chenxiaolong / elasticsearch - 2.3.2]# cd .. [root@gz03v / home / chenxiaolong]# lselasticsearch - 2.3.2 elasticsearch - 2.3.2.tar.gz[root@gz03v / home / chenxiaolong]# cd elasticsearch - 2.3.2 / bin / [root@gz03v / home / chenxiaolong / elasticsearch - 2.3.2 / bin]# cd .. / .. / [root@gz03v / home / chenxiaolong]# chown - R chenxiaolong.chenxiaolong elasticsearch - 2.3.2[root@gz03v / home / chenxiaolong]# chmod - R 755 elasticsearch - 2.3.2[root@gz03v / home / chenxiaolong]# su chenxiaolong[chenxiaolong@gz03v ~] $ . / elasticsearch - 2.3.2 / bin / elasticsearch[2017 - 02 - 24 22 : 37 : 11, 391][WARN ][bootstrap ] unable to install syscall filter: seccomp unavailable: requires kernel 3.5 + with CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER compiled in [2017 - 02 - 24 22 : 37 : 11, 712][INFO ][node ] [Erg] version[2.3.2],
- pid[20305],
- build[b9e4a6a / 2016 - 04 - 21T16: 03 : 47Z][2017 - 02 - 24 22 : 37 : 11, 712][INFO ][node ] [Erg] initializing ... [2017 - 02 - 24 22 : 37 : 12, 866][INFO ][plugins ] [Erg] modules [reindex, lang - expression, lang - groovy],
- plugins [],
- sites [][2017 - 02 - 24 22 : 37 : 12, 904][INFO ][env ] [Erg] using [1] data paths,
- mounts [[/ (/dev / xvde1)]],
- net usable_space [81.7gb],
- net total_space [98.4gb],
- spins ? [no],
- types [ext2][2017 - 02 - 24 22 : 37 : 12, 905][INFO ][env ] [Erg] heap size [1007.3mb],
- compressed ordinary object pointers [true][2017 - 02 - 24 22 : 37 : 12, 905][WARN ][env ] [Erg] max file descriptors [32768]
- for elasticsearch process likely too low,
- consider increasing to at least [65536][2017 - 02 - 24 22 : 37 : 16, 197][INFO ][node ] [Erg] initialized[2017 - 02 - 24 22 : 37 : 16, 197][INFO ][node ] [Erg] starting ... [2017 - 02 - 24 22 : 37 : 16, 315][INFO ][transport ] [Erg] publish_address {
- 127.0.0.1 : 9300
- },
- bound_addresses {
- 127.0.0.1 : 9300
- } [2017 - 02 - 24 22 : 37 : 16, 321][INFO ][discovery ] [Erg] elasticsearch / VDpJE96fQ024S4cwk0UIPg[2017 - 02 - 24 22 : 37 : 19, 374][INFO ][cluster.service ] [Erg] new_master {
- Erg
- } {
- VDpJE96fQ024S4cwk0UIPg
- } {
- 127.0.0.1
- } {
- 127.0.0.1 : 9300
- },
- reason: zen - disco - join(elected_as_master, [0] joins received)[2017 - 02 - 24 22 : 37 : 19, 430][INFO ][http ] [Erg] publish_address {
- 127.0.0.1 : 9200
- },
- bound_addresses {
- 127.0.0.1 : 9200
- } [2017 - 02 - 24 22 : 37 : 19, 430][INFO ][node ] [Erg] started[2017 - 02 - 24 22 : 37 : 19, 434][INFO ][gateway ] [Erg] recovered [0] indices into cluster_state
出现如上情况表示启动成功,在此界面 ES 会一直运行,使用 Ctrl+C 可终止 ES 进程。如果要将 ES 作为一个后台进程运行,加参数 -d 即 ./elasticsearch-2.3.2/bin/elasticsearch
可使用 curl '' 查看 ES 是否正确启动。
- [chenxiaolong@gz03v ~] $ curl 'http: //localhost:9200/?pretty'{ "name" : "She-Venom", "cluster_name" : "elasticsearch", "version" : { "number" : "2.3.2", "build_hash" : "b9e4a6acad4008027e4038f6abed7f7dba346f94", "build_timestamp" : "2016-04-21T16:03:47Z", "build_snapshot" : false, "lucene_version" : "5.5.0"
- },
- "tagline" : "You Know, for Search"
- }
其中 cluster_name 是集群的名称,这里我们只在一台机器上安装了 ES,集群名称可在 / home/chenxiaolong/elasticsearch-2.3.2/config/elasticsearch.yml 配置,出现在配置文件的第 17 行。
- 13 # ---------------------------------- Cluster -----------------------------------
- 14 #
- 15 # Use a descriptive name for your cluster:
- 16 #
- 17 # cluster.name: my-application
- 18 #
要使用 ES,php 的版本必须大于等于 5.3.9 版本。PHP 的安装在次不再赘述。下回追加上。
ES 5.0 版本需要对应的 php 5.6.6 及以上版本,ES 2.0 需要 php 5.4.0 及以上版本,ES 1.0 需要 php 5.3.9 及以上版本。
Composer 是 PHP5 以上 的一个依赖管理工具。它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们。 官网 () 。执行以下命令安装 composer
- $ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"$ php -r "if (hash_file('SHA384', 'composer-setup.php') === '55d6ead61b29c7bdee5cccfb50076874187bd9f21f65d8991d46ec5cc90518f447387fb9f76ebae1fbbacf329e583e30') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
- $ php composer-setup.php
- $ php -r "unlink('composer-setup.php');"
This installer script will simply check some php.ini settings, warn you if they are set incorrectly, and then download the latest composer.phar in the current directory. The 4 lines above will, in order:
如果看不懂,我来翻译下(相信你肯定能看懂),译文如下:
上述脚本将会检查 php.ini 是否配置正确,然后在当前目录下载最新版的 composer.phar,上面 4 行代码的执行顺序是
这将会在当前目录下生成一个 composer.phar 文件。
- [chenxiaolong@gz02v /data/htdocs/chenxiaolong]$ php composer.phar
- ______ / ____/___ ____ ___ ____ ____ ________ _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___// /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
- /_/Composer version 1.3.2 2017-01-27 18:23:41
安装成功的结果如上面所示。
在当前目录下(你的项目在哪里就把 composer.phar 复制到哪里)新建一个 composer.json 文件,文件内容如下:
- {
- "require":{
- "elasticsearch/elasticsearch" : "~1.0"
- },
- "repositories": {
- "packagist": {
- "type": "composer",
- "url": "https://packagist.phpcomposer.com"
- } }}
require 里是需要加载的依赖包,url 是下载依赖包的地址,这里的 url 填写的是国内镜像,因为国外的总是被墙。接下来在当前目录执行命令 php composer.phar install --no-dev 完成 ES php api 的安装,执行完成会在当前目录下生一个 vendor 目录,vendor 目录下有个 autoload.php 文件,在你自己写的代码中将 autoload.php 文件 require 进来即可。在 vendor 目录下还有其他一些目录。
vendor 目录里文件如下:
autoload.php composer elasticsearch guzzle monolog pimple psr symfony
编写一个 php 脚本,代码内容如下:
- <?php$params = array();$params['hosts'] = array ( '127.0.0.1:9200', // IP + Port// 'localhost:9200', // Domain + Port
- // 'localhost', // Just Domain
- // 'http://localhost', // SSL to localhost);require 'vendor/autoload.php';$client = new Elasticsearch\Client($params);$p = array( 'index' => 'company', 'type' => 'employee', 'id' => 1, 'body' => array( 'uid'=>11, 'name'=>'chenxiaolong', 'age'=>'23 years old'
- )
- );$resp = $client->index($p);$params = array( 'index' => 'company', 'type' => 'employee', 'id' => 1,
- ); try { $resp = $client->get($params);
- } catch (Exception $ex) { $resp = $ex->getMessage();
- }
- var_dump($resp);
执行以上程序示例如下:
- [chenxiaolong@gz02v /data/htdocs/chenxiaolong]$ php es.php
- array(6) { ["_index"]=>
- string(7) "company"
- ["_type"]=>
- string(8) "employee"
- ["_id"]=>
- string(1) "1"
- ["_version"]=>
- int(2)
- ["found"]=>
- bool(true)
- ["_source"]=>
- array(3) { ["uid"]=>
- int(11)
- ["name"]=>
- string(12) "chenxiaolong"
- ["age"]=>
- string(12) "23 years old"
- }
- }
至此,我们已成功的安装了 ES-PHP。下一步就是如何将 mysql 数据同步到 ES 了。
ES-JDBC 可到 github () 查看,执行以下命令下载 ES-JDBC
wget
- [chenxiaolong@gz03v ~]$ wget http://xbib.org/repository/org/xbib/elasticsearch/importer/elasticsearch-jdbc/2.3.2.0/elasticsearch-jdbc-2.3.2.0-dist.zip--2017-02-24 23:37:14-- http://xbib.org/repository/org/xbib/elasticsearch/importer/elasticsearch-jdbc/2.3.2.0/elasticsearch-jdbc-2.3.2.0-dist.zip正在解析主机 xbib.org... 176.28.49.27正在连接 xbib.org|176.28.49.27|:80... 已连接。
- 已发出 HTTP 请求,正在等待回应... 200 OK
- 长度:30414020 (29M) [application/zip]
- 正在保存至: "elasticsearch-jdbc-2.3.2.0-dist.zip"
下载对应版本,笔者安装的 ES 是 2.3.2 版本,故下载 ES-JDBC 也是 2.3.2 版本,一定要用对应版本的,否则你可能会遇到坑。这将会下载得到 elasticsearch-jdbc-2.3.2.0-dist.zip,解压该文件到当前目录 (/home/chenxiaolong) 得到 elasticsearch-jdbc-2.3.2.0 。elasticsearch-jdbc-2.3.2.0 目录下有两个子目录 lib 和 bin。编写 shell 脚本,将 mysql 数据同步到 ES。脚本代码如下:
- # ! / bin / shbin = /data/htdocs / chenxiaolong / elasticsearch - jdbc - 2.3.2.0 / bin # ES - JDBC的目录lib = /data/htdocs / chenxiaolong / elasticsearch - jdbc - 2.3.2.0 / lib echo ' {
- "type" : "jdbc",
- "jdbc": {
- "elasticsearch.autodiscover": true,
- "elasticsearch.cluster": "my-application",
- # 集群名称,在config / elasticsearch.yml配置"client.transport.sniff": "true",
- "sniffOnConnectionFault": "true",
- "client.transport.ignore_cluster_name": "false",
- "url": "jdbc:mysql://10.16.59.142:3306/sedoctorfeedback",
- #链接mysql,IP,
- PORT,
- DB,确保库名称为sedoctorfeedback "user": "chenxiaolong",
- "password": "chenxiaolong@browser",
- "sql": "select *,id as _id from feedback order by _id",
- # sql语句"elasticsearch" : { "host" : "127.0.0.1",
- # ES 所在IP,本机就写127.0.0.1即可 "port" : 9300 # 端口,9300不行的话就试试9200
- },
- "index" : "sedoctorfeedback",
- # 在ES中新的索引名称,自定义"type" : "feedback" # 在ES中新的type类型,自定义
- }
- }' | java - cp "${lib}/*" - Dlog4j.configurationFile = $ {
- bin
- }
- /log4j2.xml org.xbib.tools.Runner org.xbib.tools.JDBCImporter/
,并执行,如果执行失败,或者 ES 里没有查询到同步过来的数据,可以查看日志
- $ tailf /data/htdocs/chenxiaolong/logs/jdbc.log
若出现以下这种错误, 可能是脚本中 elasticsearch.cluster 填写错误,或者 port 端口错误,改成 9200 ,9300 试试
- ][pool - 3 - thread - 1] error
- while processing request: no cluster nodes available,
- check settings {
- autodiscover = true,
- client.transport.ignore_cluster_name = false,
- client.transport.nodes_sampler_interval = 5s,
- client.transport.ping_timeout = 5s,
- cluster.name = my - application,
- flush_interval = 5s,
- host.0 = 127.0.0.1,
- max_actions_per_request = 10000,
- max_concurrent_requests = 4,
- max_volume_per_request = 10mb,
- name = importer,
- port = 9200,
- sniff = false
- }
执行完毕,就将 mysql 表中数据同步到 ES 了,就可以用 php 查询 ES 获得数据结果了。php 查询示例如本文开头述。或使用
curl -XGET 'localhost:9200/sedoctorfeedback/feedback/_search?pretty&q=*'
查看导入结果
安装 JDK 时候,执行 java -version 错误如下:
- $java -version
- bash: /usr/local/jdk1.8.0_121//bin/java: cannot execute binary file
网上说这是因为操作系统的位数和 JDK 的位数不一致导致的,但是笔者都是 64 位的。网上的解释并不靠谱,这可能是因为你一开始下载的是 JDK 的 tar.gz 的包,将它解压到某个目录,然后配置 / etc/profile 导致的。这时候你用 whereis java 即可找到 java 命令所在,笔者的解决办法是 rpm -e 删掉 jdk 的 rpm 包,再找到并删掉 jdk 的 tar.gz。重新从官网下载 rpm, 重新 rpm -ivh 安装。只有如以下这样才算正确安装了 jdk。RPM 安装会自动将 java javac 加入环境变量。
- [root@gz02v ~]# whereis javajava: /usr/bin/java /etc/java /usr/lib/java /usr/share/java /usr/share/man/man1/java.1[root@gz02v ~]# cd /usr/bin/[root@gz02v /usr/bin]# ll | grep javalrwxrwxrwx 1 root root 22 Feb 24 15:44 java -> /etc/alternatives/java
- lrwxrwxrwx 1 root root 23 Feb 24 15:44 javac -> /etc/alternatives/javac
- lrwxrwxrwx 1 root root 25 Feb 24 15:44 javadoc -> /etc/alternatives/javadoc
- lrwxrwxrwx 1 root root 32 Feb 24 15:44 javafxpackager -> /etc/alternatives/javafxpackager
- lrwxrwxrwx 1 root root 23 Feb 24 15:44 javah -> /etc/alternatives/javah
- lrwxrwxrwx 1 root root 23 Feb 24 15:44 javap -> /etc/alternatives/javap
- lrwxrwxrwx 1 root root 30 Feb 24 15:44 javapackager -> /etc/alternatives/javapackager
- lrwxrwxrwx 1 root root 30 Feb 24 15:44 java-rmi.cgi -> /etc/alternatives/java-rmi.cgi
- lrwxrwxrwx 1 root root 24 Feb 24 15:44 javaws -> /etc/alternatives/javaws
笔者当时遇到的问题就是
lrwxrwxrwx 1 root root 22 Feb 24 15:44 java -> /etc/alternatives/java
lrwxrwxrwx 1 root root 23 Feb 24 15:44 javac -> /etc/alternatives/javac
这两个错误导致的 cannot execute binary file
使用 ES-JDBC 脚本导入数据时候,执行 curl -XGET 'localhost:9200/sedoctorfeedback/feedback/_search?pretty&q=*' 返回
- {
- "error" : {
- "root_cause" : [ {
- "type" : "index_not_found_exception",
- "reason" : "no such index",
- "resource.type" : "index_or_alias",
- "resource.id" : "sedoctorfeedback",
- "index" : "sedoctorfeedback"
- } ],
- "type" : "index_not_found_exception",
- "reason" : "no such index",
- "resource.type" : "index_or_alias",
- "resource.id" : "sedoctorfeedback",
- "index" : "sedoctorfeedback"
- },
- "status" : 404}
这可能是由于 esmysql.sh 中的端口或数据库或索引什么的配置有误。
来源: http://www.bubuko.com/infodetail-1958539.html