最近解决了一个因索引导致ES写入性能很低的问题,记录如下:
问题描述:
机器配置8C/16G 5个数据节点,照理来说性能应该不错,但是写入速度TPS只有4000左右,之后我们对写入进行bulk批量写入,虽然整体写入数据性能有所提高,但是ES的TPS依然不高,另外隔一段时间就发现ES的写入队列比较长,拒绝请求也非常高,查看Es日常日志和慢日志发现在请求过程中存在大量如下错误:

failed to execute bulk item (index) BulkShardRequest [[xxxxx][0]] containing [index {[xxxxx][xxx][23116134695937D23BD8C5290D68CAB331C81325E2A5cn-north-11635770966001], source[n/a, actual length: [44.5kb], max length: 2kb]}]
java.lang.IllegalArgumentException: Document contains at least one immense term in field="syncData" (whose UTF8 encoding is longer than the max length 32766), all of which were skipped.  Please correct the analyzer to not produce such terms.  The prefix of the first immense term is: '[123, 34, 111, 114, 100, 101, 114, 66, 97, 115, 101, 73, 110, 102, 111, 34, 58, 123, 34, 111, 114, 100, 101, 114, 84, 121, 112, 101, 34, 58]...', original message: bytes can be at most 32766 in length; 

意思是syncData这个字段最大长度是32766b,但是实际长度超过了这个限制,所以需要更换分词器。但是这个限制是谁限制的呢?原来这个限制来源于字段类型keyword,keyword长用来设置电子邮箱、地址、姓名、邮政编码和标签等数据,不进行分词,但是可以被用来过滤、排序和聚合,但是长度有所限制。解决这个问题有两种,一种是忽略超长数据,另外一种是更改字段属性。
方法1:

PUT xxx_index
	{
		"mappings": {
			"xxx_type": {
				"properties": {
					"syncData": {
						"type": "keyword",
						"ignore_above": 32766
					}
				}
			}
		}
	}

方法2:
使用text类型替换,text 数据类型被用来索引长文本,多用于全文扫描类型,如果不想进行分词扫描,可以关闭分词。

{
	"syncData":{
		"type":"text",
		"index":false
	}
}

我这里是通过方法2解决的,修改之后,妈妈再也不担心我的写入性能了。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐