如何把数据快速批量添加到Elasticsearch中

问题来源

最近新做一个项目,有部分搜索比较频繁的数据,而且量级比较大,预计一两年时间很可能达到100G,项目要求不要存在数据库中,最终出来有两个方案,一个是使用Protocol Buffers存储在文件上,另外就是存在Elasticsearch中,也方便搜索,但这两个方案需要验证,到底哪个方案好,从存储速度,搜索响应,占用空间方面做对比,而我负责给出Elasticsearch的部分技术建议!

验证需求

1、数据量:初步只算52亿条

2、写数据速度:需要超过1W条每秒

遇到问题以及解决办法

而在验证过程中遇到了无论是使用Elasticsearch.Net或者PlainElastic.Net来写数据,并且是使用了Bulk的api,加上多线程,都是太慢了,粗略算了一下,大概一秒插入3千条左右,这样的话,52亿条数据,得插到何年何月啊,太慢了,根据查阅资料,网上也有人说插入数据还是挺快 的,一秒可以插入18w条,但具体也没说是用什么办法插入的,所以只能到官方看看了,发现用REST API的_bulk来批量插入,这样速度明显快了,可以达到5到10w条每秒,速度还可以,但问题是这方法是先定义一定格式的json文件,然后再用curl命令去执行Elasticsearch的_bulk来批量插入,所以得把数据写进json文件,然后再通过批处理,执行文件插入数据,另外在生成json文件,文件不能过大,过大会报错,所以建议生成10M一个文件,然后分别去执行这些小文件就可以了,说了这么多都是文字,真的有点晕乎乎的,看图吧!

json数据文件内容的定义

1
2
3
4
5
6
7
8
9
10
{"index":{"_index":"meterdata","_type":"autoData"}}
{"Mfid ":1,"TData":172170,"TMoney":209,"HTime":"2016-05-17T08:03:00"}
{"index":{"_index":"meterdata","_type":"autoData"}}
{"Mfid ":1,"TData":172170,"TMoney":209,"HTime":"2016-05-17T08:04:00"}
{"index":{"_index":"meterdata","_type":"autoData"}}
{"Mfid ":1,"TData":172170,"TMoney":209,"HTime":"2016-05-17T08:05:00"}
{"index":{"_index":"meterdata","_type":"autoData"}}
{"Mfid ":1,"TData":172170,"TMoney":209,"HTime":"2016-05-17T08:06:00"}
{"index":{"_index":"meterdata","_type":"autoData"}}
{"Mfid ":1,"TData":172170,"TMoney":209,"HTime":"2016-05-17T08:07:00"}

 

批处理内容的定义

1
2
3
4
5
6
7
cd E:\curl-7.50.3-win64-mingw\bin
curl 172.17.1.15:9200/_bulk?pretty --data-binary @E:\Bin\Debug\testdata\437714060.json
curl 172.17.1.15:9200/_bulk?pretty --data-binary @E:\Bin\Debug\testdata\743719428.json
curl 172.17.1.15:9200/_bulk?pretty --data-binary @E:\Bin\Debug\testdata\281679894.json
curl 172.17.1.15:9200/_bulk?pretty --data-binary @E:\Bin\Debug\testdata\146257480.json
curl 172.17.1.15:9200/_bulk?pretty --data-binary @E:\Bin\Debug\testdata\892018760.json
pause

 

工具代码

 1      private void button1_Click(object sender, EventArgs e)
2 {
3 //Application.StartupPath + "\\" + NextFile.Name
4 Task.Run(() => { CreateDataToFile(); });
5 }
6 public void CreateDataToFile()
7 {
8 StringBuilder sb = new StringBuilder();
9 StringBuilder sborder = new StringBuilder();
10 int flag = 1;
11 sborder.Append(@"cd E:\curl-7.50.3-win64-mingw\bin" + Environment.NewLine);
12 DateTime endDate = DateTime.Parse("2016-10-22");
13 for (int i = 1; i <= 10000; i++)//1w个点
14 {
15 DateTime startDate = DateTime.Parse("2016-10-22").AddYears(-1);
16 this.Invoke(new Action(() => { label1.Text = "生成第" + i + "个"; }));
17
18 while (startDate <= endDate)//每个点生成一年数据,每分钟一条
19 {
20 if (flag > 100000)//大于10w分割一个文件
21 {
22 string filename = new Random(GetRandomSeed()).Next(900000000) + ".json";
23
24 FileStream fs3 = new FileStream(Application.StartupPath + "\\testdata\\" + filename, FileMode.OpenOrCreate);
25 StreamWriter sw = new StreamWriter(fs3, Encoding.GetEncoding("GBK"));
26 sw.WriteLine(sb.ToString());
27 sw.Close();
28 fs3.Close();
29 sb.Clear();
30 flag = 1;
31 sborder.Append(@"curl 172.17.1.15:9200/_bulk?pretty --data-binary @E:\Bin\Debug\testdata\" + filename + Environment.NewLine);
32
33 }
34 else
35 {
36 sb.Append("{\"index\":{\"_index\":\"meterdata\",\"_type\":\"autoData\"}}" + Environment.NewLine);
37 sb.Append("{\"Mfid \":" + i + ",\"TData\":" + new Random().Next(1067500) + ",\"TMoney\":" + new Random().Next(1300) + ",\"HTime\":\"" + startDate.ToString("yyyy-MM-ddTHH:mm:ss") + "\"}" + Environment.NewLine);
38 flag++;
39 }
40 startDate = startDate.AddMinutes(1);//
41 }
42
43 }
44 sborder.Append("pause");
45 FileStream fs1 = new FileStream(Application.StartupPath + "\\testdata\\order.bat", FileMode.OpenOrCreate);
46 StreamWriter sw1 = new StreamWriter(fs1, Encoding.GetEncoding("GBK"));
47 sw1.WriteLine(sborder.ToString());
48 sw1.Close();
49 fs1.Close();
50 MessageBox.Show("生成完毕");
51
52 }
53 static int GetRandomSeed()
54 {//随机生成不重复的编号
55 byte[] bytes = new byte[4];
56 System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
57 rng.GetBytes(bytes);
58 return BitConverter.ToInt32(bytes, 0);
59 }

总结

本次测试结果,发现Elasticsearch的搜索速度是挺快的,生成过程中,在17亿数据时查了一下,根据Mid和时间在几个月范围的数据,查十条数据两秒多完成查询,而且同一查询条件查询越多,查询就越快,应该是Elasticsearch缓存了,52亿条数据,大概占用500G空间左右,还是挺大的,相比Protocol Buffers存储的数据,要大三倍左右,但搜索速度还是比较满意的。

(有问题,大家多多交流,加群163259145,加群请记得说:博客园)

你只看到我在不停的忙碌,却没看到我奋斗的热情。你有朝九晚五,我有通宵达旦。你否定我的现在,我决定我的未来。你可以轻视我的存在,我会用代码证明这是谁的时代!Coding是注定痛苦的旅行,路上少不了Bug和Change,但!那又怎样?哪怕执行不了,也要编译得漂亮!我是屌丝程序猿,我为自己代言.

 
分类: Elasticsearch

数据快速批量添加到Elasticsearch的更多相关文章

  1. 如何把数据快速批量添加到Elasticsearch中

    问题来源 最近新做一个项目,有部分搜索比较频繁的数据,而且量级比较大,预计一两年时间很可能达到100G,项目要求不要存在数据库中,最终出来有两个方案,一个是使用Protocol Buffers存储在文 ...

  2. Redis批量执行(如list批量添加)命令工具 —— pipeline管道应用

    前言 Redis使用的是客户端-服务器(CS)模型和请求/响应协议的TCP服务器.这意味着通常情况下一个请求会遵循以下步骤: 使用Redis管道提升性能 (1)客户端向服务端发送一个查询请求,并监听S ...

  3. java操作elasticsearch实现批量添加数据(bulk)

    java操作elasticsearch实现批量添加主要使用了bulk 代码如下: //bulk批量操作(批量添加) @Test public void test7() throws IOExcepti ...

  4. net core天马行空系列-各大数据库快速批量插入数据方法汇总

    1.前言 hi,大家好,我是三合.我是怎么想起写一篇关于数据库快速批量插入的博客的呢?事情起源于我们工作中的一个需求,简单来说,就是有一个定时任务,从数据库里获取大量数据,在应用层面经过处理后再把结果 ...

  5. EF批量添加数据性能慢的问题的解决方案

    //EF批量添加数据性能慢的问题的解决方案 public ActionResult BatchAdd() { using (var db = new ToneRoad.CEA.DbContext.Db ...

  6. Java使用Mysql数据库实现批量添加数据

    EmployeeDao.java //批处理添加数据 public int saveEmploeeBatch(){ int row = 0; try{ con = DBCon.getConn(); S ...

  7. .Net中批量添加数据的几种实现方法比较

    在.Net中经常会遇到批量添加数据,如将Excel中的数据导入数据库,直接在DataGridView控件中添加数据再保存到数据库等等. 方法一:一条一条循环添加 通常我们的第一反应是采用for或for ...

  8. ThinkPHP批量添加数据和getField()示例

    批量添加数据 // 批量添加数据 $User = M('users'); $dataList[] = array('name'=>'thinkphp','email'=>'thinkphp ...

  9. ASP.NET MVC用存储过程批量添加修改数据

    用Entity Framework 进行数据库交互,在代码里直接用lamda表达式和linq对数据库操作,中间为程序员省去了数据库访问的代码时间,程序员直接可以专注业务逻辑层的编写.但是对于比较复杂的 ...

随机推荐

  1. react 之 reflux 填坑

    注意:老铁些,在看这篇文章的之前,最好了解一下react 的全局状态管理库哦,不然可能会坐飞机. ^_^ React 之reflux (它是一个功能模块,需要安装引入): import Reflux ...

  2. March 06th, 2018 Week 10th Tuesday

    Hope for the best, but prepare for the worst. 抱最好的愿望,做最坏的打算. To hope for the best and prepare for th ...

  3. Python爬虫-05:Ajax加载的动态页面内容

    1. 获取AJAX加载动态页面的内容 1.1. Introduction 如果所爬取的网址是通过Ajax方式加载的,就直接抓包,拿他后面传输数据的文件 有些网页内容使用AJAX加载,只要记得,AJAX ...

  4. Spring事务管理2--声明式

    简述 1.Spring 的声明式事务管理在底层是建立在 AOP 的基础上.其本质是在方法前后进行拦截,然后在目标方法开始之前创建一个事务,在执行这目标方法结束后,根据执行情况提交或进行回滚事务. 2. ...

  5. SecureCRT窗口输出代码关键字高亮设置

    设置方法: 下载配置文件:本站下载:Highlights.css  (下载重命名为 Highlights.ini )   原站下载:http://download.feralpacket.org/La ...

  6. Django forms 关于select和checkbox设置初始选中值

    Django的forms和models一样很牛逼.他有两种功能,一是生成form表单,还有就是form表单的验证. 这里主要说一下生成form表单时经常用到的需要设置 初始值 / 默认值 的情况. 1 ...

  7. n阶方阵的最值问题和对角线的和问题

    如题! package 矩阵2; public class JuZheng { public static void main(String args[]) { int array[][] = { { ...

  8. 最小生成树 A - 畅通工程

    dalao视频:https://www.bilibili.com/video/av4768483 https://www.bilibili.com/video/av4768483?p=2 省政府“畅通 ...

  9. @ModelAttribute

    在执行Controller方法前都会新建一个Map对象称为隐含模型,该Map对象是共享的,如果一个方法的入参为Map ModelAndMap ModelMap等类型,那么会把隐含模型当做入参赋给方法. ...

  10. Nginx系列一:正向代理和反向代理、Nginx工作原理、Nginx常用命令和升级、搭建Nginx负载均衡

    转自https://www.cnblogs.com/leeSmall/p/9351343.html 仅供个人学习 一.什么是正向代理.什么是反向代理 1. 正向代理,意思是一个位于客户端和原始服务器( ...