elasticsearch 过期数据自动删除Java代码

本文介绍了一个用于Elasticsearch的索引清理工具,该工具能够根据索引名称中的日期标识,批量删除过期的索引。通过设定索引前缀及保留期限,可以自动搜索并删除指定日期之前的旧索引,适用于需要定期清理历史数据的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

es中的索引名为index-yyy-MM-dd 的形式的时候,可以根据直接日期判断来直接删除过期的整个索引


请尊重知识产权,博客原文地址http://blog.youkuaiyun.com/qq1032355091/article/details/79558496

package cn.bmkp.esCleaner;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.stats.IndexStats;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import lombok.extern.log4j.Log4j;

@Log4j
public class App {
	public static void main(String[] args) {
		String expiryDate = getDate(45);
		String indexPreffix = "order_process";
		TransportClient client;
		try {

			client = getClient();
			List<String> index = searchIndexNameByPreffix(indexPreffix, client, expiryDate);
			delete(client, index);
		} catch (UnknownHostException e1) {
			e1.printStackTrace();
		}

	}

	/**
	 * 删除整个索引
	 * 
	 * @param client
	 * @param index
	 * @user jiangqiang
	 * @date 2018年3月14日下午5:01:02
	 */
	public static void delete(TransportClient client, List<String> index) {
		IndicesAdminClient indicesAdminClient = client.admin().indices();
		for (String s : index) {

			DeleteIndexResponse response = indicesAdminClient.prepareDelete(s).execute().actionGet();
			log.info("删除 索引 " + s);
			log.info(response.isAcknowledged());
		}
	}

	/**
	 * 根据索引前缀名搜索出要过期的索引名
	 * 
	 * @param preffix
	 * @param client
	 * @param expiryDate 过期日期
	 * @return
	 * @user jiangqiang
	 * @date 2018年3月14日下午5:01:28
	 */
	public static List<String> searchIndexNameByPreffix(String preffix, TransportClient client, String expiryDate) {
		List<String> deleteIndex = new ArrayList<>();

		IndicesAdminClient indicesAdminClient = client.admin().indices();
		IndicesStatsResponse response = indicesAdminClient.prepareStats(preffix + "-*").all().get();
		Map<String, IndexStats> indices = response.getIndices();

		Set<String> keySet = indices.keySet();

		for (String key : keySet) {
			String d = key.substring(key.indexOf("-") + 1);
			int c = d.compareTo(expiryDate);
			if (c < 0) {
				log.info(d);
				deleteIndex.add(preffix + "-" + d);
			}
		}

		return deleteIndex;

	}

	/**
	 * 获取客户端连接
	 * 
	 * @return
	 * @throws UnknownHostException
	 * @user jiangqiang
	 * @date 2018年3月14日下午5:02:09
	 */
	public static TransportClient getClient() throws UnknownHostException {
		// 设置集群名称
		Settings settings = Settings.builder().put("cluster.name", "test-es").build();
		TransportClient client = new PreBuiltTransportClient(settings)
				.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("111.111.111.111"), 9300));
		return client;
	}

	/**
	 * 获取多少天以前的日期
	 * 
	 * @param num
	 * @return
	 * @user jiangqiang
	 * @date 2018年3月14日下午4:30:55
	 */
	public static String getDate(int num) {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.DATE, c.get(Calendar.DATE) - num);
		Date day = c.getTime();
		String str = new SimpleDateFormat("yyyy-MM-dd").format(day);
		log.info(str);
		return str;
	}

}

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>cn.bmkp</groupId>
	<artifactId>esCleaner</artifactId>
	<version>0.1</version>
	<packaging>jar</packaging>

	<name>esCleaner</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.elasticsearch.client</groupId>
			<artifactId>transport</artifactId>
			<version>5.6.4</version>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.16.18</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.2</version>
		</dependency>
	</dependencies>
	<build>
		<sourceDirectory>src/main/java</sourceDirectory>
		<testSourceDirectory>src/test/java</testSourceDirectory>

		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>2.4.1</version>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
						<configuration>
							<transformers>
								<transformer
									implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
									<mainClass>cn.bmkp.esCleaner.App</mainClass>
								</transformer>
							</transformers>
						</configuration>
					</execution>
				</executions>
			</plugin>

			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>exec-maven-plugin</artifactId>
				<version>1.2.1</version>
				<executions>
					<execution>
						<goals>
							<goal>exec</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<executable>java</executable>
					<includeProjectDependencies>true</includeProjectDependencies>
					<includePluginDependencies>false</includePluginDependencies>
					<classpathScope>compile</classpathScope>
					<mainClass>cn.bmkp.esCleaner.App</mainClass>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

ss

### ### 实现流程 在实现文章联想词搜索功能时,结合 **Elasticsearch** 和 **Redis** 可以充分发挥两者的优势:Elasticsearch 用于强大的全文搜索和分词能力,而 Redis 则作为缓存层提升高频查询的响应速度。整个系统的工作流程如下: 1. 用户在 APP 中输入关键词(如“机器”)。 2. 后端服务接收请求后,首先检查 Redis 缓存中是否存在该关键词的联想结果。 3. 如果存在,则直接返回 Redis 缓存的数据;否则向 Elasticsearch 发起查询。 4. Elasticsearch 基于倒排索引进行快速检索,返回相关文章标题或内容片段作为联想词建议。 5. 将 Elasticsearch 的查询结果写入 Redis 缓存一段时间,供后续相同请求使用。 ![架构图](https://via.placeholder.com/600x300?text=Elasticsearch+%2B+Redis+Search+Suggestion+Architecture) ### ### Java 示例代码 以下是一个基于 Spring Boot 框架整合 Elasticsearch 与 Redis 的示例代码: #### 1. Maven 依赖配置 ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level</artifactId> <version>7.17.0</version> </dependency> </dependencies> ``` #### 2. 配置 RedisTemplate 与 Elasticsearch 客户端 ```java @Configuration public class AppConfig { @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, String> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } @Bean public RestHighLevelClient elasticsearchClient() { return new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http") ) ); } } ``` #### 3. 联想词搜索服务类 ```java @Service public class SuggestionService { private final RedisTemplate<String, String> redisTemplate; private final RestHighLevelClient esClient; public SuggestionService(RedisTemplate<String, String> redisTemplate, RestHighLevelClient esClient) { this.redisTemplate = redisTemplate; this.esClient = esClient; } public List<String> getSuggestions(String keyword) throws IOException { String cacheKey = "suggestion:" + keyword; String cachedJson = (String) redisTemplate.opsForValue().get(cacheKey); if (cachedJson != null) { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(cachedJson, new TypeReference<List<String>>() {}); } // 构造 Elasticsearch 查询 SearchRequest searchRequest = new SearchRequest("articles"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(keyword, "title^3", "content") .type(MatchQuery.Type.PHRASE_PREFIX); // 使用短语前缀匹配实现联想 sourceBuilder.query(queryBuilder).size(10); searchRequest.source(sourceBuilder); // 执行查询 SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT); List<String> results = Arrays.stream(response.getHits().getHits()) .map(hit -> hit.getSourceAsMap().get("title").toString()) .collect(Collectors.toList()); // 写入 Redis 缓存 ObjectMapper mapper = new ObjectMapper(); String resultJson = mapper.writeValueAsString(results); redisTemplate.opsForValue().set(cacheKey, resultJson, 5, TimeUnit.MINUTES); return results; } } ``` ### ### 面试知识点总结 #### **Elasticsearch 相关** 1. **倒排索引原理**:Elasticsearch 使用倒排索引将文档中的词汇映射到包含该词汇的文档列表,从而加速全文检索过程[^1]。 2. **分词器(Analyzer)**:不同 Analyzer 对搜索效果有直接影响,例如 `standard`、`ik`、`english` 等,选择合适的 Analyzer 是提高搜索质量的关键[^1]。 3. **Query DSL**:掌握常用查询类型如 `match`, `multi_match`, `term`, `bool` 等,能构建复杂查询条件以满足多样化的搜索需求。 4. **聚合查询(Aggregation)**:用于统计和分析数据,如获取某字段的平均值、最大值、唯一值数量等。 5. **性能优化技巧**:包括合理设置索引、字段类型选择、分片策略、副本控制等,可以显著提升查询效率。 6. **近实时搜索特性**:Elasticsearch 默认每隔一秒刷新一次索引,称为 refresh_interval,它决定了数据从写入到可被搜索的时间间隔。 7. **集群与节点角色**:主节点负责管理集群状态,数据节点存储数据并执行操作,协调节点处理客户端请求并将任务分发给其他节点。 #### **Redis 相关** 1. **五大数据结构**:String、Hash、List、Set、Sorted Set,适用于不同的业务场景,如缓存字符串、对象、队列、集合等[^2]。 2. **持久化机制**:RDB 快照适合备份和灾难恢复,AOF 更适合防止数据丢失,两者结合使用效果更佳[^2]。 3. **缓存穿透、击穿、雪崩**:可通过布隆过滤器避免非法请求、互斥锁防止并发重建缓存、随机过期时间分散压力等方式解决。 4. **Redis 过期策略与淘汰机制**:默认使用惰性删除+定期删除策略,淘汰机制包括 LFU、LRU、TTL 等。 5. **Redis 分布式锁实现**:RedLock 算法通过多个独立实例达成一致性共识,适用于分布式系统中资源竞争的控制[^2]。 6. **Pipeline 与 Lua 脚本**:Pipeline 提高吞吐量,Lua 脚本保证操作的原子性和一致性。 7. **Redis 高可用方案**:主从复制提供读写分离,哨兵模式实现自动故障转移,Cluster 集群支持水平扩展[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值