es-reindex

Elasticsearch索引管理-reindex重建索引

2017年08月29日 18:27:08 阅读数:5666 标签: elasticsearch 索引 重建 更多

个人分类: elasticsearch

所属专栏: elasticsearch

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/loveyaqin1990/article/details/77684599

一个field的设置是不能被修改的,如果要修改一个field,那么应该重新按照新的mapping,建立一个index,然后将数据批量查询出来,重新用bulk api写入新index中。
批量查询的时候,建议采用scroll api,并且采用多线程并发的方式来reindex数据,每次scroll就查询指定日期的一段数据,交给一个线程即可。

具体操作步骤:

(1)一开始,依靠dynamic mapping,插入数据,但是不小心有些数据是2017-01-01这种日期格式的,所以ES自动将这种格式的field映射为了date类型,实际上他应该是string类型。这时候我们插入hello这类词语就会报错,因为他已经默认是date类型了

 
  1. PUT /my_index/my_type/3

  2. {

  3. "title" : "2017-01-01"

  4. }

GET my_index/_mapping/my_type
结果

 
  1. {

  2. "my_index": {

  3. "mappings": {

  4. "my_type": {

  5. "properties": {

  6. "title": {

  7. "type": "date"

  8. }

  9. }

  10. }

  11. }

  12. }

  13. }

结果表明,ES的dynamic mapping自动将日志格式的字符串给映射为了date类型

(2)当我们向索引中加入string类型的title值的时候就会报错

 
  1. PUT /my_index/my_type/4

  2. {

  3. "title" : "hello world"

  4. }

返回结果

 
  1. {

  2. "error": {

  3. "root_cause": [

  4. {

  5. "type": "mapper_parsing_exception",

  6. "reason": "failed to parse [title]"

  7. }

  8. ],

  9. "type": "mapper_parsing_exception",

  10. "reason": "failed to parse [title]",

  11. "caused_by": {

  12. "type": "illegal_argument_exception",

  13. "reason": "Invalid format: \"hello world\""

  14. }

  15. },

  16. "status": 400

  17. }

(3)如果此时想修改title的类型,那么是不可能的

 
  1. PUT /my_index/_mapping/my_type

  2. {

  3. "properties": {

  4. "title" : {

  5. "type": "text"

  6. }

  7. }

  8. }

返回结果

 
  1. {

  2. "error": {

  3. "root_cause": [

  4. {

  5. "type": "illegal_argument_exception",

  6. "reason": "mapper [title] of different type, current_type [date], merged_type [text]"

  7. }

  8. ],

  9. "type": "illegal_argument_exception",

  10. "reason": "mapper [title] of different type, current_type [date], merged_type [text]"

  11. },

  12. "status": 400

  13. }

结果表明:field一旦被创建就不可能被更改类型。

(4)此时,唯一办法就是进行reindex,也就是说,重新建立一个新的索引,将旧索引的数据查询出来,再导入新索引。

(5)如果说旧索引的名字是old_index,新索引的名字是new_index,终端java应用,已经在使用old_index在操作了,难道还要去停止线上的java应用,修改用户正在使用的index为new_index,再重启java服务吗?这个过程中,一定会导致用户正在浏览,但是突然就无法访问了的情况。

(6)所以说,给java应用一个别名,这个别名是指向旧索引的,java应用先用着,java应用先用good_index alias来操作,此时实际指向的是旧的index(my_index)

PUT /my_index/_alias/good_index

此时我们去查good_index

 
  1. GET /good_index/_search

  2. {

  3. "query": {

  4. "match_all": {}

  5. }

  6. }

返回结果:

 
  1. {

  2. "took": 4,

  3. "timed_out": false,

  4. "_shards": {

  5. "total": 5,

  6. "successful": 5,

  7. "failed": 0

  8. },

  9. "hits": {

  10. "total": 1,

  11. "max_score": 1,

  12. "hits": [

  13. {

  14. "_index": "my_index",

  15. "_type": "my_type",

  16. "_id": "3",

  17. "_score": 1,

  18. "_source": {

  19. "title": "2017-01-01"

  20. }

  21. }

  22. ]

  23. }

  24. }

结果表明:现在good_index就是my_index的别名,good_index指向了my_index。

(7)新建一个index,调整其title的类型为string

 
  1. PUT /my_index_new

  2. {

  3. "mappings": {

  4. "my_type" : {

  5. "properties": {

  6. "title" : {

  7. "type": "string"

  8. }

  9. }

  10. }

  11. }

  12. }

(8)使用scroll api将数据批量查询出来

 
  1. GET /my_index/_search?scroll=1m

  2. {

  3. "query": {

  4. "match_all": {}

  5. },

  6. "sort": ["_doc"],

  7. "size": 1

  8. }

这里size:1,是因为我们没有那么多的数据。所以就模拟一下,真实场景可能成千上万,看自己的数据量了。

返回结果

 
  1. {

  2. "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAASFVFnJyRk9uQ0IzUndxS094YUlleUxuVXcAAAAAAAEhVhZyckZPbkNCM1J3cUtPeGFJZXlMblV3AAAAAAABIVcWcnJGT25DQjNSd3FLT3hhSWV5TG5VdwAAAAAAASFYFnJyRk9uQ0IzUndxS094YUlleUxuVXcAAAAAAAEhWRZyckZPbkNCM1J3cUtPeGFJZXlMblV3",

  3. "took": 2,

  4. "timed_out": false,

  5. "_shards": {

  6. "total": 5,

  7. "successful": 5,

  8. "failed": 0

  9. },

  10. "hits": {

  11. "total": 1,

  12. "max_score": null,

  13. "hits": [

  14. {

  15. "_index": "my_index",

  16. "_type": "my_type",

  17. "_id": "3",

  18. "_score": null,

  19. "_source": {

  20. "title": "2017-01-01"

  21. },

  22. "sort": [

  23. 0

  24. ]

  25. }

  26. ]

  27. }

  28. }

(9)采用bulk api将scroll查出来的一批数据,批量写入新索引

 
  1. POST /_bulk

  2. {"index": {"_index" : "my_index_new", "_type" : "my_type", "_id" : "3"}}

  3. {"title" : "2017-01-01"}

(10)反复循环8~9次,查询一批又一批的数据出来,采取bulk api将每一批数据批量写入新索引

(11)将goods_index alias切换到my_index_new上去,java应用会直接通过index别名使用心得索引中的数据,java应用程序不需要停机,零提交,高可用

 
  1. POST /_aliases

  2. {

  3. "actions" : [

  4. {"remove" : {"index" : "my_index", "alias" : "goods_index"}},

  5. {"add" : {"index" : "my_index_new", "alias" : "goods_index"}}

  6. ]

  7. }

(12)直接通过goods_index别名来查询是否ok
GET /goods_index/my_type/_search

返回结果

 
  1. {

  2. "took": 1,

  3. "timed_out": false,

  4. "_shards": {

  5. "total": 5,

  6. "successful": 5,

  7. "failed": 0

  8. },

  9. "hits": {

  10. "total": 1,

  11. "max_score": 1,

  12. "hits": [

  13. {

  14. "_index": "my_index_new",

  15. "_type": "my_type",

  16. "_id": "3",

  17. "_score": 1,

  18. "_source": {

  19. "title": "2017-01-01"

  20. }

  21. }

  22. ]

  23. }

  24. }

大功告成!!!


 

猜你喜欢

转载自blog.csdn.net/apriaaaa/article/details/82593183
es