1 客户端是单线程,一次性传输100条数据,费时1分钟;
2 客户端单线程主要是避免 数据重复传输
3 主要实现从客户端mysql数据库向中心oracle上传数据,中心发布接口服务在tomcat
4 整个流程:部署客户端服务(tomcat),查询是否有需要传输的数据---分页查询100条,改变要传输数据状态---组装成json---调用中心发布的接口服务----中心接受到客户端请求解析数据,保存成功,返回给客户端结果,客户端删除传输成功的数据---客户端提示上传成功
目前最大的问题就是效率低下,中心在收到请求以后到写入oracle成功的这段时间,传输100数据耗时1分钟。一共70个客户端,一个中心
求解:怎样提高传输速度
不要凭感觉,还是找出在那里执行最耗时,在针对性做出优化.
能不能直接从mysql直接入库到oracle数据库
@花开半夏雨: MySQL能不能导出Oracle不知道,即使能到,那你的客户端还要吗? 看来你还没找在哪里耗时,还是找出现在系统的瓶颈在哪里,在去优化吧!
@秋壶冰月: 已经找到了,昨天对数据库优化过了,效果不是很明显,包括数据库大小,并发数量,缓存,建立索引,索引单独分区,。现在想的直接是mysql导出文件,再导入oracle数据库。
mysql导入到oracle可以用kettle,速度很快,你数据传输的慢的问题应该是你后台代码的问题,一般过滤查询的时候别用in,用exists 执行速度会很快
感觉没有说太清楚
100数据有多大?
你是怎么得出1分钟的,这1分钟包含了处理数据和数据库操作吗?
传输慢的原因是什么? 是网速慢?
100条数据,一条数据 样例 “20001;交通换乘枢纽;三公司;20010000000000000071;渝A60592;酉阳;大高二级;2017-06-05 00:00:00” 得出一分钟是在确认客户端发起请求以后,中心基本同时受到请求,开始计时,中心接受请求处理数据,写入oracle数据库,保存成功,计时结束 ,整个过程都有记录时间,目前怀疑是中心接受请求太多,需要处理的数据多,排队等候,导致写入数据库慢,效率低
@花开半夏雨:
看起来数据不是很大,应该不是网络的问题,
初步认为瓶颈在数据库操作
根据实际情况,可以考虑:
1. 数据库操作采用批量操作 类似 jdbctemplate的batchUpdate, 不要逐条操作,
2. 查看数据库服务器的压力,如果还可以的话,可以增加oracle数据库的最大连接数,同时调整工程的连接池的大小,或者直接把数据库操作改为并发, 增加数据库操作的并发量。
3. 数据库做集群,读写分离,减少读数据库照成的开销
@苍枫露雨: 是oracle11g的,表空间是users。
@苍枫露雨: 最后发现是中心接受数据解析为自定义对象以后。逐条循环根据数据主键判断中心是否存在,无则添加,有则修改。循环完所有数据进行插入或者更新比较耗时。基本100条数据1分钟左右
@花开半夏雨:
那就是了,可以改为批量操作,
比如根据主键判断这个可以直接用 select key from table where key in (k1,k2...,kn)
用返回的keys 比较in中的key,就知道哪些没了,
不知道你们是不是用的spring ,是的话批量插入和更新可以用 jdbctemplate的batchUpdate
@花开半夏雨: "逐条循环根据数据主键判断中心是否存在"===在多个客户端并发上传时,这个地方可能会有问题。如果有这样的时序:
1. 客户端a 判断 key = 'key_999' 是否存在,结果是不存在
2. 客户端b 判断 key = 'key_999' 是否存在,结果是不存在
3. 客户端a insert,
4. 客户端b insert,
结果会报错。
@Jacklondon Chen:两个客户端不会判断同一个主键
有几个优化办法:
1. 分页查询100条 ==增大到5000. 减少客户端与服务器端的网络交互,是性能优化的基本思想。
2. 100条数据,一条数据 样例... ==== 同一批次的所有数据,统一放在同一个 json 字符串中。不要一个数据,提交一次。同以上思想:减少客户端与服务器端的网络交互。
3. 客户端删除传输成功的数据 ==== 接口数据,按理一般保存若干时间,使用标志位来标明上传成功与否;或者另建一个表,作为上传成功/失败状态及记录。
4. 客户端是单线程...客户端提示上传成功 === 单线程的客户端提示,客户端刷新也需要时间。建议改成:成功只提示状态(开始上传、正在上传、结束上传、空闲等待),失败才提示详细信息;改成多线程是肯定的,单机版程序,主线程只用于显示,后台工作线程用于干活,可以控制启动只启动一个后台工作线程。
5. 增加服务器程序、客户端程序的文件日志。便于调试、调查问题、正式使用后的后续支持。
6. 中心发布接口服务在tomcat === 查 tomcat 文档,改允许的最大并发参数。
7. 数据库做集群 ===这么小的量,用不着。
1 客户端的数据是分类上传,并不是所有的数据都已一种。数据是随时产生的,就算一次上传5000,中心解析为自定义对象以后在,再向数据库插入,这个过程耗时,客户端长时间收不到中心反馈,连接超时()目前时间调整为5分钟)
2 100条数据是一次性写入一个jsonArray里边的
3 客户端有上传任务表,上传状态标识,当其他表有新增或者修改向任务表插入数据,根据主键关联查询上传数据。
4 客户端只有提示上传成功多少条的标识
5 有上传日志表记录,但未记录整体耗时
6 并发数设置的1000
@花开半夏雨:
有上传日志表记录 === 性能调优时,日志应记录在本地文件。可使用 log4j/log4net 之类的组件。日志写详细一点。log4j 的文件日志,每一个都带时间,写详细一点,能看出哪一段用时很多。
数据库日志,本身就会消耗较多的系统资源。如果数据库日志多的话,慢是肯定的。
@花开半夏雨:
客户端的数据是分类上传,并不是所有的数据都已一种 === 那就在 json 中,增加一个字段: 数据种类。争取一次上传所有种类的数据。
首先要通过文件日志来查明,哪一步用时较多,然后进行有针对的优化。
@Jacklondon Chen:是用表记录的,并不是日志文件
@Jacklondon Chen: 最后发现是中心接受数据解析为自定义对象以后。逐条循环根据数据主键判断中心是否存在,无则添加,有则修改。循环完所有数据进行插入或者更新比较耗时。基本100条数据1分钟左右
@花开半夏雨: 服务器端,接口数据的处理方法,应该是先将接收到的接口数据,保存到接口表中,稍作检查,立即返回信息给客户端。
不要同时做很多事情。
做接口程序,数据接收只做“数据落地”,纯 insert ,则性能会好。
其它复杂处理,由单独的后台线程/进程,读接口表,逐个处理。即使慢,客户端也看不到。
估计你们的数据库表索引设计有问题。
@Jacklondon Chen:索引有问题?
单个数据表做的索引是客户端ID的传输哪张表的主键 做的非唯一性索引
@花开半夏雨:
如果"数据主键判断中心是否存在,无则添加,有则修改",应该建立唯一性索引。
不知道你们此处,数据主键是一个字段,还是多个字段的组合。
另,也需要判断,数据解析为自定义对象,用时多长时间。
还是那句话,"通过文件日志来查明,哪一步用时较多,然后进行有针对的优化"
@Jacklondon Chen: 现在在想,不用封装以后再解析,不通过webservice,直接写一个程序从MySQL数据库直接抽取oracle数据库
1.或许可以考虑一次性提交吧多条数据整理成一个大集合上传;这样调用接口的次数就会少,如果你后台处理的足够快,很快就能完成;
2.改用异步方式;先提交上传数据,然后放到队列中后台来处理上传的数据,等处理完在通知调用方上传状态
目前是一次性提交多条数据的jsonArray,再解析为自定义对象集合
是你说的这个做法,先提交数据,等处理结果
1.查询的部分:可以考虑SQL语句、表结构、缓存等方面优化
2.提交的部分:增加吞吐量,可以考虑异步执行,让服务器端记录请求数据后立马返回请求结果,执行结果待稍后再请求查询。执行任务放在队列中,交给1个或多个工作单元来完成
客户端服务端都是自己写的吗?可以写个main方法,看看直接调用insert方法快不快。
性能调优从影响性能的主要因素去考虑。
不过一般是数据库引起的,你的数据量有多少?