关于elasticsearch与数据库同步的探讨

前言:在最近的一个项目中,存在着es与Mysql同步的需求,当时就想着使用插件来完成,但是在实际的操作中存在一些不可避免的问题。

    目前,仅存的插件中,能够满足elasticsearch5.x版本同步更新的插件只剩下logstash-input-jdbc(插件的使用与原理:http://blog.csdn.net/yeyuma/article/details/50240595),而本人在实际操作的过程中发现了此款插件存在以下缺点:

    0. 安装logstash麻烦,需要配置一些列参数。

    1.更新时间频率最低只能60s以上,不能达到秒级。

    2.同时也要修改数据库。

    3.当数据库不在同一主机时,更新时间不统一。


     当我把此套方案提交给经理的时候,被无情的拒绝了,无奈只能想想其他办法,经过一段时间的思考,根据logstash插件的原理,利用任务调度来替换插件,从而可以避免原插件的部分问题。

     方案内容:利用自增字段来记录最新的更新数据的原理,使用任务调度可以自定义更新频率,实现elasticsearch与mysql同步更新。
 避免了安装插件的麻烦,同时也可以实现秒级更新,但是依然有修改数据库这一缺点。

![创建一张表,来记录更新的最新数据id](https://img-blog.csdn.net/20170621100908378?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzY0ODkyNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

下面引用项目中的代码,作为补充:

       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);
        }

注:省略了任务调度的代码,读者自行补充

你可能感兴趣的:(elasticSearch)