Elasticsearch近实时查询

Elasticsearch写入数据原理

是的发送到在这里插入图片描述

  • 客户端发起写入请求
  • 写入内存缓存区,并写入数据到translog buffer
  • 每隔1s数据从buffer中refresh到FileSystemCache中,生成segment文件,一旦生成segment文件,就能通过索引查询到了;
  • refresh完,memory buffer就清空了;
  • 每隔5s中,translog 从buffer flush到磁盘中;
  • 定期/定量从FileSystemCache中,结合translog内容flush index到磁盘中。做增量flush的。
    ES的近实时查询主要是因为从内存缓存区生成segment之间的延迟。

插入数据性能测试

Es提供了三种刷新策略

  • 插入即刷新
  • wait_for 1秒后刷新 时间可设置
  • 不执行刷新相关操作。此请求所做的更改将在请求返回后的某个时刻可见。

通过代码验证一下这三种策略

从数据库读取5000条数据,分别用不同的策略插入到ES中,查看响应的耗时
关键代码如下:

 IndexResponse response = esClient.index(i-> i.index(index)
 .id((String.valueOf(resident.getId()))).
                    document(resident).refresh(Refresh.True));

结论

立即刷新 耗时:545064毫秒
不刷新 耗时: 24583毫秒
wait_for 耗时 5473795毫秒

使用wait_for 比立即刷新还耗时,难以理解,希望有知道的大佬,可以指点一下
测试环境是在docke4.27.2 Elasticsearch 8.6.2

基于wait_for更耗时这里做一下说明

通过验证发现,插入每条数据,耗时差不多都是1秒多点儿。

2024-06-28 10:07:30.868  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1043
2024-06-28 10:07:31.936  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1044
2024-06-28 10:07:33.051  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1045
2024-06-28 10:07:34.155  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1046
2024-06-28 10:07:35.267  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1047
2024-06-28 10:07:36.367  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1048
2024-06-28 10:07:37.485  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1049
2024-06-28 10:07:38.611  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1050
2024-06-28 10:07:39.717  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1051
2024-06-28 10:07:40.832  INFO 22152 --- [           main] com.itcv.service.impl.EsServiceImpl      :ES中添加数据,数据已存在进行修改1052

1秒是个敏感词,会不会跟默认的刷新频率有关呢?

做以下验证

  1. 修改默认刷新频率
put /resident/_settings
{
   "index" : {
    "refresh_interval" : "2s"
  }
}
  1. 再做验证
2024-06-28 10:11:56.296  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1043
2024-06-28 10:11:58.364  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1044
2024-06-28 10:12:00.489  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1045
2024-06-28 10:12:02.611  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1046
2024-06-28 10:12:04.707  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1047
2024-06-28 10:12:06.814  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1048
2024-06-28 10:12:08.913  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1049
2024-06-28 10:12:11.012  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1050
2024-06-28 10:12:13.115  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1051
2024-06-28 10:12:15.228  INFO 23376 --- [           main] com.itcv.service.impl.EsServiceImpl      : 向ES中添加数据,数据已存在进行修改1052

耗时变成了两秒多

批量添加数据

   public boolean batchAddData(String index, List<Resident> residentList){
        try {
            BulkRequest.Builder br = new BulkRequest.Builder();
            for (Resident r : residentList){
                br.operations(op ->
                        op.index(idx ->
                                idx.index("resident")
                                        .id(String.valueOf(r.getId()))
                                        .document(r)
                        )

                ).refresh(Refresh.WaitFor);
            }

            BulkResponse result = esClient.bulk(br.build());
            
            log.info(JSONObject.toJSONString(result));

        } catch (Exception e) {
            log.error("向ES中添加数据失败",e);
        }

        return false;
    }

一次性批量写入5000条数据耗时 2435毫秒,批量写入性能是最高的

参考文章
https://longxiaofei.github.io/post/elasticsearch%E7%9A%84%E5%86%99%E5%85%A5%E6%B5%81%E7%A8%8B/

https://blog.csdn.net/weixin_42586723/article/details/120441348

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值