日增TB级Elasticsearch索引数据存储别名优化

背景

随着业务量的增加,以及其他厂商数据的对接整个,我们的数据量从每天gb到pb的增加,实现了千亿级别的经济方案。

疼点:Elasticsearch在新建索引都需要指定shard分片数,当索引数据量增加不好扩容,业务代码需要调整等等;

索引别名

Elasticsearch中的API在针对特定索引时接受索引名称,并在适用时接受多个索引。索引别名API允许使用名称别名化索引,所有API都自动将别名转换为实际索引名称。别名也可以映射到多个索引,并且在指定别名时,别名将自动扩展为别名索引。别名还可以与在搜索和路由值时自动应用的过滤器相关联。别名不能与索引同名。

官方文档定义:

https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html

帮助我们解决什么样的问题?

1.数据增量横向扩展(我们每天的数据增量几十亿,以前老的架构每天需要建一个分区表,前期在别名使用不好的时候,评估3个月的数据存储量,建好索引,不太方便)。

2.每一个索引(三个月每天的索引的别名都使用同一个,查询方案,删除数据方案,主要是3个月以前的时间我们需要删除操作,使用java api的方式简直是没法做的)。

3.在一个集群中的数据非常好的对接到新的索引上面(我们在做数据迁移的时候,比如我们迁移率16年的数据到一个索引,17年的数据在一个索引,后面要做合并操作,有了别名就太方案)。

索引通过上面的方式很好的解决了我们数据扩容的问题,数据清除的问题。

demo实践

1.创建索引

  下面的代码我分别创建了 log2017,log2018,log2019三个索引,按照我们业务的划分,17,18,19年的数据会单独存放到对应的所有库中;

    private static Logger log = Logger.getLogger(LogIndex.class);
	//分别建log2017,log2018,log2019索引名
	//索引名称
	private static String indexName = "log2017";
	//索引类型
	private static String indexType = "t_log2017";
	
	/**
	 * 创建标签mapping
	 * @return
	 */
	public static XContentBuilder createMapping() {
		XContentBuilder mapping = null;
		try {
			mapping = XContentFactory.jsonBuilder().startObject()
					// properties 声明字段
					// string 类型 如果analyzed的话结果是text;如果not_analyzed的话结果是keyword
					.startObject("properties")
					.startObject("id").field("type", "string").field("index", "not_analyzed").endObject()
					.startObject("name").field("type", "string").field("index", "not_analyzed").endObject()
					.startObject("idCard").field("type", "string").field("index", "not_analyzed").endObject()
					.startObject("createtime").field("type", "date").field("format","yyyy-MM-dd HH:mm:ss").field("index", "not_analyzed").endObject()
					.startObject("LOCATION").field("type", "geo_point").endObject()
					.endObject().endObject();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mapping;
	}

2.分别倒入17,18,19三个索引库数据

/**
	 * 插入数据
	 * @throws Exception
	 */
	public static void insertTestDataEs() throws Exception {
		String[] idCards = {"522121198568523581","522121198568523582","522121198568523583"};
		List list = getDataList(size);
		BulkRequestBuilder builder =  trClient.prepareBulk();
		for(LogModel logModel : list) {
			XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject();
			int index = (int) (Math.random()*idCards.length);
			String idCard = idCards[index];
			xContentBuilder.field("id", logModel.getId());
			xContentBuilder.field("name", logModel.getName());
			xContentBuilder.field("idCard", idCard);
			xContentBuilder.field("createtime", logModel.getCreatetime());
			xContentBuilder.endObject();
			builder.add(trClient.prepareIndex(indexName, indexType).setSource(xContentBuilder));
		}
		BulkResponse bulkResponse = builder.execute().actionGet();
		System.out.println(bulkResponse);
	}

	/**
	 *  生成数据
	 * @param szie 
	 * @return
	 */
	public static List getDataList(int szie){
		List list = new ArrayList();
		String[] names = {"系统登录","数据查询","我的订单","我的消息","购买中心","信息查询","审批中心"};
 		for(int i = 0 ;i < szie ; i++) {
			String id = UUID.randomUUID().toString().replaceAll("-", "");
			int index = (int) (Math.random()*names.length);
			String name = names[index];
			String createtime = randomDate(startTime, endTime);
			System.out.println(id + " " + name + " " + createtime + " ");
			LogModel logModel = new LogModel();
			logModel.setId(id);
			logModel.setName(name);
			logModel.setCreatetime(createtime);
			list.add(logModel);
		}
		return list;
	}

	private static String randomDate(String beginDate,String endDate){
		try {
			 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			 Date start = format.parse(beginDate);
	         Date end = format.parse(endDate);
	         if(start.getTime() >= end.getTime()){return null;}
	         long date = random(start.getTime(),end.getTime());
	         return format.format(new Date(date));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private static long random(long begin, long end) {
		long rtn = begin + (long)(Math.random() * (end - begin));
		if(rtn == begin || rtn == end){
			return random(begin,end);
		}  
		return rtn;
	}

3.分别给三个索引添加别名

trClient.admin().indices().prepareAliases().addAlias("log2017", "logAll").execute().actionGet();
trClient.admin().indices().prepareAliases().addAlias("log2018", "logAll").execute().actionGet();
trClient.admin().indices().prepareAliases().addAlias("log2019", "logAll").execute().actionGet();

4.我们通过别名logAll查询数据

         我们通过idCard=522121198568523583查询三年的数据,查看下面的截图我们看见查询出来了,17/18/19年的数据,业务层面我们还使用geo_point帮助我们做地图分析,展示。

GET /logAll/_search
{
  "query": {
    "match": {
      "idCard":"522121198568523583"
    }
  }
}
{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 15,
    "successful": 15,
    "failed": 0
  },
  "hits": {
    "total": 22,
    "max_score": 1.1631508,
    "hits": [
      {
        "_index": "log2019",
        "_type": "t_log2019",
        "_id": "AWiD9SM5BXRto4xedAgI",
        "_score": 1.1631508,
        "_source": {
          "id": "c44e4f2d1d5b42af80cddc543dde4b08",
          "name": "系统登录",
          "idCard": "522121198568523583",
          "createtime": "2018-01-25 08:25:55"
        }
      },
      {
        "_index": "log2019",
        "_type": "t_log2019",
        "_id": "AWiD9UlBXgDYyKQPhMWV",
        "_score": 0.9808292,
        "_source": {
          "id": "3257512c2d2446b38643ec4584afe295",
          "name": "我的消息",
          "idCard": "522121198568523583",
          "createtime": "2018-05-18 05:34:53"
        }
      },
      {
        "_index": "log2019",
        "_type": "t_log2019",
        "_id": "AWiD9Y6EBXRto4xedAgS",
        "_score": 0.9808292,
        "_source": {
          "id": "bdc598477d454f73bdb5cc16e2fe34eb",
          "name": "购买中心",
          "idCard": "522121198568523583",
          "createtime": "2017-08-29 16:21:10"
        }
      },
      {
        "_index": "log2019",
        "_type": "t_log2019",
        "_id": "AWiD9OXMXgDYyKQPhMWL",
        "_score": 0.8266786,
        "_source": {
          "id": "1339d9ef87cd49aaa29359a021a7cb37",
          "name": "我的消息",
          "idCard": "522121198568523583",
          "createtime": "2019-11-13 10:11:06"
        }
      }
    ]
  }
}

详细代码见:https://github.com/444728248/elasticsearch-alias.git

你可能感兴趣的:(Elasticsearch,Elasticsearch,索引,别名,千亿数据查询)