APP下载

一种基于Hibernate的并行查询方法

2016-07-10卞林

电子技术与软件工程 2016年7期
关键词:远程监控数据库

为了保证车载动力电池的安全运行,全面掌握其运行状态,电动汽车远程监控系统已被各个厂家越来越重视,如何对监控产生的海量数据进行安全快速的查询是远程监控中的重要研究课题。本文着重介绍了一种基于Hibernate框架针对监控车辆的海量数据进行并行查询的设计思路、关键技术分析以及具体实现手段。通过将海量数据在ORACLE数据库中分区存储,查询终端经Hibernate服务器并行查询数据,保证了数据库安全的同时缩短了查询所需时间,达到了预期效果。

【关键词】远程监控 Hibernate 数据库 并行查询

电动汽车远程监控系统已被各个厂家越来越重视,而对监控产生的海量数据进行安全快速查询是远程监控中的重要研究课题。

基于Hibernate的远程监控数据并行查询目的在于:

(1)确保数据库安全;

(2)确保海量数据存储合理;

(3)提高海量数据查询效率。

本课题实现了通过中间Hibernate服务器将查询终端和数据库服务器间安全连接,通过按时间分区,保证了数据存储合理及在此基础上的并行查询算法的实现。

1 基于Hibernate的远程监控系统设计

架构图如图1,下面详细介绍模块。

1.1 远程监控终端采集模块

用于采集动力电池运营数据并将数据上传。

1.2 数据库集群

数据处理中心,负责存储查询数据,采用的是ORACLE11gR2 RAC版本。

1.3 远程监控系统应用服务器集群

数据接入服务器,负责接收远程终端采集来的数据。

1.4 Hibernate中间服务器模块

响应客户端的数据操作,保证数据安全。

1.5 客户端模块

包括pc,手机端等,通过中间服务器和数据库进行数据交换。

基于Hibernate的并行查询主要研究的是数据库安全和快速查询响应,因此远程监控终端采集模块和应用服务器集群不在此文的研究之中。

2 关键技术的研究

本项目中通过将数据库按时间进行分区,使海量数据合理存储;在查询端和数据库服务器集群间添加Hibernate框架中间服务器,保证数据安全;在客户端用并行查询的算法提高查询效率。

2.1 数据库分区

在存有海量数据的表格中,查询效率非常的低,进行按天分区后,查询时间大为缩短但还是未达到预期要求,因此我们提出了在分区基础上的并行查询。

2.2 Hibernate中间服务器

传统三层编程将客户端直连数据库,造成了安全隐患。而使用Hibernate架构,采用中间服务器处理客户端请求,避免了将数据服务器直接暴露在公网上,确保了数据安全。

2.3 并行查询算法

本项目并行查询基于数据库分区和Hibernate架构进行。在数据库中,我们将记录按天进行分区,为并行查询算法提供了可行基础。

数据库中的记录虽不断增加,但每天的记录是有限的,分区数据具备可操作性。如查询某辆车某月的数据,可以将数据查询拆分成30个并发线程,每个线程只查询一天的记录,将查询时间压缩至1天。

图2是两种查询方式的流程对比。

但长时距数据,不可能去开启无限线程,本项目采用了给定线程数上限按需循环去解决这个矛盾。在单个分区内进行查询效率最高,并行查询就是将所有的查询从跨分区的需求拆分为针对各个单独数据分区的查询,使查询效率大为提高。

本项目客户端采用C#开发,以单体信息查询为例,部分代码示例如下:

2.3.1 首先设置线程上限。

private long totalCount = 0; //存放计算结果

private readonlyintthreadCounts = 30; //处理的线程数

private static object locker = new object(); //线程锁

staticTCellInfoDao()

{

intminWorker, minIOC;

ThreadPool.GetMinThreads(out minWorker, out minIOC);

}

2.3.2 计算并发线程实际需要的数量,开启线程,在同步完成后给出结果统计

/// 并发计算count(*)

///

DateTimenextEndTime = DateTime.Parse(endTime.ToString("yyyy-MM-dd ")); //结束日期前零点时间 00:00:00

TimeSpants = endTime - nextbeginTime;

double seconds = ts.TotalSeconds;

if (seconds <= 0) //查询时间同一天

{

ManualResetEventmre = new ManualResetEvent(false);

manualEvents.Add(mre);

CellParams par = new CellParams();

par.BeginDate = beginTime;

par.EndDate = endTime;

par.BwtId = bwtid;

par.UserID = userID;

par.mrEvent = mre;

ThreadPool.QueueUserWorkItem(CalcCounts, par);

WaitHandle.WaitAll(manualEvents.ToArray()); //等待所有线程执行完毕,返回总数据

}

else //查询时间跨天

{

//计算开头和结尾时间段中数据

DateTime b = beginTime;

DateTime e = nextbeginTime;

for (inti = 0; i< 2; i++)

{

ManualResetEventmre = new ManualResetEvent(false);

manualEvents.Add(mre);

CellParams par = new CellParams();

par.BeginDate = b;

par.EndDate = e;

par.BwtId = bwtid;

par.mrEvent = mre;

par.UserID = userID;

ThreadPool.QueueUserWorkItem(CalcCounts, par);

b = nextEndTime;

e = endTime;

}

if (manualEvents.Count !=0)

WaitHandle.WaitAll(manualEvents.ToArray()); //等待所有线程执行完毕,返回总数据

if (manualEvents.Count != 0)

{

manualEvents.Clear();

}

//计算整数天的数据总数

inttotalDays = (nextEndTime - nextbeginTime).Days;

intprocessCounts = totalDays / threadCounts; //总处理次数,每次处理64条查询

intlastCounts = totalDays % threadCounts; //剩余天数

b = nextbeginTime; //开始时间下一天零点开始

for (inti = 0; i

{

for (int j = 0; j

{

ManualResetEventmre = new ManualResetEvent(false);

manualEvents.Add(mre);

CellParams par = new CellParams();

par.BeginDate = b;

par.EndDate = b.AddDays(1); //计算一天的分区的数据量

par.BwtId = bwtid;

par.UserID = userID;

par.mrEvent = mre;

ThreadPool.QueueUserWorkItem(CalcCounts, par);

b = b.AddDays(1);

}

if (manualEvents.Count != 0)

WaitHandle.WaitAll(manualEvents.ToArray()); //等待所有线程执行完毕,返回总数据

if (manualEvents.Count != 0)

{

manualEvents.Clear();

}

}

//计算剩余天数

for (inti = 0; i

{

ManualResetEventmre = new ManualResetEvent(false);

manualEvents.Add(mre);

CellParams par = new CellParams();

par.BeginDate = b;

par.EndDate = b.AddDays(1);

par.BwtId = bwtid;

par.UserID = userID;

par.mrEvent = mre;

ThreadPool.QueueUserWorkItem(CalcCounts, par);

b = b.AddDays(1);

}

if (manualEvents.Count != 0)

WaitHandle.WaitAll(manualEvents.ToArray()); //等待所有线程执行完毕,返回总数据

if (manualEvents.Count != 0)

{

manualEvents.Clear();

}

}

returntotalCount;

}

3 运行情况

采用了基于Hibernate架构的并行查询算法后,按时间段查询车辆数据的效率提高明显,单辆车每月数据查询的响应时间提高至0.3秒,每年数据查询的响应时间提高至2秒,用户使用体验良好,达到了项目预期。

4 结束语

基于Hibernate架构的并行查询算法克服了海量数据查询的难题,数据查询不再受限于数据表格中的记录总数,也减少了对于查询的时间段长短的依赖,在实际应用中很好的满足了用户的需求。

参考文献

[1]孙卫琴.精通Hibernate[M].北京:电子工业出版社,2005.

[2]周亮.Oracle DBA实战攻略:运维管理、诊断优化、高可用与最佳实践[M].北京:机械工业出版社,2013.

作者简介

卞林 (1976-),男,大学本科学历。现为合肥国轩高科动力能源有限公司工程师。主要研究方向为电动汽车远程监控系统。

郑中华(1988-),男,硕士学位。现为合肥国轩高科动力能源有限公司工程师。主要研究方向为电动汽车远程监控系统。

唐晓新(1989-),女,硕士学位。现为合肥国轩高科动力能源有限公司工程师。主要研究方向为电动汽车电池管理系统。

作者单位

合肥国轩高科动力能源有限公司 安徽省合肥市 230012

猜你喜欢

远程监控数据库
变电站直流电源智能化在线远程监测系统的实际应用
基于数据融合的家庭远程监护系统研究
保鲜库智能温度远程监控系统