搜索引擎:ElasticSearch+Logstash+Node.js+Vue+ElementUI+Axios
1. node.js安装
下载地址:https://nodejs.org/en/download/。
下载完成后安装(直接按默认方式安装就行)。
打开cmd 输入下面的命令查看是否成功安装。
node -v
npm –v
2. 安装搭建Vue项目
2.1 打开idea,新建项目
Create New Project > Static Web>填写project name和选择保存的工作空间>Finish
2.2 安装vue脚手架工具
等待下载完成以后,继续安装vue的脚手架工具,在Terminal内继续输入以下命令:
npm i -g vue-cli
测试是否安装成功:
vue –V
脚手架安装完成后,初始化包结构,继续输入:
vue init webpack demo
由于网络, 这步可能失败。提示错误:
vue-cli · Failed to download repovuejs-templates/w le ebpack-simple
这次解决办法, 只能用离线了。先到github下载模板zip:https://github.com/vuejs-templates/webpack-simple 用windows下cmd cd
到C:\\user\\{账号名}
,然后用来创建文件夹,再将从git上下载的zip文件解压到.vue-templates
文件夹中并重命名为webpack-simple。再运行:
vueinit webpack-sample {projectName} –offlin
一个项目目录就产生了,此处{projectName}为es_demo。初始化完成后。依次在Terminal输入如下指令:
cd { projectName }
npm install
npm run dev
2.3 配置外部IP可访问
打开项目根目录的package.json
,然后找到scripts
,如果你是希望在 npm run dev
的时候 内网可以方访问,那么你再 scripts下的dev 结尾增加一个参数:
--host {hostIP}
3. ES搭建和相关插件安装
3.1 下载ES
浏览ES官方网址https://www.elastic.co/downloads/elasticsearch下载相关版本的ES(ES最新版本为6.6.0)。本文档使用Linux作为ES安装,部署的操作系统。
3.2 解压ES
解压ES压缩包到自定义的目录,定义为$ES_HOME。
3.3 添加特定的Linux用户
本文档使用Linux作为配置ES的操作系统,此时使用root账户启动ES实例会出现如下的错误:
[2017-12-08T16:25:43,072][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main]
解决方案为创建另外一个非root的linux用户并使用该非root用户启动ES实例。
3.4 配置集群
根据实际需要,可以配置一个或多个节点的ES集群,集群由集群名和服务器地址确定,一个节点可以理解为一个ES实例,多节点的ES集群即为启动了多个配置了相同集群名和服务器地址的ES实例。此处使用配置了3个节点的ES集群作为例子,其中包括了一个主节点和两个副节点。
拷贝解压得到的Elasticsearch文件夹两次,并将其分别重命名为slave1和slave2作为两个副节点,重命名解压得到的Elasticsearch文件夹为master作为集群的主节点。
3.4.1 配置主节点
打开并编辑master/bin/elasticsearch.yml文件,在文件最后加入如下几行配置代码:
network.host: 127.0.0.1
http.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*"
node.name: master
http.port: 9200
node.master: true
cluster.name: {your cluster name}
注意每行配置代码前有一个空格,其中network.host是配置ES的服务器IP地址,该配置使得外部网络和服务器本地能够访问该服务器上的ES服务。
3.4.2 配置副节点
打开并编辑slave1/bin/elasticsearch.yml文件,在文件最后加入如下几行配置代码:
network.host: 127.0.0.1
http.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*"
node.name: slave1
http.port: 9201
node.master: false
cluster.name: {your cluster name}
discovery.zen.ping.unicast.hosts: ["master ip"]
打开并编辑slave2/bin/elasticsearch.yml文件,在文件最后加入如下几行配置代码:
network.host: 127.0.0.1
http.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*"
node.name: slave2
http.port: 9202
node.master: false
cluster.name: {your cluster name}
discovery.zen.ping.unicast.hosts: ["master ip"]
注意主节点和所有副节点的network.host
和cluster.name
必须保持一致,否则集群将找不到他的副节点。所有配置代码前均有一个空格。
3.5 启动ES实例
通过以下代码依次启动ES实例:
$ES_HOME/master/bin/elasticsearch –d
$ES_HOME/slave1/bin/elasticsearch –d
$ES_HOME/slave2/bin/elasticsearch –d
其中-d表示后台启动ES实例。
3.6 启动ES时可能会遇到的问题
3.6.1 文件句柄不足
max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
解决方案:
- 切换到root账号;
- 修改limits.conf文件,并添加以下内容:
vi /etc/security/limits.conf
* soft nproc 4096
* hard nproc 4096
* soft nofile 65536
* hard nofile 131072
* hard memlock unlimited
* soft memlock unlimited
* - as unlimited
3.6.2 设定虚存不足
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
解决方法:
- 切换到root用户下;
- 修改sysctl.conf文件:
vi /etc/sysctl.conf
,并添加:
vm.max_map_count=262144
- 使配置生效:
sysctl –p
3.7 安装ES可视化插件:Head
Elasticsearch head是一个入门级的Elasticsearch前端插件,提供集群管理、索引管理、查询过滤等功能。
Head插件安装有两种方式,一种是运行nodejs运行安装,elasticsearch5.x以后要求使用该方式;另一种是在chrome浏览器中安装ElasticSearch Head 0.14扩展程序。为简便和安全起见,可在需要时采取后一种安装方式安装。因为该插件可以对索引数据进行增删改查,对ES集群状态监控和管理,因此在生产环境使用时需要谨慎。插件下载地址:https://github.com/mobz/elasticsearch-head
3.8 安装ES中文分词插件:IK
ES自带有标准分词器(stand),该分词器对中文支持不太友好。在中文使用环境中,常用的分词器是IK(词库分词)。IK支持自定义词典,热更新 IK 分词,并提供两种粒度的分词:ik_max_word和ik_smart。
- ik_max_word: 会将文本做最细粒度的拆分,会穷尽各种可能的组合。
- ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。
IK的安装方式如下:
- 从https://github.com/medcl/elasticsearch-analysis-ik/releases下载与ES匹配的zip包
- create plugin folder cd your-es-root/plugins/ && mkdir ik
- unzip plugin to folder your-es-root/plugins/ik
- restart es service
4 Logstash搭建
4.1 Logstash下载
从https://www.elastic.co/downloads/logstash下载logstash版本,注意要和ES的版本匹配。下载完成之后解压到自定义的存放目录即可(目录定义为:$LOGSTASH_HOME),logstash拆箱即用,无需其他安装配置。
4.2 使用Logstash同步MySQL的数据到ES
我们借助Logstash的logstash-input-jdbc插件来实现同步MySQL的数据到ES,该插件在Logstash6.6中自带,无需另外安装。Logstash通过在配置文件中分别指定Input、Filter、Output配置项,来完成读取指定源数据、数据过滤、输出到指定位置的过程。同步MySQL数据到ES中有两种配置方式,第一种是全量数据同步,该场景适合数据表修改少,数据量小,表结构中没有数据更新时间戳字段或者自增长主键;第二种是增量数据同步,该场景适合数据表修改多,数据量大,表结构中有数据更新时间戳字段或者自增长主键。
4.3 全量数据同步
Input配置项如下:
jdbc_driver_library
: jdbc mysql 驱动的路径,在上一步中已经下载
jdbc_driver_class
: 驱动类的名字,mysql 填 com.mysql.jdbc.Driver 就好了
jdbc_connection_string
: 数据库的完整URL
jdbc_user
: mysql 用户
jdbc_password
: mysql 密码
schedule
: 执行 sql 时机,类似 crontab 的调度
statement
: 要执行的 sql,全量数据同步一般写为:select * from table_name。
Output配置项如下:
hosts
: es 集群地址
index
: 导入到 es 中的 index 名,ES6.X版本不再支持一个索引下有多个type,因此设置为一个表对应一个索引,索引名字直接设置成 mysql 表的名字
document_id
: 导入到 es 中的文档 id,这个需要设置成主键,否则同一条记录更新后在 es 中会出现两条记录,%{id} 表示引用 mysql 表中 id 字段的值
template_overwrite
:是否用指定模板
template
:自定义ES映射模板存储位置
4.4 增量数据同步
增量数据同步的配置与全量数据同步配置的差别在于Input部分:statement不同,以及增加了几个配置项。
use_column_value
: 使用递增列的值
tracking_column_type
: 递增字段的类型,numeric 表示数值类型, timestamp表示时间戳类型
tracking_column
: 递增字段的名称,这里使用gmt_modified这一列,这列的类型是timestamp
last_run_metadata_path
: 同步点文件,这个文件记录了上次的同步点,重启时会读取这个文件,这个文件可以手动修改
statement
: 要执行的 sql,以":"开头是定义的变量,可以通过 parameters 来设置变量,这里的 sql_last_value 是内置的变量,表示上一次 sql 执行中gmt_modified的值
4.5 ES mapping模板配置
ES的mapping映射机制用于字段类型确认,将每个字段匹配为一种确定的数据类型。Mapping机制使用模板来配置数据字段的类型和其他属性,支持动态模板和静态模板。动态模板(dynamic_templates)可以做到对某种类型字段进行匹配mapping,当Elasticsearch处理一个位置的字段时,它通过【动态映射】来确定字段的数据类型且自动将该字段加到类型映射中。静态模板则需要具体配置字段的名称。以下配置为采用动态模板的配置。
动态模板中比较重要的配置是“string_fields”:该配置项对匹配到的string类型做映射,目前该配置的作用是对string类型用ik_max_word分词,然后转换为es的text类型。第二个是properties配置项,在该配置项下可以添加具体的字段,配置该字段的名称、类型、映射属性。以下配置是在该项目下加入了”@timestamp”和”@version”两个字段,”@timestamp”的默认值是当前文档索引建立的时间;”@version”代表当前文档版本号,默认值是1。
静态和动态模板各有自己的应用场景:
- 静态模板 :适合索引字段数据固定的场景,一旦配置完成,不能向里面加入多余的字段,否则会报错
- 优点:scheam已知,业务场景明确,不容易出现因字段随便映射从而造成元数据撑爆es内存,从而导致es集群全部宕机
- 缺点:字段数多的情况下配置稍繁琐
- 动态模板 :适合字段数不明确,大量字段的配置类型相同的场景,多加字段不会报错
- 优点:可动态添加任意字段,无须改动schemal
- 缺点:如果添加的字段非常多,有可能造成es集群宕机
定制索引模板,是搜索业务中一项比较重要的步骤,需要注意的地方有很多,比如:
- 字段数固定吗
- 字段类型是什么
- 分不分词
- 索引不索引
- 存储不存储
- 排不排序
- 是否加权
除了这些还有其他的一些因素,比如,词库的维护改动,搜索架构的变化等等。如果前提没有充分的规划好,后期改变的话,改动其中任何一项,都需要重建索引,这个代价是非常大和耗时的,尤其是在一些数据量大的场景中。
4.6 logstash多表同步到ES
Logstash 在 6.0 推出了 multiple pipeline 的解决方案,即在一个 logstash 实例中可以同时进行多个独立数据流程的处理工作,如下图所示。
而在这之前用户只能通过在单机运行多个 logstash 实例或者在配置文件中增加大量 if-else条件判断语句来解决。一个 logstash 实例可以借助 pipelines 机制同步多个表,只需要写多个配置文件就可以了,假设我们有两个表 table1 和 table2,对应两个配置文件 sync_table1.cfg 和 sync_table2.cfg。在 config/pipelines.yml 中配置:
- pipeline.id: table1
path.config: "config/sync_table1.cfg"
- pipeline.id: table2
path.config: "config/sync_table2.cfg"
直接 bin/logstash 启动即可。
5 Element UI
打开刚刚解压缩生成的{projectName}目录下,执行以下指令
npm i element-ui –S
在 main.js 中写入以下内容:
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
5.1 url-loader
然后如果出现compile failed错误,安装url-loader:
npm i url-loader file-loader –D
打开webpack.config.js添加如下的代码:
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'url-loader'
},
运行npm install
,然后npm run dev
重启vue。
5.2 vue-axios
5.2.1 安装Axios
npm install
npm install vue-axios –save
npm install qs.js –save
5.2.2 安装成功后,在main.js页面引用:
import Vue from 'vue'
import axios from 'axios'
import qs from 'qs'
//全局注册,使用方法为:this.$axios
Vue.prototype.$axios = axios
//全局注册,使用方法为:this.qs
Vue.prototype.qs = qs
5.2.3 使用实例
const vm = this;
let api = "http://{host_ip}/_search?filter_path=hits.hits._source";
let bodyData = JSON.stringify({
query: {
}
});
const configAxios = {
headers: {'Content-Type': 'application/json'}
};
vm.$axios.post(api, bodyData, configAxios)
.then((response) => {
vm.result = response.data.hits.hits;
})
.catch((err) => {console.warn('error during http call', err);
});