前言:在最近的一个项目中,存在着es与Mysql同步的需求,当时就想着使用插件来完成,但是在实际的操作中存在一些不可避免的问题。
目前,仅存的插件中,能够满足elasticsearch5.x版本同步更新的插件只剩下logstash-input-jdbc(插件的使用与原理:http://blog.youkuaiyun.com/yeyuma/article/details/50240595),而本人在实际操作的过程中发现了此款插件存在以下缺点:
0. 安装logstash麻烦,需要配置一些列参数。
1.更新时间频率最低只能60s以上,不能达到秒级。
2.同时也要修改数据库。
3.当数据库不在同一主机时,更新时间不统一。
当我把此套方案提交给经理的时候,被无情的拒绝了,无奈只能想想其他办法,经过一段时间的思考,根据logstash插件的原理,利用任务调度来替换插件,从而可以避免原插件的部分问题。
方案内容:利用自增字段来记录最新的更新数据的原理,使用任务调度可以自定义更新频率,实现elasticsearch与mysql同步更新。
避免了安装插件的麻烦,同时也可以实现秒级更新,但是依然有修改数据库这一缺点。

下面引用项目中的代码,作为补充:
logger.info("同步开始 : "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()).toString());
Record record = recordMapper.findById(1l);
List<CollectData> collectDatas = collectDataMapper.findByEsID(record.getRecord());
List<Long> nums = new ArrayList();
for (int i = 0; i < collectDatas.size(); i++) {
//拿到自增最大的id
nums.add(collectDatas.get(i).getEs_id());
CollectData data = collectDatas.get(i);
Map map = new HashMap();
map.put("author",data.getAuthor());
map.put("authorId",data.getAuthorId());
map.put("burl",data.getUrl());
map.put("click",data.getClick());
map.put("type",data.getType());
map.put("content",data.getContent());
try {
URL url = new URL(data.getUrl());
map.put("domain",url.getHost());
}catch (Exception e){
e.printStackTrace();
}
map.put("forward",data.getForward());
map.put("id",data.getId());
map.put("match_keys",data.getMatch_keys());
try {
Date date = data.getPublishDate();
if (null!=date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String time = sdf.format(date);
map.put("publishDate",time);
}
}catch (Exception e){
e.printStackTrace();
}
map.put("repeatTotal",data.getRepeatTotal());
map.put("score",data.getScore());
map.put("source",data.getSource());
//处理关键字
List<Long> ids= dataSubjectMapper.getAllIdByUUID(data.getId());
if (ids.size()>0){
map.put("subjectId",ids.toString());
}
map.put("title",data.getTitle());
map.put("url",data.getUrl());
map.put("zanTotal",data.getZanTotal());
elasticSearchClient.inserForIndex(map,"btext");
}
logger.info("同步数据条数 : "+nums.size());
if (nums.size()>0) {
Long max = Collections.max(nums);
logger.info("当前同步到的自增ID:" +max);
Record rnew = new Record();
rnew.setId(1l);
rnew.setRecord(max);
recordMapper.update(rnew);
}
注:省略了任务调度的代码,读者自行补充