您的位置:首页 > 编程语言 > Java开发

用序列化的方式保存简单的数据类型之积分查询系统的建设

2014-03-15 00:00 288 查看
摘要: 一个简单的会员卡积分查询接口,由于数据量达到了50多万条,且无法用数据库间的数据交换进行数据同步,导致作者走了不少弯路,并最终抛弃了数据库。

最近有个小活,是做一个积分查询接口,由于积分系统是内部系统且无法连接外网,所以数据只能通过导出-导入的方式加入到积分查询接口的小系统中。

看到这里,你肯定认为这没什么呀,但我把以下条件列出后,你的想法可能会改变一些:

1、数据一共有50万条左右;

2、数据的导出只能用文本文件;

3、积分接口的数据库是mysql;

4、原卡库的数据库是mssqlsser2008;

5、要保证查询速度;

6、每日更新的数据大概有20000条左右;

7、积分接口所在服务器不允许远程连接数据库和远程登录,只能通过积分接口系统完成数据的导入;

8、服务器配置不高。

以上就是要求,根据需求,我先测试如何将这几十万条数据导入到数据库;首先存放数据的文本文件有10MB大小,初步我想的是如何将这个文件中的KV键值对转换成数据库能识别的sql语句,于是,我用了一下午的时间完成文件内容的转换... ... 或许你会问,怎么会用了一下午呢?应该很快吧?我要说编码的时间确实没用多少,但转换可就费时了,整个转换过程整整用了一整个下午!!!

试过才知道该方法不可行,那就分割数据文件吧,然后用多线程同时执行。我先把数据文件分割成没20000条一个文件,然后用线程分别转换,这次转换效果较第一次有很大改善,但依然用了将近一个小时。莫非java对字符串的处理这么费时?于是百度、google,没有找到有用的解释,好吧,那继续吧。

转换完成的sql文件有24MB大小,当我看到这个文件时,我预料到数据导入的速度也不会快。不过我还是执行了数据导入,结果我不想多说,总之,很惨。

惨归惨,不过数据好在都有了,那就做查询接口吧。轻车熟路,很快,一个带传输参数加密(其实就是编码)、验证身份和数据缓存的接口完成了,本地部署测试,一切正常,然后上传到服务器,当天一切正常。到第二天早上,我把新导出的文本文件(19000多条数据)上传到服务器并执行数据的转换和导入操作,通过日志查询页面,感觉系统响应速度奇慢,大约运行了两个小时后,页面停止响应,查看服务器状态,提示内存溢出,服务器配置本身就不高,我还在一个tomcat下部署了N个应用,看来撑不住了。

这个时候我有点心虚了,怎么办?不能每天搞这么个东西呀?在这后面我想了很多办法,如把文件2sql转换的工作放在前台用JS来实现,结果浏览器挂了;用lucene生成索引吧,无法完成有效的查询;... ...

最终,我想不行就试试serizable接口吧,把数据导入到继承了serizable接口的对象中,然后序列化到磁盘中,用的时候缓存到内存中,查询也快;经过将近一个小时的改造,除了最初的文件上传还保留外,其他的都改造了。改造完成的系统,文件上传到服务器端后,不再保存为文件,而是通过stream的方式读取数据并进行KV键值对的分离,然后存入MAP对象中。KV分离完成后,先将Map对象赋值给缓存供接口查询用,然后将map保存到磁盘,以便容器重启后可以重新导入数据,也相当于做了数据的持久化。

由于每天都有更新的数据,而这些数据中可能有需要将map中已有Key的value更新的,也可能有新加入的,这也正好是map的特性。

到目前为止,系统运行稳定,查询直接从内存中完成,且能经受住高强度负载,基本满意,但数据的转换速度还是有点慢,虽然已经使用了线程。

总结:做应用的一个习惯,就是挂载数据库,其实在做一些不复杂的且数据量不大的应用时,完全可以考虑序列化。不过序列化也有一些局限性,如某些数据对象是无法做序列化的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐