上一篇说到如果一个索引的mapping设置过了,想要修改type或analyzer,通常的做法是新建一个索引,重新设置mapping,再把数据同步过来。

那么如何实现零停机时间更新索引配置或迁移索引?这就需要用到索引的别名设置。

思路:

1、假设我们的索引是demo_v1,我们定义了一个别名demo,以后所有的操作都用别名demo操作。

2、现在索引demo_v1的mapping设置或者其他一些设置不满足我们的需求了,我们需要修改。新建一个索引demo_v2,同时设置好最新配置。

3、同步索引demo_v1的数据到索引demo_v2。直到同步完。

4、移除索引demo_v1的别名demo,同时设置索引demo_v2的别名为demo。

5、删除索引demo_v1。

6、迁移完成。以后如果还有设置变更,可以按照这个思路继续设置索引demo_v3、demo_v4……

接下来用一个例子说明实现过程,实际项目中我也是按这个思路做的。如果有一些命令操作看不懂,可参看上一篇文章。

1、创建索引demo_v1

> curl -XPUT 'localhost:9200/demo_v1'
{"acknowledged":true,"shards_acknowledged":true}%

2、给索引demo_v1添加几条数据

#给索引demo_v1添加了type=fruit的3条数据,每条数据用name和tag两个字段
> curl -XPOST 'localhost:9200/_bulk?pretty' -d'
{ "index" : { "_index" : "demo_v1", "_type" : "fruit", "_id" : "" }}
{ "name" : "苹果","tag":"苹果,水果,红富士"}
{ "create" : { "_index" : "demo_v1", "_type" : "fruit", "_id" : "" }}
{ "name" : "香蕉","tag":"香蕉,水果,海南,弯弯,小黄人"}
{ "index" : { "_index" : "demo_v1", "_type" : "fruit", "_id" : "" }}
{ "name" : "西瓜","tag":"西瓜,水果,圆形,绿,闰土"}
'
#返回
{
"took" : ,
"errors" : false,
"items" : [
{
"index" : {
"_index" : "demo_v1",
"_type" : "fruit",
"_id" : "",
"_version" : ,
"result" : "created",
"_shards" : {
"total" : ,
"successful" : ,
"failed" :
},
"created" : true,
"status" :
}
},
{
"create" : {
"_index" : "demo_v1",
"_type" : "fruit",
"_id" : "",
"_version" : ,
"result" : "created",
"_shards" : {
"total" : ,
"successful" : ,
"failed" :
},
"created" : true,
"status" :
}
},
{
"index" : {
"_index" : "demo_v1",
"_type" : "fruit",
"_id" : "",
"_version" : ,
"result" : "created",
"_shards" : {
"total" : ,
"successful" : ,
"failed" :
},
"created" : true,
"status" :
}
}
]
}

3、给索引demo_v1设置别名demo

#设置别名
> curl -XPUT 'localhost:9200/demo_v1/_alias/demo'
{"acknowledged":true}%

4、使用别名查看信息

#使用别名查看一下数据,是可以查询到的
> curl -XGET 'localhost:9200/demo/fruit/_search?pretty' #查看mapping
> curl -XGET 'localhost:9200/demo/fruit/_mapping?pretty'
#返回
{
"demo_v1" : {
"mappings" : {
"fruit" : {
"properties" : {
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" :
}
}
},
"tag" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" :
}
}
}
}
}
}
}
} #检索数据
> curl -XGET 'http://localhost:9200/demo/fruit/_search?pretty' -d '{
"query" : {
"term" : { "tag" : "水" }
}
}'
#返回
{
"took" : ,
"timed_out" : false,
"_shards" : {
"total" : ,
"successful" : ,
"failed" :
},
"hits" : {
"total" : ,
"max_score" : 0.28582606,
"hits" : [
{
"_index" : "demo_v1",
"_type" : "fruit",
"_id" : "",
"_score" : 0.28582606,
"_source" : {
"name" : "苹果",
"tag" : "苹果,水果,红富士"
}
},
{
"_index" : "demo_v1",
"_type" : "fruit",
"_id" : "",
"_score" : 0.27233246,
"_source" : {
"name" : "西瓜",
"tag" : "西瓜,水果,圆形,绿,闰土"
}
},
{
"_index" : "demo_v1",
"_type" : "fruit",
"_id" : "",
"_score" : 0.24257512,
"_source" : {
"name" : "香蕉",
"tag" : "香蕉,水果,海南,弯弯,小黄人"
}
}
]
}
}

数据因为先前创建索引时没有设置mapping,所以这些设置都是默认设置,分词器也默认标准分词器。

上面检索标签tag中带有“水”的数据,都查询出来了,说明默认分词器把“水果”这个词拆分了。

如果我们需要tag字段按照逗号分词,“水果”作为一个完整的词不拆分该怎么弄呢?

5、新建一个索引demo_v2,同时自定义逗号分词器,并把逗号分词器应用到tag字段上

#新建索引demo_v2
> curl -XPUT 'http://localhost:9200/demo_v2/' -d'{
"settings": {
"index": {
"analysis": {
"analyzer": {
"douhao_analyzer": {
"pattern": ",",
"type": "pattern"
}
}
},
"number_of_shards": ,
"number_of_replicas":
}
},
"mappings": {
"fruit": {
"properties": {
"name": {
"type": "text",
"index": "not_analyzed"
},
"tag": {
"type": "string",
"analyzer": "douhao_analyzer",
"search_analyzer": "douhao_analyzer"
}
}
}
}
}'
#返回
{"acknowledged":true,"shards_acknowledged":true}%

关于mapping设置及分词器设置可参见官方文档:

https://www.elastic.co/guide/en/elasticsearch/reference/5.3/mapping.html#mapping-type

https://www.elastic.co/guide/en/elasticsearch/reference/5.3/analysis-analyzers.html

6、同步索引demo_v1中的数据到demo_v2

我使用工具elasticdump同步数据,ElasticDump是一个ElasticSearch的数据导入导出开源工具包。

官方地址:https://github.com/taskrabbit/elasticsearch-dump

同步命令如下:

> elasticdump --input='http://localhost:9200/demo_v1'  --output='http://localhost:9200/demo_v2' --type=data
Wed, Jun :: GMT | starting dump
Wed, Jun :: GMT | got objects from source elasticsearch (offset: )
Wed, Jun :: GMT | sent objects to destination elasticsearch, wrote
Wed, Jun :: GMT | got objects from source elasticsearch (offset: )
Wed, Jun :: GMT | Total Writes:
Wed, Jun :: GMT | dump complete

7、验证一下demo_v2中的数据

#检索tag中包含“水”的数据,检索不到就是正常的
curl -XGET 'http://localhost:9200/demo_v2/fruit/_search?pretty' -d '{
"query" : {
"term" : { "tag" : "水" }
}
}' #检索tag中包含“水果”的数据,可以全部检索到
curl -XGET 'http://localhost:9200/demo_v2/fruit/_search?pretty' -d '{
"query" : {
"term" : { "tag" : "水果" }
}
}'

8、移除索引demo_v1的别名demo,同时设置索引demo_v2的别名为demo

curl -XPOST 'localhost:9200/_aliases?pretty' -d'{
"actions" : [
{ "remove" : { "index" : "demo_v1", "alias" : "demo" } },
{ "add" : { "index" : "demo_v2", "alias" : "demo" } }
]}'

9、删除索引demo_v1

curl -XDELETE 'localhost:9200/demo_v1'

至此整个迁移完成

ok!

学习用Node.js和Elasticsearch构建搜索引擎(7):零停机时间更新索引配置或迁移索引的更多相关文章

  1. 学习用Node.js和Elasticsearch构建搜索引擎(6):实际项目中常用命令使用记录

    1.检测集群是否健康. curl -XGET 'localhost:9200/_cat/health?v' #后面加一个v表示让输出内容表格显示表头 绿色表示一切正常,黄色表示所有的数据可用但是部分副 ...

  2. 学习用Node.js和Elasticsearch构建搜索引擎(1):了解并运行Elasticsearch

    1.学习Elasticsearch概述. 了解Elasticsearch是什么?能做什么?可以查一下elasticsearch.lucene等的相关介绍,另外也可以查查资料比较一下其它的搜索引擎sph ...

  3. 学习用Node.js和Elasticsearch构建搜索引擎(4): 构建Elasticsearch搜索引擎

    一.目标 使用node搭建一个知识库检索系统,要求词条平均检索速度必须在1s以内. 二.思路. 本人思路如下图. 橙色部分为我们要开发的内容, ES服务搭建(暂时用单节点测试,集群搭建以后再说), 三 ...

  4. 学习用Node.js和Elasticsearch构建搜索引擎(2):一些检索命令

    1.Elasticsearch搜索数据有两种方式. 一种方式是通过REST请求URI,发送搜索参数: 另一种是通过REST请求体,发送搜索参数.而请求体允许你包含更容易表达和可阅读的JSON格式.这个 ...

  5. 学习用Node.js和Elasticsearch构建搜索引擎(5):mac本机部署canal

    1.背景介绍 最近做的一个项目需要快速检索数据,经过商讨后采用了ElasticSearch作为快速检索数据引擎,但是数据如何同步到ES中是个问题,我们最开始计划了定时任务.mysql trigger等 ...

  6. 学习用Node.js和Elasticsearch构建搜索引擎(3):使用curl命令操作elasticsearch

    使用Elasticsearch不免要提到curl工具,curl是利用URL语法在命令行方式下工作的开源文件传输工具.官网地址:https://curl.haxx.se/ 因为elasticsearch ...

  7. Elasticsearch零停机时间更新索引配置或迁移索引

    本文介绍Elasticsearch零宕机时间更新索引配置映射内容的方法,包括字段类型.分词器.分片数等.方法原理就是,利用别名机制,给索引配置别名,所有应用程序都通过别名访问索引.重建索引,通过索引原 ...

  8. 如何用 Node.js 和 Elasticsearch 构建搜索引擎

    Elasticsearch 是一款开源的搜索引擎,由于其高性能和分布式系统架构而备受关注.本文将讨论其关键特性,并手把手教你如何用它创建 Node.js 搜索引擎. Elasticsearch 概述 ...

  9. 学习用node.js建立一个简单的web服务器

    一.建立简单的Web服务器涉及到Node.js的一些基本知识点: 1.请求模块 在Node.js中,系统提供了许多有用的模块(当然你也可以用JavaScript编写自己的模块,以后的章节我们将详细讲解 ...

随机推荐

  1. 纯手写SpringMVC框架,用注解实现springmvc过程

    闲话不多说,直接上代码! 1.第一步,首先搭建如下架构,其中,annotation中放置自己编写的注解,主要包括service controller qualifier RequestMapping ...

  2. Excel 斜线表头制作方法

    Excel 斜线表头制作方法

  3. 阿里云CentOS安装配置Python3.7及pip3

    一.安装Python3.7 安装依赖包 yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqli ...

  4. 如何提升JavaScript的任务效率?学会后教给你同事

    本文由云+社区发表 一.概述 JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事.前面的任务没做完,后面的任务只能等着.随着电脑计算能力的增强,尤其 ...

  5. 手把手在Ubuntu上面安装Docker

    一.环境准备 1.Ubuntu64位系统(目前docker仅支持64位系统) 2.官方支持的Ubuntu版本(1)Ubuntu Trusty 14.04(LTS)(2)Ubuntu Precise 1 ...

  6. [转]bitcoin: 通过 rpc 请求节点数据

    本文转自:https://laravel-china.org/index.php/articles/8919/bitcoin-requests-node-data-through-rpc 文章来自本人 ...

  7. 【转载】Sqlserver强制密码过期导致数据库登录失败

    Sqlserver在设置登录账户信息的时候,有个复选框信息会被默认勾上,即强制实施密码策略,默认勾选上的还有强制密码过期.如果勾上了这个强制密码过期后,则你的账户密码在一定时间登录后会提示Sqlser ...

  8. 【转载】C#常用数据库Sqlserver中DATEPART() 函数

    在Sqlserver数据库中,DATEPART() 函数用于返回日期/时间的单独部分,比如年.月.日.小时.分钟等等.DatePart()函数的语法为: DATEPART(datepart,date) ...

  9. 如何加入Microsoft Teams 技术社区

    作者:陈希章 时间:2018-11-19   概述 这个手册适合没有Office 365 账号的用户,你可以使用免费版立即开始使用Microsoft Teams,并且与微软的产品组专家,以及来自两岸三 ...

  10. EF(EntityFramework) 插入或更新数据报错

    报错信息:Store update, insert, or delete statement affected an unexpected number of rows (0). Entities m ...