我是es小白中的小白,遇到个问题也不知道为啥,反正是解决了,各位路过的大哥,有知道原因的还望留言指教,在此感谢!
我先讲一下这个问题的背景,我们线上有一套es,版本是7,想把数据导出来,导入到es6中,具体版本是6.8.23,因为es7和es6索引有些差别,开始创建索引的时候没成功,后来创建成功了,但是发现把数据导入到新创建的索引中,运行非常缓慢,导入程序是我用python写的脚本。
我是怎么发现慢的呢,因为除了这套数据(数据A),我还有一套别的数据(数据B),从单条数据体量上讲,数据B要比数据A大很多,索引B也要比索引A复杂很多,但是数据B的导入速度比数据A快很多,这明显不合理。
我用100万数据做并发导入测试,首先把100万数据切割成100份,然后用3个线程并发处理,每个线程单独处理一个文件。数据B导入100万13分钟左右,数据A导入100万需要一个小时左右,差距十分明显。
通过多次尝试及对比发现,数据B的索引与数据A的索引结构不同,把结构修改了导入速度就提升上来了,3线程能达到5000QPS左右(我是windows笔记本,导入使用的docker环境也在本机中)。
下面我介绍下具体是怎么修改的
1. 首先介绍索引无法创建成功的样例
es7中索引是这样的,但在es6.8.23中无法创建成功,原因是缺少一层
{
"settings": {
"number_of_shards": 30,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"XXX": {
"type": "keyword"
},
"XXX": {
"index": False,
"type": "keyword"
},
"XXX": {
"index": False,
"type": "keyword"
}
}
}
}
2. 要这样才能创建成功
注意properties上边的doc,这样索引能创建成功,数据也能插入进去,但是非常慢
{
"index": {
"refresh_interval": "8s",
"translog": {
"durability": "async",
"sync_interval": "10s"
},
"unassigned": {
"node_left": {
"delayed_timeout": "1m"
}
}
},
"settings": {
"number_of_shards": 16,
"number_of_replicas": 0
},
"mappings": {
"doc": {
"properties": {
"XXX": {
"type": "keyword"
},
"XXX": {
"index": False,
"type": "keyword"
},
"XXX": {
"index": False,
"type": "keyword"
}
}
}
}
}
3. 要这样插入才快
注意,index的内容放到了setting中,index中的其它配置,是我做的优化,但并不能显著提高插入性能,只有把index放入到setting中之后,插入性能才得到显著提升。为什么我也不知道,有清楚的留言指教,感谢!
bodySet = {
"settings": {
"index": {
"refresh_interval": "8s",
"translog": {
"durability": "async",
"sync_interval": "10s"
},
"number_of_shards": "16",
"number_of_replicas": "0",
"unassigned": {
"node_left": {
"delayed_timeout": "1m"
}
}
}
},
"mappings": {
"doc": {
"properties": {
"XXX": {
"type": "keyword"
},
"XXX": {
"index": False,
"type": "keyword"
},
"XXX": {
"index": False,
"type": "keyword"
}
}
}
}
}