最近着手处理大批量数据的任务。

现状是这样的,一个数据采集程序承载大批量数据的存储和检索。后期可能需要对大批量数据进行统计。

数据分布情况

13个点定时生成采集结果到4个文件(小文件生成周期是5分钟)

名称                                                 大小(b)
gather_1_2014-02-27-14-50-0.txt 568497
gather_1_2014-02-27-14-50-1.txt 568665
gather_1_2014-02-27-14-50-2.txt 568172
gather_1_2014-02-27-14-50-3.txt 568275

同步使用shell脚本对四个文件入到sybase_iq库的一张表tab_tmp_2014_2_27中.

每天数据量大概是3亿条,所以小文件的总量大概是3G。小文件数量大,单表容量大执行复合主键查询,由原来2s延时变成了,5~10分钟。

针对上述情况需要对目前的储存结构进行优化。

才是看了下相关系统 catior使用的是环状数据库,存储相关的数据优点方便生成MRTG图,缺点不利于数据统计。后来引入elasticsearch来对大数据检索进行优化。

测试平台

cpu: AMD Opteron(tm) Processor 6136 64bit 2.4GHz   * 32
内存: 64G
硬盘:1.5T
操作系统:Red Hat Enterprise Linux Server release 6.4 (Santiago)

读取文件的目录结构:

[test@test001 data]$ ls
0 1 2 3

简单测试代码:

public class FileReader
{ private File file;
private String splitCharactor;
private Map<String, Class<?>> colNames;
private static final Logger LOG = Logger.getLogger(FileReader.class); /**
* @param path
* 文件路径
* @param fileName
* 文件名
* @param splitCharactor
* 拆分字符
* @param colNames
* 主键名称
*/
public FileReader(File file, String splitCharactor, Map<String, Class<?>> colNames)
{
this.file = file;
this.splitCharactor = splitCharactor;
this.colNames = colNames;
} /**
* 读取文件
*
* @return
* @throws Exception
*/
public List<Map<String, Object>> readFile() throws Exception
{
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
if (!file.isFile())
{
throw new Exception("File not exists." + file.getName());
}
LineIterator lineIterator = null;
try
{
lineIterator = FileUtils.lineIterator(file, "UTF-8");
while (lineIterator.hasNext())
{
String line = lineIterator.next();
String[] values = line.split(splitCharactor);
if (colNames.size() != values.length)
{
continue;
}
Map<String, Object> map = new HashMap<String, Object>();
Iterator<Entry<String, Class<?>>> iterator = colNames.entrySet()
.iterator();
int count = 0;
while (iterator.hasNext())
{
Entry<String, Class<?>> entry = iterator.next();
Object value = values[count];
if (!String.class.equals(entry.getValue()))
{
value = entry.getValue().getMethod("valueOf", String.class)
.invoke(null, value);
}
map.put(entry.getKey(), value);
count++;
}
list.add(map);
}
}
catch (IOException e)
{
LOG.error("File reading line error." + e.toString(), e);
}
finally
{
LineIterator.closeQuietly(lineIterator);
}
return list;
}
}
public class StreamIntoEs
{ public static class ChildThread extends Thread
{ int number; public ChildThread(int number)
{
this.number = number;
} @Override
public void run()
{
Settings settings = ImmutableSettings.settingsBuilder()
.put("client.transport.sniff", true)
.put("client.transport.ping_timeout", 100)
.put("cluster.name", "elasticsearch").build();
TransportClient client = new TransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress("192.168.32.228",
9300));
File dir = new File("/export/home/es/data/" + number);
LinkedHashMap<String, Class<?>> colNames = new LinkedHashMap<String, Class<?>>();
colNames.put("aa", Long.class);
colNames.put("bb", String.class);
colNames.put("cc", String.class);
colNames.put("dd", Integer.class);
colNames.put("ee", Long.class);
colNames.put("ff", Long.class);
colNames.put("hh", Long.class);
int count = 0;
long startTime = System.currentTimeMillis();
for (File file : dir.listFiles())
{
int currentCount = 0;
long startCurrentTime = System.currentTimeMillis();
FileReader reader = new FileReader(file, "\\$", colNames);
BulkResponse resp = null;
<strong>BulkRequestBuilder bulkRequest = client.prepareBulk();</strong>
try
{
List<Map<String, Object>> results = reader.readFile();
for (Map<String, Object> col : results)
{
bulkRequest.add(client.prepareIndex("flux", "fluxdata")
.setSource(JSON.toJSONString(col)).setId(col.get("getway")+"##"+col.get("port_info")+"##"+col.get("device_id")+"##"+col.get("collecttime")));
count++;
currentCount++;
}
resp = bulkRequest.execute().actionGet();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
long endCurrentTime = System.currentTimeMillis();
System.out.println("[thread-" + number + "-]per count:" + currentCount);
System.out.println("[thread-" + number + "-]per time:"
+ (endCurrentTime - startCurrentTime));
System.out.println("[thread-" + number + "-]per count/s:"
+ (float) currentCount / (endCurrentTime - startCurrentTime)
* 1000);
System.out.println("[thread-" + number + "-]per count/s:"
+ resp.toString());
}
long endTime = System.currentTimeMillis();
System.out.println("[thread-" + number + "-]total count:" + count);
System.out.println("[thread-" + number + "-]total time:"
+ (endTime - startTime));
System.out.println("[thread-" + number + "-]total count/s:" + (float) count
/ (endTime - startTime) * 1000);
// IndexRequest request =
// = client.index(request);
}
} public static void main(String args[])
{
for (int i = 0; i < 4; i++)
{
ChildThread childThread = new ChildThread(i);
childThread.start();
}
}
}

起了4个线程来做入库,每个文件解析完成进行一次批处理。

初始化脚本:

curl -XDELETE 'http://192.168.32.228:9200/twitter/'
curl -XPUT 'http://192.168.32.228:9200/twitter/' -d '
{
"index" :{
"number_of_shards" : 5,
"number_of_replicas ": 0,
<strong>"index.refresh_interval": "-1",
"index.translog.flush_threshold_ops": "100000"</strong>
}
}'
curl -XPUT 'http://192.168.32.228:9200/twiter/twiterdata/_mapping' -d '
{
"<span style="font-size: 1em; line-height: 1.5;">twiterdata</span><span style="font-size: 1em; line-height: 1.5;">": {</span>
"aa" : {"type" : "long", "index" : "not_analyzed"},
"bb" : {"type" : "String", "index" : "not_analyzed"},
"cc" : {"type" : "String", "index" : "not_analyzed"},
"dd" : {"type" : "integer", "index" : "not_analyzed"},
"ee" : {"type" : "long", "index" : "no"},
"ff" : {"type" : "long", "index" : "no"},
"gg" : {"type" : "long", "index" : "no"},
"hh" : {"type" : "long", "index" : "no"},
"ii" : {"type" : "long", "index" : "no"},
"jj" : {"type" : "long", "index" : "no"},
"kk" : {"type" : "long", "index" : "no"},
}
}

执行效率参考:

不开启refresh_interval
[test@test001 bin]$ more StreamIntoEs.out|grep total
[thread-2-]total count:1199411
[thread-2-]total time:1223718
[thread-2-]total count/s:980.1368
[thread-1-]total count:1447214
[thread-1-]total time:1393528
[thread-1-]total count/s:1038.5253
[thread-0-]total count:1508043
[thread-0-]total time:1430167
[thread-0-]total count/s:1054.4524
[thread-3-]total count:1650576
[thread-3-]total time:1471103
[thread-3-]total count/s:1121.9989
4195.1134 开启refresh_interval
[test@test001 bin]$ more StreamIntoEs.out |grep total
[thread-2-]total count:1199411
[thread-2-]total time:996111
[thread-2-]total count/s:1204.0938
[thread-1-]total count:1447214
[thread-1-]total time:1163207
[thread-1-]total count/s:1244.1586
[thread-0-]total count:1508043
[thread-0-]total time:1202682
[thread-0-]total count/s:1253.9
[thread-3-]total count:1650576
[thread-3-]total time:1236239
[thread-3-]total count/s:1335.1593
5037.3117 开启refresh_interval 字段类型转换
[test@test001 bin]$ more StreamIntoEs.out |grep total
[thread-2-]total count:1199411
[thread-2-]total time:1065229
[thread-2-]total count/s:1125.9653
[thread-1-]total count:1447214
[thread-1-]total time:1218342
[thread-1-]total count/s:1187.8552
[thread-0-]total count:1508043
[thread-0-]total time:1230474
[thread-0-]total count/s:1225.5789
[thread-3-]total count:1650576
[thread-3-]total time:1274027
[thread-3-]total count/s:1295.5581
4834.9575 开启refresh_interval 字段类型转换 设置id
[thread-2-]total count:1199411
[thread-2-]total time:912251
[thread-2-]total count/s:1314.7817
[thread-1-]total count:1447214
[thread-1-]total time:1067117
[thread-1-]total count/s:1356.1906
[thread-0-]total count:1508043
[thread-0-]total time:1090577
[thread-0-]total count/s:1382.7937
[thread-3-]total count:1650576
[thread-3-]total time:1128490
[thread-3-]total count/s:1462.6412
5516.4072

580M的数据平均用时大概是20分钟。索引文件大约为1.76G

相关测试结果可以参考这里:

elasticsearch 性能测试

ElasticSearch大批量数据入库的更多相关文章

  1. ODP方式,大批量数据写入ORACLE数据库

    项目中在同步数据的时候,需要把获得的数据DataTable,写入oracle数据库 因为System.Data.OracleClient写入方式写入大批量数据特别慢,改用Oracle.DataAcce ...

  2. 使用hive访问elasticsearch的数据

    使用hive访问elasticsearch的数据 1.配置 将elasticsearch-hadoop-2.1.1.jar拷贝到hive/lib hive -hiveconf hive.aux.jar ...

  3. 使用spark访问elasticsearch的数据

    使用spark访问elasticsearch的数据,前提是spark能访问hive,hive能访问es http://blog.csdn.net/ggz631047367/article/detail ...

  4. oracle 快速删除大批量数据方法(全部删除,条件删除,删除大量重复记录)

    oracle 快速删除大批量数据方法(全部删除,条件删除,删除大量重复记录) 分类: ORACLE 数据库 2011-05-24 16:39 8427人阅读 评论(2) 收藏 举报 oracledel ...

  5. Sql Server数据库使用触发器和sqlbulkcopy大批量数据插入更新

    需要了解的知识 1.触发器 2.sqlbulkcopy 我的用途 开发数据库同步的工具,需要大批量数据插入和数据更新. 方式 使用SqlBulkCopy类对数据进行数据批量复制,将需要同步数据的表新建 ...

  6. Java实现大批量数据导入导出(100W以上) -(二)导出

    使用POI或JXLS导出大数据量(百万级)Excel报表常常面临两个问题: 1. 服务器内存溢出: 2. 一次从数据库查询出这么大数据,查询缓慢. 当然也可以分页查询出数据,分别生成多个Excel打包 ...

  7. Java实现大批量数据导入导出(100W以上) -(一)导入

    最近业务方有一个需求,需要一次导入超过100万数据到系统数据库.可能大家首先会想,这么大的数据,干嘛通过程序去实现导入,为什么不直接通过SQL导入到数据库. 大数据量报表导出请参考:Java实现大批量 ...

  8. elasticsearch(3) 数据操作-更新

    一 更新整个文档 更新整个文档的方法和存放数据的方式是相同的,通过PUT 127.0.0.1/test/test/1  我们可以把test/test/1下的文档更新为新的文档 例: PUT 127.0 ...

  9. oracle数据入库

    oracle数据入库 注意:先要处理文件中的分隔符   将数据分列 创建为标准的sql语句   1.在oracle数据库中创建要入库的表如果有该表则不用创建(注:创建字段的数据类型要符合实际逻辑 va ...

随机推荐

  1. <php>统计目录数和文件数

    $dirn = 0; //目录数 $filen = 0; //文件数 //用来统计一个目录下的文件和目录的个数 function getdirnum($file) { global $dirn; gl ...

  2. Python获取并输出当前日期时间

    取得时间相关的信息的话,要用到python time模块,python time模块里面有很多非常好用的功能,你可以去官方文档了解下,要取的当前时间的话,要取得当前时间的时间戳,时间戳好像是1970年 ...

  3. [转] ubuntu 一些常用软件的安装

    首先说明一下 ubuntu 的软件安装大概有几种方式: 1. deb 包的安装方式deb 是 debian 系 Linux 的包管理方式, ubuntu 是属于 debian 系的 Linux 发行版 ...

  4. hibernate-4.3.5安装配置

    起初照着官方文档配,一直出错,貌似官方的文档时错的,查了非常多资料,综合整理了一个可行的方案,例如以下: 0.1包结构 test.demo test.domain  //实体类 test.util// ...

  5. [RxJS] Reactive Programming - Using cached network data with RxJS -- withLatestFrom()

    So now we want to replace one user when we click the 'x' button. To do that, we want: 1. Get the cac ...

  6. 完善GDAL与OpenCV间的数据格式转换与影像分块读写

    本博客为原创内容,未经博主允许禁止转载,商用,谢谢. 一.前言 关于GDAL与openCV间的数据格式转换,在我之前的博客中已有简要说明,这里,由于最近工作上经常用到openCV里的函数进行图像处理, ...

  7. .NET基础拾遗(5)反射1

    1.反射产生的背景 对无法直接添加引用的程序集中类型元素的动态获取和使用.使用场景如插件开发,vs本身的智能提示. 2.反射的基本原理 依托于元数据,运行时动态获取并构建程序集.模块.类型及字段等目标 ...

  8. 通过JS控制textarea的输入长度

    废话不多说,直接上代码(因为自己也只是遇到的时候然后上网查到的解决办法,放在此处只是为了方便各位看以及以后再碰到用起来方便) <ul> <li> <textarea ro ...

  9. SuperSocket学习笔记(一)

    这是根据我自己学习的经历整理出来的,如有不对之处,还请多多指教! SuperSocket源码下载 SuperSocket文档 安装并启动Telnet 学习方法: QuickStrart + 文档 参考 ...

  10. C#窗体实现文件拖拽功能

    1.首先要把你的窗体或者空间的AllowDrag属性设置为允许 2.注册DragEnter事件 3.获得文件路径,先通过e.Data.GetFormats()方法获得所有数据格式 4.调用e.GetD ...