首页 > 代码库 > Elasticsearch PHP MYSQL的同步使用
Elasticsearch PHP MYSQL的同步使用
简介与用途
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,jdk需要使用1.8版本,如果使用1.7版本会报错。
ES安装,安装ES一定要注意ES的版本,笔者安装的是2.3.2版本
安装php,php至少为5.3.9版本,否则无法使用ES,笔者安装的是5.6.3版本。
php composer安装,并更改composer的镜像为国内
Elasticsearch-jdbc安装,版本要和ES的版本对应。
1 安装JDK
先检查系统有没有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
到(http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) 选择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加入环境变量。
2 安装Elasticsearch
ES的安装比较简单,首先到官网下载。笔者在(https://www.elastic.co/downloads/past-releases?page=9)下载的是2.3.2版本,因为后面使用elasticsearch-jdbc也是要2.3.2版本。另外使用的php必须是5.3.9或以上版本,因为5.3.8及以下版本存在两个bug,致使php无法使用ES。详情见(https://www.elastic.co/guide/en/elasticsearch/client/php-api/1.0/_php_version_requirement.html)。需要说明的是,不同的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 ‘http://localhost:9200/?pretty‘ 查看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 #
3 安装PHP
要使用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及以上版本。
4 安装php composer
Composer 是 PHP5以上 的一个依赖管理工具。它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们。 官网(https://getcomposer.org/) 。执行以下命令安装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:
Download the installer to the current directory
Verify the installer SHA-384 which you can also cross-check here
Run the installer
Remove the installer
如果看不懂,我来翻译下(相信你肯定能看懂),译文如下:
上述脚本将会检查php.ini是否配置正确,然后在当前目录下载最新版的composer.phar,上面4行代码的执行顺序是
在当前目录下载安装包
SHA-384检验安装包
执行安装命令
删除安装包(此步骤可省略)
这将会在当前目录下生成一个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了。
5 Elasticsearch-jdbc安装 将mysql数据同步到ES
ES-JDBC可到github (https://github.com/jprante/elasticsearch-jdbc) 查看,执行以下命令下载ES-JDBC
wget http://xbib.org/repository/org/xbib/elasticsearch/importer/elasticsearch-jdbc/2.3.2.0/elasticsearch-jdbc-2.3.2.0-dist.zip
[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
保存以上文件为esmysql.sh,并执行,如果执行失败,或者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中的端口或数据库或索引什么的配置有误。
最后,还有非常重要的一环,就是如何实现ES和mysql增量数据的实时同步,这个等我研究深入了再来更新博文,哈哈哈哈
Elasticsearch PHP MYSQL的同步使用