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

转载 2017年10月18日 10:44:35

问题来源

最近新做一个项目,有部分搜索比较频繁的数据,而且量级比较大,预计一两年时间很可能达到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存储的数据,要大三倍左右,但搜索速度还是比较满意的。

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

http://www.cnblogs.com/hai-ping/p/6068946.html 问题来源 最近新做一个项目,有部分搜索比较频繁的数据,而且量级比较大,预计一两...
  • zdy0_2004
  • zdy0_2004
  • 2016年11月16日 16:27
  • 932

ElasticSearch大批量数据入库

最近着手处理大批量数据的任务。 现状是这样的,一个数据采集程序承载大批量数据的存储和检索。后期可能需要对大批量数据进行统计。 数据分布情况 13个点定时生成采集结果到4个文件(小文件生成周期是5...
  • xiamizy
  • xiamizy
  • 2014年07月28日 10:49
  • 32756

JAVA接口将从MySql查出的大量数据导入到Elasticsearch中实现类

通过JAVA API 用BulkRequestBuilder 导入从MySql查出的大量数据至ElasticSearch
  • EliTheGod
  • EliTheGod
  • 2017年04月27日 14:41
  • 1227

elasticsearch-批量插入,删除,修改处理

代价较小的批量操作 与 mget 可以使我们一次取回多个文档同样的方式,bulk API 允许在单个步骤中进行多次 create 、 index 、 update 或 delete 请求。如果你需...
  • chuan442616909
  • chuan442616909
  • 2017年01月13日 14:46
  • 3321

Elasticsearch 批量导入数据

前言 Elasticsearch 是一款非常高效的全文检索引擎。 Elasticsearch 可以非常方便地进行数据的多维分析,所以大数据分析领域也经常会见到它的身影,生产环境中绝大部分新产生的数...
  • u013063153
  • u013063153
  • 2017年03月10日 10:18
  • 7388

ElasticsearchCRUD使用(十五)【批量插入数据】

本文介绍如何使用别名和bulk插入大量文档来设置Elasticsearch索引。 批量插入大量文档时,可以通过关闭刷新间隔(RefreshInterval="-1")并关闭复制来提高性能。 插入完成后...
  • WuLex
  • WuLex
  • 2017年05月11日 22:54
  • 797

Elasticsearch 2.0以上版本根据条件批量删除Java如何实现

Elasticsearch在2.0以前版本,删除操作有两种方式,一种是通过id来进行删除,但是这种方式一般不常用,因为id不容易得到;另一种方式是通过先查询操作,然后删除,也就是通过client.pr...
  • u014039577
  • u014039577
  • 2016年07月01日 16:03
  • 8302

Elasticsearch学习笔记(五)批量操作

一次性检索多个文档【多个查询条件】mget 结果中可以看到:第二个文档不存在,但是mget请求返回码是200,即使一个都不存在也是返回200,所以要判断found是否为TRUE来判断是否真正查询出...
  • fgyibupi
  • fgyibupi
  • 2017年01月25日 12:10
  • 2124

ElasticSearch批量更新索引的优化

1. 多线程程序插入可以根据服务器情况开启多个线程index,速度可以提高n倍, n>=2 2. 取消replias如果有多台机器,可以以每台设置n个shards的方式,根据业务情况,可以考虑取消re...
  • lazythinker
  • lazythinker
  • 2017年03月08日 14:02
  • 1779

ElasticSearch中批量导入数据: _bulk命令

在使用Elasticsearch的时候,bulk批量导入
  • bsh_csn
  • bsh_csn
  • 2016年12月28日 09:33
  • 891
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何把数据快速批量添加到Elasticsearch中
举报原因:
原因补充:

(最多只允许输入30个字)