我有点怀疑你在刷屏

elasticsearch的数据插入时reindex误区?

Elasticsearch | 作者 miniuig | 发布于2020年01月09日 | 阅读数:3891

elasticsearch版本5.6
用的是python的elasticsearch模块
最近刚接触es,需求优化脚本并做大无缝衔接。脚本是将mysql的数据跑到es中,为了不影响数据的使用,我是在原有索引存在的情况下新建索引,然后把数据跑到新索引上,跑完以后删除原索引,然后通过reindex迁移数据至原索引名,最后删除创建的新索引
 
在整个过程中遇到两个问题:
1.reindex以后,数据量跟新索引下的数据量有时候不一致,会少一点几条或者几十条,猜想是因为数据数据还在写入未写完时,reindex就已经开始导入文档,因此会导致少量数据遗漏
2.最重要的问题!我的reindex的目标索引的映射和新索引原映射不一致!我一直以为reindex不仅会拷贝数据,还会把数据的映射一起复制过来,我发现很多字段的type不一样,最重要的是搜索补全字段不再补全了
新索引映射:
微信图片_20200109095603.png

reindex目标索引映射
微信图片_20200109095614.png
class Command(BaseCommand):
def handle(self, *args, **options):
print('开始')
self.options = options
start_time = time()
self.create_index() # 创建es索引
print('*' * 30)
self.insert_data() # 插入数据
# self.change_index() # todo 切换索引, 删除当前索引
end_time = time()
print('耗时%f' % (end_time - start_time))

def change_index(self):
"""
切换es索引
:return:
"""
es.indices.delete(index=artist_index, ignore=404)
body = {
"source": {
"index": before_artist_index
},
"dest": {
"index": artist_index
}
}
result = es.reindex(body)
print(result)
es.indices.delete(index=before_artist_index, ignore=404)

def create_index(self):
"""
插入数据前创建对应的index
"""
print('开始建立index')
es.indices.delete(index=before_artist_index, ignore=404)
index_mappings = {
'mappings': {
artist_type: ARTIST_MAPPING
}
}
es.indices.create(index=before_artist_index, body=index_mappings)
print('index建立成功')

def insert_data(self):
"""
从mysql取数据,组装好后批量插入到elasticsearch
"""
pass
已邀请:

caizhongao

赞同来自: zhangdi

可以把新索引建别名。别名和老索引一样,就不用迁数据了吧

God_lockin

赞同来自: miniuig

别名这个我们一般会用统一的对外名称+带时间戳的索引,比如,我的index叫my_test
 
先建一个my_test_20200101,给他加两个别名,my_test_current_reader和my_test_current_writer
 
在写数据的地方统一用my_test_current_writer,读数据的地方统一用my_test_current_reader
 
由于ES的索引操作在一条命令里面是原子操作,我们可以在读写服务都不停机的条件下做索引切换
 
再建一个新索引,作出一些我们需要的settings/mapping之类的改动,my_test_20200102
 
然后用aliases api从my_test_20200101把两个别名原子操作迁移到my_test_20200102

God_lockin

赞同来自:

reindex你可以简单理解为scroll+bulkinsert,ES不会帮你复制source的mapping、settings,只会按默认设置自动做映射
 
建议是先建好新的索引再做reindex

要回复问题请先登录注册