一、热更新原理

  elasticsearch开启加载外部词典功功能后,会每60s间隔进行刷新字典。具体原理代码如下所示:

public void loadDic(HttpServletRequest req,HttpServletResponse response){
String eTag =req.getParameter("If-None-Match");
try {
OutputStream out= response.getOutputStream();
List<String> list=new ArrayList<String>();
list.add("中华人民共和国");
list.add("我爱你爱我");
String oldEtag = list.size() + "";
StringBuffer sb=new StringBuffer();
if (oldEtag != eTag) {
for (String str : list) {
if(StringUtils.isNotBlank(str)){
sb.append("\r\n");
}
sb.append(str+"\r\n");
}
}
String data=sb.toString(); response.setHeader("Last-Modified", String.valueOf(list.size()));
response.setHeader("ETag",String.valueOf(list.size()));
response.setContentType("text/plain; charset=gbk");
out.write(data.getBytes());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}

二、配置说明

  我们公司以及用户常用的分词器为 IK 分词器,其中它有一个对应的核心配置文件名为:IKAnalyzer.cfg.xml,具体内容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">custom/mydict.dic;custom/single_word_low_freq.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">custom/ext_stopword.dic</entry>
<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">location</entry>
<!--用户可以在这里配置远程扩展停止词字典-->
<entry key="remote_ext_stopwords">http://xxx.com/xxx.dic</entry>
</properties>

  热更新 IK 分词使用方法,目前该插件支持热更新 IK 分词,通过上文在 IK 配置文件中提到的如下配置

<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">location</entry>
<!--用户可以在这里配置远程扩展停止词字典-->
<entry key="remote_ext_stopwords">location</entry>

  其中 location 是指一个 url,比如 http://yoursite.com/getCustomDict,该请求只需满足以下两点即可完成分词热更新。
  该 http 请求需要返回两个头部(header)

  1. 一个是 Last-Modified,

  2. 一个是 ETag

  这两者都是字符串类型,只要有一个发生变化,该插件就会去抓取新的分词进而更新词库。
  该 http 请求返回的内容格式是一行一个分词,换行符用 \n 即可。

  满足上面两点要求就可以实现热更新分词了,不需要重启 ES 实例。还需要注意的是获取词典的url,必须支持head访问

下面自己做的访问远程扩展词典的web api 服务接口(这一步可以直接忽略,看第三个即可,这里只是想说明也可以使用下面这种方式)

[HttpHead, HttpGet, HttpPost]
public async Task<HttpResponseMessage> GetDictionary(string path)
{
var response = this.Request.CreateResponse(HttpStatusCode.OK);
var content = File.ReadAllText(path);
response.Content = new StringContent(content, Encoding.UTF8);
response.Headers.Age = TimeSpan.FromHours(1);
response.Headers.ETag = EntityTagHeaderValue.Parse($"\"{content.ToMD5()}\"");
return response;
}

三、Tomcat 服务器自动更新

 1、部署http服务

  在这使用 tomcat8 作为 web 容器,先下载一个 tomcat8.5.16,然后上传到某一台服务器上(192.168.80.100)。

  再执行以下命令

tar -zxvf apache-tomcat-8.5.16.tar.gz
cd apache-tomcat-8.5.16/webapp/ROOT
vim hot_ext.dic
智能移动机器人
vim hot_stopwords.dic
项目

  之后验证一下这个文件是否可以正常访问   http://192.168.80.100:8080/hot.dic

 2、修改ik插件的配置文件

  修改 IK 核心配置文件 IKAnalyzer.cfg.xml 中的配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">custom/mydict.dic;custom/single_word_low_freq.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">custom/ext_stopword.dic</entry>
<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">http://192.168.80.100:8080/hot_ext.dic</entry>
<!--用户可以在这里配置远程扩展停止词字典-->
<entry key="remote_ext_stopwords">http://192.168.80.100:8080/hot_stopwords.dic</entry>
</properties>

 3、验证

  重启es,会看到如下日志信息,说明远程的词典加载成功了。

  

  在浏览器中输入如下命令:http://localhost:9200/patent/_analyze?analyzer=ik_smart&text=智能移动机器人

  正常情况下会分出很多次,这次发现只有这一个词,不会被分词,说明刚才配置远程的词库生效了,那么我们再换一个:北京雾霾,正常情况下可能会被分成两个词:北京、雾霾,如果我直接修改 tomcat 下的 hot_ext.dic 词库文件,增加一个关键词:北京雾霾,文件保存之后,查看es的日志会看到如下日志信息:

  

  此时,再执行下面命令查看分词效果:http://localhost:9200/patent/_analyze?analyzer=ik_smart&text=北京雾霾

  结果就是只有一个词,不会被分词了。

  到这为止,可以实现动态添加自定义词库实现词库热更新。~~

  

ElasticStack系列之七 & IK自动热更新原理与实现的更多相关文章

  1. 【热更新IK词典】ElasticSearch IK 自动热更新原理与实现

    一.热更新原理 elasticsearch开启加载外部词典功功能后,会每60s间隔进行刷新字典.具体原理代码如下所示: public void loadDic(HttpServletRequest r ...

  2. ElasticSearch IK热词自动热更新原理与Golang实现

    热更新概述 ik分词器本身可以从配置文件加载扩张词库,也可以从远程HTTP服务器加载. 从本地加载,则需要重启ES生效,影响比较大.所以,一般我们都会把词库放在远程服务器上.这里主要有2种方式: 借助 ...

  3. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  4. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  5. 深入理解xLua热更新原理

    热更新简介 热更新是指在不需要重新编译打包游戏的情况下,在线更新游戏中的一些非核心代码和资源,比如活动运营和打补丁.热更新分为资源热更新和代码热更新两种,代码热更新实际上也是把代码当成资源的一种热更新 ...

  6. webpack与browser-sync热更新原理深度讲解

    本文首发于CSDN网站,下面的版本又经过进一步的修订.原文:webpack与browser-sync热更新原理深度讲解本文包含如下内容: webpack-hot-middleware EventSou ...

  7. Unity3D热更新之LuaFramework篇[08]--热更新原理及热更服务器搭建

    前言 前面铺垫了这么久,终于要开始写热更新了. Unity游戏热更新包含两个方面,一个是资源的更新,一个是脚本的更新. 资源更新是Unity本来就支持的,在各大平台也都能用.而脚本的热更新在iOS平台 ...

  8. 图解 Webpack 4.x 热更新原理

    图解 Webpack 4.x 热更新原理 Webpack HMR ️ module.hot & module.hot.accept if (module.hot) { module.hot.a ...

  9. 深入理解xLua基于IL代码注入的热更新原理

    目前大部分手游都会采用热更新来解决应用商店审核周期长,无法满足快节奏迭代的问题.另外热更新能够有效降低版本升级所需的资源大小,节省玩家的时间和流量,这也使其成为移动游戏的主流更新方式之一. 热更新可以 ...

随机推荐

  1. psp报告

    1.读材料回答问题 (1)回想一下你曾经对计算机专业的畅想.当初你是如何做出选择计算机专业的决定的?你认为过去接触到的课程是否符合你对计算机专业的期待,为什么?你觉得计算机是你喜欢的领域吗,它是你擅长 ...

  2. BugPhobia回顾篇章:团队Alpha阶段工作分析

    0x00:序言 1 universe, 9 planets, 204 countries,809 islands, 7 seas, and i had the privilege to meet yo ...

  3. 【转】 MATLAB下如何指定GPU资源

    [转] MATLAB下如何指定GPU资源 原文链接

  4. 四则运算App--大总结(已完成)

    1. 贡献分分配(20分) 欧泽波:14分,Android的学习,代码的编写,等等 杨洁华:1分,提供学习资料,框架的设计等等 赵泽嘉:3分,提供学习资料,框架的设计等等 林扬滨:2分,提供学习资料, ...

  5. Eclipse下使用Git

    安装Git 有的eclipse已经自带了Git了,就不用安装了. 如果,想重新安装,可以先卸载git,卸载 不同eclipse卸载不一样: 1.在Eclipse中依次点击菜单"Help&qu ...

  6. 通达OA工作流主要表的数据结构

    flow_run_prcs 流程执行明细 字段名称 类型 中文 说明 RUN_ID 数值 流水号(关键字段) 每发起一个工作流,即创建一个全局唯一的流水号 PRCS_ID 数值 执行步骤序号 USER ...

  7. area point sql

    UPDATE aa_info_area t,(SELECT areaId, areacenter,CONCAT('POINT(' ,substring_index(areacenter,',', 1) ...

  8. javascript易混淆的split()、splice()、slice()方法详解

    很多时候,一门语言总有那么些相似的方法,容易让人傻傻分不清楚,尤其在不经常用的时候.而本文主要简单总结了JavaScript中的关于字符串和数组中三个容易混淆的方法.旨在方便查阅,在容易混淆的时候有据 ...

  9. 在tensorflow环境下安装matplotlib

    在运行程序时,报错ImportError: No module named 'matplotlib',如图.经网上查询发现是没有安装matplotlib 因此记录一下在tensorflow环境下安装m ...

  10. Django 2.0 学习(19):Django 分页器

    Django 分页器 要使用Django实现分页功能,必须从Django中导入Paginator模块(painator - 分页器) views.py from django.shortcuts im ...