Elasticsearch索引刷新延迟问题解决方案
Elasticsearch索引刷新延迟问题解决方案
问题描述
在EsMaterialController中,当调用save方法保存素材后,立即调用page方法查询,无法查询到刚刚保存的数据。这是因为Elasticsearch的索引刷新机制导致的延迟问题。
原因分析
Elasticsearch为了提高写入性能,采用了近实时(Near Real Time,NRT)搜索机制:
当数据写入ES时,首先写入内存缓冲区
默认情况下,ES每隔1秒(可配置)将缓冲区数据刷新到文件系统缓存,此时数据才可被搜索
这个刷新间隔导致了写入操作与查询操作之间的延迟
解决方案
方案1:装饰器模式增强服务(推荐)
通过装饰器模式增强EsMaterialService,在增删改操作后主动刷新索引:
创建EsRefreshService接口及实现类,提供刷新索引的方法
创建EsMaterialServiceWithRefreshImpl类,使用@Primary注解使其成为首选实现
在增删改操作后调用刷新方法
优点:
对业务代码无侵入
实现了关注点分离,便于维护
可以统一处理所有需要刷新索引的场景
实现类:
EsRefreshService – 提供刷新索引的接口
EsRefreshServiceImpl – 实现刷新索引的具体逻辑
EsClientAdapter – 封装与ES客户端的交互
EsMaterialServiceWithRefreshImpl – 装饰器模式增强服务
方案2:控制器中等待刷新
在控制器方法中,保存数据后主动等待一段时间,确保ES索引刷新:
@PostMapping(value = “/save”)
public R<String> saveMaterial(@Valid @RequestBody MaterialParamDTO paramDTO) {
// 保存素材
String materialId = esMaterialService.save(paramDTO);
// 等待ES索引刷新
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return R.ok(materialId);
}
优点:实现简单
缺点:
- 阻塞请求处理线程
- 硬编码等待时间,不够灵活
- 每个需要处理的地方都要添加等待代码
方案3:调整ES刷新间隔
通过配置调整ES索引的刷新间隔:
PUT /material_data/_settings
{
“index”: {
“refresh_interval”: “500ms”
}
}
优点:全局生效,无需修改代码
缺点:
- 可能影响ES写入性能
- 需要管理员权限
- 不适合所有索引
方案4:客户端重试机制
在客户端实现重试机制,如果查询不到刚保存的数据,则等待一段时间后重试:
// 前端代码示例
async function saveAndQueryMaterial(material) {
const id = await saveMaterial(material);
let retries = 3;
while (retries > 0) {
const result = await queryMaterial(id);
if (result) return result;
await new Promise(resolve => setTimeout(resolve, 500));
retries–;
}
throw new Error(‘保存成功但查询失败’);
}
优点:对服务端无侵入
缺点:增加前端复杂度
最佳实践建议
首选方案1:使用装饰器模式增强服务,在增删改操作后主动刷新索引
对于性能要求不高的场景,可以考虑方案2或方案3
对于特定业务场景,可以结合方案1和方案4
在批量操作后,一定要主动刷新索引
实现细节
装饰器模式实现
EsRefreshService接口:
refreshMaterialIndex() – 刷新素材索引
refreshIndex(String indexName) – 刷新指定索引
EsClientAdapter类:
封装与ES客户端的交互
提供refreshIndex方法
EsMaterialServiceWithRefreshImpl类:
使用@Primary注解
在增删改操作后调用refreshMaterialIndex方法
配置要点
确保ES客户端依赖正确配置
确保索引名称配置正确
注意异常处理,刷新失败不应影响业务流程
测试验证
单元测试:EsMaterialControllerTest
集成测试:EsMaterialServiceTest
性能测试:测试不同方案下的响应时间和资源消耗
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
7. 本站有不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
66源码网 » Elasticsearch索引刷新延迟问题解决方案