elasticsearch使用BulkProcessor批量入库数据
在解决es入库问题上,之前使用过rest方式,经过一段时间的测试发现千万级别的数据会存在10至上百条数据的丢失问题,
在需要保证数据的准确性的场景下,rest方式并不能保证结果的准确性,因此采用了elasticsearch的BulkProcessor方式来进行数据入库,
实际上采用es客户端不同,rest方式采用的是restClient,基于http协议,BulkProcessor使用的是TransportClient,基于Tcp协议。
下面是在spring下具体的实现步骤:
1 定义一个student类,并json序列化
2 json的具体实现
3 构造BulkProcessor
* setBulkActions(1000):每添加1000个request,执行一次bulk操作
* setBulkSize(new ByteSizeValue(5, ByteSizeUnit.MB)):每达到5M的请求size时,执行一次bulk操作
* setFlushInterval(TimeValue.timeValueSeconds(5)):每5s执行一次bulk操作
* setConcurrentRequests(1):默认是1,表示积累bulk requests和发送bulk是异步的,其数值表示发送bulk的并发线程数,设置为0表示二者同步的
*setBackoffPolicy(BackoffPolicy.exponentialBackoff(TimeValue.timeValueMillis(100),3)):当ES由于资源不足发生异常
EsRejectedExecutionException重試策略:默认(50ms, 8),
* 策略算法:start + 10 * ((int) Math.exp(0.8d * (currentlyConsumed)) - 1)
package es; import org.elasticsearch.action.bulk.BackoffPolicy;
import org.elasticsearch.action.bulk.BulkProcessor;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.net.InetAddress;
import java.net.UnknownHostException; @Configuration
public class ESConfiguration {
public static final Logger logger = LoggerFactory.getLogger(ESConfiguration.class); @Bean
public BulkProcessor bulkProcessor() throws UnknownHostException { Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build(); Client client = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("http://192.168.10.33"), Integer.parseInt("9300"))); return BulkProcessor.builder(client, new BulkProcessor.Listener() {
@Override
public void beforeBulk(long l, BulkRequest bulkRequest) { } @Override
public void afterBulk(long l, BulkRequest bulkRequest, BulkResponse bulkResponse) { } @Override
public void afterBulk(long l, BulkRequest bulkRequest, Throwable throwable) {
logger.error("{} data bulk failed,reason :{}", bulkRequest.numberOfActions(), throwable);
} }).setBulkActions(1000)
.setBulkSize(new ByteSizeValue(5, ByteSizeUnit.MB))
.setFlushInterval(TimeValue.timeValueSeconds(5))
.setConcurrentRequests(1)
.setBackoffPolicy(BackoffPolicy.exponentialBackoff(TimeValue.timeValueMillis(100), 3))
.build();
}
}
4. 入库代码实现
package es; import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.bulk.BulkProcessor;
import org.elasticsearch.action.index.IndexRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository; @Repository
public class StudentInsertDao{
private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired
private BulkProcessor bulkProcessor; private ObjectMapper objectMapper = new ObjectMapper(); public void insert(Student student) {
String type = student.getAge();
String id = student.getName()+student.getAddr()+student.getAge();
try {
byte[] json = objectMapper.writeValueAsBytes(student); bulkProcessor.add(new IndexRequest("students", type, id).source(json)); } catch (Exception e) {
logger.error("bulkProcessor failed ,reason:{}",e);
}
}
}
5. 测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:servlet-context.xml", "classpath:applicationContext.xml"})
public class StudentInsertDaoTest {
@Autowired
private StudentInsertDao insertDao; @Test
public void insert() throws Exception { Student student = new Student();
student.setAge(12);
student.setAddr("SH");
student.setName("Jack"); insertDao.insert(student);
}
}
原文链接:https://blog.csdn.net/wslyk606/article/details/79413980
Elasticsearch-BulkProcessor浅析:
https://blog.csdn.net/baichoufei90/article/details/97117025
elasticsearch使用BulkProcessor批量入库数据的更多相关文章
- Elasticsearch使用BulkProcessor批量插入
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-bulk. ...
- elasticsearch REST API方式批量插入数据
elasticsearch REST API方式批量插入数据 1:ES的服务地址 http://127.0.0.1:9600/_bulk 2:请求的数据体,注意数据的最后一行记得加换行 { &quo ...
- discuz数据批量入库接口
近期在做社区,首选discuz,数据需要用scrapy爬虫批量入库,就写了一个php入库接口. <?php define('PW', 'abc123456');//一定要修改 if($_REQU ...
- SqlBulkCopy 批量复制数据到数据表
使用 SqlBulkCopy 类只能向 SQL Server 表写入数据.但是,数据源不限于 SQL Server:可以使用任何数据源,只要数据可加载到 DataTable 实例或可使用 IDataR ...
- SQLServer使用表值参数,高性能批量插入数据
记得前段时间帮同事写了个解析账号并入库的小工具,来批量导入账号信息,账号量相当大,程序每读取一条记录便执行一次insert来插入数据,整整跑了一下午才把账号全部入库. 今天又接到同事类似的需求,不过这 ...
- 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)
问题分析 问题一:要求日志最好入库:但是,直接入库mysql确实扛不住,批量入库没有问题,done.[批量入库和直接入库性能差异] 问题二:批量入库就需要有高并发的消息队列,决定采用redis lis ...
- myBatis获取批量插入数据的主键id
在myBatis中获取刚刚插入的数据的主键id是比较容易的 , 一般来说下面的一句话就可以搞定了 , 网上也有很多相关资料去查. @Options(useGeneratedKeys = true, k ...
- 转载:【高并发简单解决方案 | 靠谱崔小拽 】redis队列缓存 + mysql 批量入库 + php离线整合
需求背景:有个调用统计日志存储和统计需求,要求存储到mysql中:存储数据高峰能达到日均千万,瓶颈在于直接入库并发太高,可能会把mysql干垮. 问题分析 思考:应用网站架构的衍化过程中,应用最新的框 ...
- redis 队列缓存 + mysql 批量入库 + php 离线整合
问题分析 思考:应用网站架构的衍化过程中,应用最新的框架和工具技术固然是最优选择:但是,如果能在现有的框架的基础上提出简单可依赖的解决方案,未尝不是一种提升自我的尝试. 解决: 问题一:要求日志最好入 ...
随机推荐
- Kubernetes- Dashboard 部署
获取dashboard 的yaml文件 wget wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/dep ...
- 打造kubernetes 高可用集群(nginx+keepalived)
一.添加master 部署高可用k8s架构 1.拷贝/opt/kubernetes目录到新的master上(注意如果新机上部署了etcd要排除掉) scp -r /opt/kubernetes/ ro ...
- (多核DSP快速入门)SYS/BIOS入门
(多核DSP快速入门)SYS/BIOS入门 原创文章 转载请注册来源http://blog.csdn.net/tostq 系列教程目录:http://blog.csdn.net/tostq/art ...
- 批处理引擎MapReduce程序设计
批处理引擎MapReduce程序设计 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MapReduce API Hadoop同时提供了新旧两套MapReduce API,新AP ...
- PHP添加php-java-brideg模块(ubuntu环境)
1.下载php-java-bridge 下载地址:https://sourceforge.net/projects/php-java-bridge/files/Binary%20package/php ...
- C++(四十)— C++中一个class类对象占用多少内字节
一个空的class在内存中多少字节?如果加入一个成员函数后是多大?这个成员函数存储在内存中什么部分? 一个Class对象需要占用多大的内存空间.最权威的结论是: 非静态成员变量总合. 加上编译器为了C ...
- mysql字典取值,列表包含
SELECT * FROM e where JSON_CONTAINS(json_extract(scope_detail, '$.shop'), '001');
- linux系统编程之文件与io(五)
上一节中已经学习了文件描述符的复制,复制方法有三种,其中最后一种fcntl还并未使用到,关于这个函数,不光只有复制文件描述符的功能,还有其它一些用法,本节就对其进行一一剖析: fcntl常用操作: 这 ...
- 微信小程序使用本地图片在真机不显示的问题
最近做的小程序,在真机测试发现有些本地图片在开发工具上可以显示,但是在真机上预览的时候不能显示 代码是这样写的 <view class='seat-size' wx:for="{{it ...
- Spring-05 -AOP [面向切面编程] -Schema-based 实现aop的步骤
一.AOP [知识点详解] AOP:中文名称面向切面编程 英文名称:(Aspect Oriented Programming) 正常程序执行流程都是纵向执行流程 3.1 又叫面向切面编程,在原有纵向执 ...