Spring Boot + Elasticsearch 实现索引批量写入
在使用Eleasticsearch进行索引维护的过程中,如果你的应用场景需要频繁的大批量的索引写入,再使用上篇中提到的维护方法的话显然效率是低下的,此时推荐使用bulkIndex来提升效率。批写入数据块的大小取决于你的数据集及集群的配置。
下面我们以Spring Boot结合Elasticsearch创建一个示例项目,从基本的pom配置开始
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
application.properties配置
#elasticsearch config
spring.data.elasticsearch.cluster-name:elasticsearch
spring.data.elasticsearch.cluster-nodes:192.168.1.105:9300
#application config
server.port=8080
spring.application.name=esp-app
我们需要定义域的实体和一个Spring data的基本的CRUD支持库类。用id注释定义标识符字段,如果你没有指定ID字段,Elasticsearch不能索引你的文件。同时需要指定索引名称类型,@Document注解也有助于我们设置分片和副本数量。
@Data
@Document(indexName = "carIndex", type = "carType", shards = 1, replicas = 0)
public class Car implements Serializable {
/**
* serialVersionUID:
* @since JDK 1.6
*/
private static final long serialVersionUID = 1L;
@Id
private Long id;
private String brand;
private String model;
private BigDecimal amount;
public Car(Long id, String brand, String model, BigDecimal amount) {
this.id = id;
this.brand = brand;
this.model = model;
this.amount = amount;
}
}
接着定义一个IndexService并使用bulk请求来处理索引,操作前首先要判断索引是否存在,以免出现异常。为了更好的掌握Java API,这里采用了不同于上篇中ElasticSearchRepository的ElasticSearchTemplate工具集,相对来讲功能更加丰富。
@Service
public class IndexerService {
private static final String CAR_INDEX_NAME = "car_index";
private static final String CAR_INDEX_TYPE = "car_type";
@Autowired
ElasticsearchTemplate elasticsearchTemplate;
public long bulkIndex() throws Exception {
int counter = 0;
try {
//判断索引是否存在
if (!elasticsearchTemplate.indexExists(CAR_INDEX_NAME)) {
elasticsearchTemplate.createIndex(CAR_INDEX_NAME);
}
Gson gson = new Gson();
List<IndexQuery> queries = new ArrayList<IndexQuery>();
List<Car> cars = assembleTestData();
for (Car car : cars) {
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(car.getId().toString());
indexQuery.setSource(gson.toJson(car));
indexQuery.setIndexName(CAR_INDEX_NAME);
indexQuery.setType(CAR_INDEX_TYPE);
queries.add(indexQuery);
//分批提交索引
if (counter % 500 == 0) {
elasticsearchTemplate.bulkIndex(queries);
queries.clear();
System.out.println("bulkIndex counter : " + counter);
}
counter++;
}
//不足批的索引最后不要忘记提交
if (queries.size() > 0) {
elasticsearchTemplate.bulkIndex(queries);
}
elasticsearchTemplate.refresh(CAR_INDEX_NAME);
System.out.println("bulkIndex completed.");
} catch (Exception e) {
System.out.println("IndexerService.bulkIndex e;" + e.getMessage());
throw e;
}
return -1;
}
private List<Car> assembleTestData() {
List<Car> cars = new ArrayList<Car>();
//随机生成10000个索引,以便下一次批量写入
for (int i = 0; i < 10000; i++) {
cars.add(new Car(RandomUtils.nextLong(1, 11111), RandomStringUtils.randomAscii(20), RandomStringUtils.randomAlphabetic(15), BigDecimal.valueOf(78000)));
}
return cars;
}
}
再下面的工作就比较简单了,可以编写一个RestController接受请求来测试或者CommandLineRunner,在系统启动时就加载上面的方法。
@SpringBootApplication
@RestController
public class ESPApplicatoin {
public static void main(String[] args) {
SpringApplication.run(ESPApplicatoin.class, args);
}
@Autowired
IndexerService indexService;
@RequestMapping(value = "bulkIndex",method = RequestMethod.POST)
public void bulkIndex(){
try {
indexService.bulkIndex();
} catch (Exception e) {
e.printStackTrace();
}
}
}
CommandLineRunner方法类:
@Component
public class AppLoader implements CommandLineRunner {
@Autowired
IndexerService indexerService;
@Override
public void run(String... strings) throws Exception {
indexerService.bulkIndex();
}
}
结束后,就可在通过地址http://localhost:9200/car_index/_search/来查看索引到底有无生效。注:要特别关注版本的兼容问题,如果用Es
5+的话,显然不能采用Spring Data Elasticsearch的方式。
Spring Boot Version (x) |
Spring Data Elasticsearch Version (y) | Elasticsearch Version (z) |
---|---|---|
x <= 1.3.5 | y <= 1.3.4 | z <= 1.7.2* |
x >= 1.4.x | 2.0.0 <=y < 5.0.0** | 2.0.0 <= z < 5.0.0** |
(*) - require manual change in your project pom file (solution 2.)
(**) - Next big ES release with breaking changes
>>>案例地址:https://github.com/backkoms/spring-boot-elasticsearch
扩展阅读:
Spring
Boot + Elasticsearch 实现索引的日常维护
基于SpringCloud的Microservices架构实战案例-序篇
Nginx+Lua+MySQL/Redis实现高性能动态网页展现
Spring Boot + Elasticsearch 实现索引批量写入的更多相关文章
- Spring Boot + Elasticsearch 实现索引的日常维护
全文检索的应用越来越广泛,几乎成了互联网应用的标配,商品搜索.日志分析.历史数据归档等等,各种场景都会涉及到大批量的数据,在全文检索方面,方案无外乎Lucene.Solr.Elasticsearch三 ...
- Spring Boot + Elasticsearch实现大批量数据集下中文的精确匹配-案例剖析
缘由 数据存储在MYSQ库中,数据基本维持不变,但数据量又较大(几千万)放在MYSQL中查询效率上较慢,寻求一种简单有效的方式提高查询效率,MYSQL并不擅长大规模数据量下的数据查询. 技术方案 考虑 ...
- 搭建spring boot+elasticsearch+activemq服务
目前时间是:2017-01-24 本文不涉及activemq的安装 需求 activemq实时传递数据至服务 elasticsearch做索引 对外开放查询接口 完成全文检索 环境 jdk:1.8 s ...
- Spring Boot + Elasticsearch
spring data elasticsearch elasticsearch 2.0.0.RELEASE 2.2.0 1.4.0.M1 1.7.3 1.3.0.RELEASE 1.5.2 1.2.0 ...
- spring boot使用log4j2将日志写入mysql数据库
log4j2官方例子在spring boot中报错而且还是用的是org.apache.commons.dbcp包 我给改了一下使用org.apache.commons.dbcp2包 1.log4j2. ...
- Spring Boot + Elasticsearch 使用示例
本文分别使用 Elasticsearch Repository 和 ElasticsearchTemplate 实现 Elasticsearch 的简单的增删改查 一.Elastic Stack El ...
- Spring Boot 增加删除修改 批量
1.批量删除 a.自定义Repositoy中写 前台处理https://blog.csdn.net/yhflyl/article/details/81557670首先前台先要获取所有的要删除数据的I ...
- 在线elasticsearch集群批量写入变慢,导致kafka消息消费延迟
写入报错如些: -- ::24.166 [elasticsearch[_client_][listener][T#1]] INFO com.mobanker.framework.es.Elastics ...
- 。。。。。。不带http https : 不报错 spring boot elasticsearch rest
......不带http https : 不报错 先telnet http://onf:8080/getES653/道路桥梁正在“理疗”%20这14条道路纳入市政中修 @GetMapping(&qu ...
随机推荐
- C#:foreach语句,yield语句
原文:C#:foreach语句,yield语句 1. foreach语句 C#编译器会把foreach语句转换为IEnumerable接口的方法和属性. foreach (Person p in pe ...
- C#高性能大容量SOCKET并发(六):超时Socket断开(守护线程)和心跳包
原文:C#高性能大容量SOCKET并发(六):超时Socket断开(守护线程)和心跳包 守护线程 在服务端版Socket编程需要处理长时间没有发送数据的Socket,需要在超时多长时间后断开连接,我们 ...
- .net EF Join 关联表分页查询
Join中第二个参数和第三个参数即为两张表关联对应的字段 第四个参数new 后面如果不写Model名,系统会自动生成带字段的list类型 IQueryable<Operator> oper ...
- MFC OnPaint()函数中最先调用CDialog::OnPaint()和最后调用CDialog::OnPaint()的巨大区别
OnPaint()函数中最先调用CDialog::OnPaint()和最后调用CDialog::OnPaint()的巨大区别,如果没有注意这个问题就会出现无厘头式的绘图问题-- 效果就是出不来!在经过 ...
- Wolf RPG Editor游戏解包
前言 使用arc_conv_r53进行解包 使用touhouSE进行解包 使用DXEXTRACT进行解包 前言 Wolf RPG Editor由于其需要翻来覆去的转码,脚本名称等问题算是解包跟汉化中比 ...
- Ubuntu14.04 静态编译安装Qt4.8.6
./configure -static -nomake demos -nomake examples -nomake tools -no-exceptions -prefix /usr/local/Q ...
- Dedecms 中,获取某一栏目所有子栏目
以前从来没写过递归(其实想想,对算法完全没概念),刚好有这个需求,试着写了一下,发现也挺容易的,特别记录一下. 数据库是dedecms默认的,dede_arctype是保存栏目的表,reid是栏目的父 ...
- Mount挂载/data时出现mount: /data is busy 如何解决?
1.df -h查看下挂载点/data是否正在使用,有时候会存在挂载了,但df -h不会显示出来,这时候 grep “/data” /proc/mounts 来进行查看 2.当确认挂载点/data正在使 ...
- Dynamics 365 for sales - Account与Contact之间的关系
Account :可以理解成客户,可以是公司组织,当然也可以是个人 Contact: 从字面理解为联系人 例如,腾讯公司要买我们公司的软件,他们的主要负责人是IT部门的小马,那么,腾讯要创建成Acco ...
- Spring Boot:整合MyBatis框架
综合概述 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单 ...