最近公司打算用elasticsearch做搜索,首先当然需要同步一部分数据过去,但我在网上搜来搜去都找不到比较好的资料,要不就是方案很复杂,要不就是语焉不详,干脆就自己研究了。
整体架构流程
同步说白了就是把变动的记录查出来,再塞到elasticsearch里,很简单。其实官方是有提供一套完整的技术栈的(elk),没什么特别原因,不需要瞎折腾。各位跟着我一步一步做就行了,直接保姆教学。
技术名词解释
- ELK 【es官方推出的技术栈,目前好像有四个组件,但一般只用三个】
- Elasticsearch 【一个分布式搜索和分析引擎】
- Logstash 【一个数据采集和处理中间件】
- Kibana 【一个数据管理和可视化工具】
详解
1.前期准备:
首先要去Releases · infinilabs/analysis-ik · GitHub看一下中文分词插件更新到哪里了,你就按照对应插件的版本号来选elasticsearch的版本,除非你的项目不需要中文分词。
然后去官网Past Releases of Elastic Stack Software | Elastic下载对应的资源,除了elasticsearch还有logstash也得装,至于Kibana可装可不装,同步是用不上的。
注意:以上的所有资源,下载时都要注意版本号一致。
2.elasticsearch的安装和启动:
我不知道你是用什么系统,所以就不贴命令了。
总之把压缩包里的东西解压出来就行,然后你会得到一个es的文件目录,进入config目录,里面有一个elasticsearch.yml文件,这个就是es的配置文件。
随便用什么软件编辑,在末尾添加如下配置(以单机启动为例):
# 节点名称
node.name: node-1
# 开放外部访问
network.host: 0.0.0.0
# 是否锁定内存
bootstrap.memory_lock: false
# 关闭ip地址库下载
ingest.geoip.downloader.enabled: false
# 关闭用户密码登录
xpack.security.enabled: false
# 定义初始主节点集合
cluster.initial_master_nodes: ["node-1"]
然后再编辑另一个文件jvm.options,这个是es自带的jvm环境的配置文件,添加如下配置:
# 分配的内存范围
-Xmx512m
-Xms512m
如果你是linux系统,可能还要修改如下配置:
# 修改文件句柄数
vim /etc/security/limits.conf
# 增加以下内容
* soft nofile 65536
* hard nofile 65536
# 调整vm.max_map_count的大小
# 永久修改
echo vm.max_map_count=262144 >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf
# 临时修改
sysctl -w vm.max_map_count=262144
# 或者
sudo sysctl -w vm.max_map_count=262144
最后安装中文分词插件并启动elasticsearch:
# 安装中文分词插件
./elasticsearch-plugin install https://github.com/infinilabs/analysis-ik/releases/download/v8.12.2/elasticsearch-analysis-ik-8.12.2.zip
# 查看插件是否安装成功
./elasticsearch-plugin list
# 启动ES
./elasticsearch &
3.logstash的安装:
同样是把压缩包解压出来,得到软件目录,然后下载一个jdbc驱动(这里以mysql为例,别的数据库就下载对应的驱动)放到lib目录下。
下载地址:https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.28/mysql-connector-java-8.0.28.jar
4.开始同步数据
先在es创建一个索引,结构就是mysql指定的表(数据来源)里你需要的字段,可以是全部字段,也可是特定的字段,没有限制,只要数据类型对应得上就可以。
这里提供一个转换脚本:https://github.com/daimengdewo/mysqltoes
顺便再提供一个示例:
PUT /test
{
"mappings": {
"dynamic" : "false",
"properties": {
"housesalegjid": {
"type": "integer"
},
"houseid": {
"type": "integer"
},
"gjinfo": {
"type": "text",
"analyzer" : "ik_max_word",
"search_analyzer" : "ik_smart"
},
"createtime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
然后在logstash的config目录下新建一个jdbc.conf文件,内容如下:
input {
jdbc {
# 数据库连接字符串
jdbc_connection_string => "jdbc:mysql://gz-cynosdbmysql-grp-otkg01dn.sql.tencentcdb.com:24011/erp?useUnicode=true&characterEncoding=UTF-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8"
# 数据库账号
jdbc_user => "javaAgent"
# 数据库密码
jdbc_password => "lzc-apps-java-agent-db"
# jdbc驱动路径
jdbc_driver_library => "G:\ELK\logstash-8.2.3\lib\mysql-connector-java-8.0.28.jar"
# 驱动程序类名
jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
# 是否分页
jdbc_paging_enabled => "true"
# 每页行数
jdbc_page_size => "10000"
# 查询语句(用于在数据库查询需要同步的记录,这个要你自己定义)
statement => "SELECT housesalegjid,houseid,gjinfo,DATE_FORMAT ( CreateTime, '%Y-%m-%d %H:%i:%s' ) AS createtime FROM housesalegj WHERE housesalegjid > :sql_last_value"
# 开启字段捕获
use_column_value => true
# 指定增量标识
tracking_column => "housesalegjid"
# 运行频率(不懂就去搜一下schedule)
schedule => "*/30 * * * * *"
# 时区
jdbc_default_timezone => "Asia/Shanghai"
# 类型
type => "jdbc"
}
}
filter {
}
output {
elasticsearch {
# es的索引名称(你刚才创建那个)
index => "test"
# 主键对应的字段,es和数据库表里要一致
document_id => "%{housesalegjid}"
# 自动覆盖
template_overwrite => true
# 指定es的目标地址
hosts => ["localhost:9200"]
}
}
至此一切准备完成,执行如下命令即可开启同步:
./logstash -f config/jdbc.conf &
logstash会自动执行全量+增量,如果中途出现意外,重新启动后还会自动进行差异同步,非常好用。