es sharding 文档数量超过最大限制,写入失败的4种解决方案

es 插入数据的时候报错
failure in bulk execution:
[0]: index [leopard_user.driver_work_detail_record], type [detail_info], id [xxx], message [ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=number of documents in the index cannot exceed 2147483519]]],

超过了2^31次方

解决方案:
方案一
重新创建一个index 增大sharding 数量, reindex

新建一个索引

PUT xxxx_record_new
{
  "mappings": {
            "detail_info": {
                "properties": {
                    "carId": {
                        "type": "long"
                    }、、、
  "settings": {
    "number_of_shards": 16,
    "number_of_routing_shards":16,
    "number_of_replicas": 0,
    "refresh_interval": "-1",
    "translog": {
          "flush_threshold_size": "2048mb",
          "durability": "async"
        } 
  }

副本数量和refresh_interval 等reindex 以后再更改

POST _reindex
{
  "source": {
    "index": "xxxxx_record"
    , 
    "size": 10000
  },
  "dest": {
    "index": "xxxx_record_new",
    "op_type": "create"
  }
}

reindex过程中 源端索引不能有写入 避免数据不一致

方案二
通过别名的方式,
新建一个索引, 然后给旧的索引和新的索引 创建同一个别名, 并且允许写新的索引, 这样程序只需要把旧的索引名字改成新的别名,就可以实现, 查询旧的索引和新的索引, 只写新的索引。

  POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "xxxx_record", 旧索引名字
        "alias": "xxxx_record_new",
        "is_write_index": false
      }
    },
    {
      "add": {
        "index": "xxx_record_1",   新索引名字
        "alias": "xxx_record_new",
        "is_write_index": true
      }
    }
  ]
}  

方案三、
清理历史数据

POST /xxxx_record/_delete_by_query?&slices=8&wait_for_completion=false&conflicts=proceed
{
	"query":{
		"bool":{
			"must":[
				{"range":{"gmt_create":{"gte":0,"lte": 1641028459000}}}
			]
		    
		}
	}
}
GET  /xxxx_record/_search
{
  "query":{
    "bool":{
      "must":[
        {"range":{"gmt_create":{"gte":0,"lte": 1641028459000}}}
      ]
        
    }
  }
}

看看命中多少数据

再删除过程中,如果删除一年的数据大概1.3亿, 大概删除半个小时以后,后台删除进程会退出,并且无报错,数据无法删除

控制每次只删除一天的数据可以删除成功,用的是es6.7版本,估计是数据超过了内存限制。

POST xxxx_record/_delete_by_query
{
  "query":{
    "range": {
      "gmt_create": {
        "gte": xxx,
        "lte": xx
      }
    }
  }
}

清理数据以后,merge是异步的,可能删除数据以后,不会立即释放doc 数量。 还是需要merge

方案四
直接forcemerge 清理已经标记删除的数据。

POST /索引名/_forcemerge

如果只merge 超过 index.merge.policy.expunge_deletes_allowed(默认10)配置的segment
添加参数

POST /索引名/_forcemerge?only_expunge_deletes=true

放入后台执行
POST /索引名/_forcemerge?only_expunge_deletes=true&wait_for_completion=false

把segment合并到 max_num_segments个segment
比如合并成一个segment
POST /.ds-my-data-stream-2099.03.07-000001/_forcemerge?max_num_segments=1

调大max_num_segments 可以增加merge速度。

使用这个命令POST /索引名/_forcemerge?only_expunge_deletes=true&wait_for_completion=false
1.5T的数据大概用了7个小时merge完毕

你可能感兴趣的:(elasticsearch,elasticsearch,大数据,搜索引擎)