我是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"}}}}}