首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

使用数据库来进行图像分布式运算中的有关问题

2012-03-25 
使用数据库来进行图像分布式运算中的问题当前有个应用,需要数据库作同步,我想了很久,有些问题需要请各位高

使用数据库来进行图像分布式运算中的问题
当前有个应用,需要数据库作同步,我想了很久,有些问题需要请各位高人指点一下。
  在图像运算中,有些需要接近实时运算,例如,每秒钟需要运算20次以上。但是算法又太复杂,于是我计划使用LAN上的N台机机进行分布式运算,其中的N可能是随时变化的,现在大致计划30台左右。而且每台客户机的速度也可能不一样。数据库平台没有定,SQL或ORACLE 均可,算法使用 C++.net 或者C# 来实现。 
  我是这么构想的。算法是存储在EXE文件中,客户机执行这个EXE。
服务器上的表A:内容为需要运算的图片,定段为:
  int id//主键
  string FileName//源图片的定位
  int RunState//运算状态
  string CFileName//结果图片的输出位置
  服务器上对应每个需要运算的图像生成1张表,暂名为B。其字段为:
  int ID,//主键
  int PictID,//表A的对应ID
  int LineNO,//行号
  int Channel,//通道号,如果返回的结果不是灰度图,才需要这个字段
  int RunState,//当前运算情况
  string Count,//返回的结果

  客户机根据表A的内容,确定当前需要运算的源图,查找对应的表B,查看有哪些行还没有被运算,然后运算这个行。因为可能要跨行获取运算所需的参数,因此要先载入整个源图(如果已经下载当然就不用重新下了),然后将源图和需运算的行号输入到算法,算法计算出这一行的结果,将它转换成 char[],然后输出到表B/Count。
  当然了,里面的数据和文件同步算法很简单,就此略过。图像与字符串的相互转换已经完成,这个也不复杂。
  在数据库效率方面有两个限制:
  1.数据库的写入阶段需要锁定,否则会造成查询用户的返回错误。
  2.太多的连接或者频繁的打开关闭都会影响数据库的性能
  因为 1 和 2 的限制,使我不能采用频繁打开和关闭连接的方法,同时又不能打开连接,直到完成运算并写入数据才关闭。为此,我想了另外的一个方法,就是将结果字符串不写入数据表格中,将它以文本文件的方式传入文件服务器,然后连接到表B,将运算状态写入即可。
  请问这样做的话,效率是否会高一些?还会出现什么问题?
  事实上几乎所有的图像算法都是遂行遍历的,因此这个构架可以大范围推广,并且可以在WAN上运行。最后我打算用 JAVA 把算法和数据库操作都写成跨等平台的,MAC,UNIX都能够运行。

[解决办法]
在数据库效率方面有两个限制: 
1.数据库的写入阶段需要锁定,否则会造成查询用户的返回错误。 
2.太多的连接或者频繁的打开关闭都会影响数据库的性能 
这个是并发问题,应该用事务隔离呀,没必要老断开老连接吧
[解决办法]
可能出现的问题
运算端死掉, 解决办法-》某客户端一担开始进行某数据库中,来源数据行进行处理,对当行数据做处理中标记,统计记录当前数据库时间,,当其他客户端需要进行新的数据行运算时,查询当前正在运行的数据行,的开始运行时间,发现当前行处理时间过长(看你实际业务中算做异常的时间范围),则取代带他,自己去运算,同时覆写开始运算时间(当然也可以你做一个服务器端软件来做时时监控的方式实现)

[解决办法]
1-2张图片肯定可能比单机慢
何况还是1秒处理20多张图片?
,,,因为你这个处理办法,,存在机器性能差异,,读取数据库时间,,,等
怎么能和一切内存搞定,,,何况现在电脑CPU又NB,,,做好多线程就搞定了
但是只要没有其他技术上的问题,,,,在处理大批量的图片时
绝对性能会优异很多,。。
所以建议一次性,,,从数据库度取N张图片(这个需要你自己多测试看怎样的情况是最优的)
别一张一张搞

[解决办法]
1.并发问题,应该用事务隔离呀,没必要老断开老连接
2.注意死锁,多测试看看数据。
3.。。。,还在探索
[解决办法]
你可以考慮參考那種群集服務器實現方式,,,
网络负载平衡群集(简称NLB)
實現這種負載分配的問題

你圖片量大,,,牽涉個數據傳輸問題,,自然速度快不了,,,
要不處理完畢后圖片別回傳,,,就存在本地,,,只對數據庫中數據行,,做完成標記
所有行被標記完畢后,,再通過服務器端程式,,,去一一copy每個運算節點的文件
整合,並檢測是否有漏掉的,,,
[解决办法]
那就只有一个批次一个批次处理完毕后上传
在服务器端,,做一个队列,,
一个客户端完成一个批次的图片处理,则在这个队列上加入,,,并传回客户端的完整的完成图片的绝对路径文件夹名,已经完成的图片张数
由服务器端主动去客户端拷贝已处理完的整个图片包,,,拷贝完毕后验证图片张数是否与客户提交的数量一致。。。
考虑到客户端挂掉情况,,可以在服务器加入重试次数,,,

建议在数据库做客户端分发图片批次的时候,,,再做一个总表,,已一个编号到一个编号为一行,,,把整行作为一个用户一次读取来标实,就不需要一次update大量标识行了, ,,
[解决办法]
其实你这个程式数据库上的问题不大,,。
计算部分又在客户端,只要你一次拷贝足够量的图片到客户端,不太可能发生客户端频繁去访问服务器端的情况
主要是copy过来copy过去的时候,需要在服务器端做好输出队列,接收对列,避免大量的copy并发

当然如果条件允许,,,直接一次性让服务器用udp协议,像飞鸽传书一样(反正网络上又有源代码,借鉴过来用三),一次把处理源丢出去,基本就没有out数据的时候的问题,而接受的时候,只要服务器段有个数据表,来存储copy请求队列,基本就完全解决的并发问题了,,
但这必须要求客户端硬盘和服务器端硬盘一样大了, ,,,

还是得看你实际情况,和数据量大小问题
[解决办法]
嘛。。。反正你数据源放哪哪就是瓶井
毕竟图片拷贝,,,及站网络,,又站硬盘读写,,,,
在我看来,,,应该多个数据源,,,来减轻这个问题,,,
把图片,,,多少编号到多少编号放在哪,,,
路径放在数据库里,,,然后让客户端分别读,,这样才是最好的办法,,,


[解决办法]
不我的意思是,,,服务器一个完整的,,,数据源
分别切成4-7分,,分别放在4-7个比较好的电脑中(各自只放属于他的那一份,不重复),,,
然后让客户端根据数据库的中的绝对路径,,,去对应 小数据源中获取数据,,,


存在异常,,再去主服务器中,,获取数据
这样不知道行不?
[解决办法]
客户端处理后的上传目标必然是服务器,,,
缩小每次处理,上传颗粒大小,,,
就可以降低同步的时候,客户端出现问题的可能性和时间损失了啊,,,

处理每一批次向总服务器发送一次,请求拷贝进入服务器的拷贝队列,,,
请求完毕后,继续去新的数据源获取新的需要处理图片,,,
再进入处理状态,,,
而服务器只需要不停的,根据请求队列的依次去各个客户端拷贝数据,拷贝前当然先会确认客户端是否活跃状态,,,跳过不活跃的用户,,,每次拷贝完毕,准备拷贝下一个目标的时候,再去看下这些派在请求拷贝队列前面的,,,用户端是否已活跃,,,

[解决办法]
我觉得没必要每台都完全可服务器同步,,,而是让服务器作为一个严整错误,或者出现拥塞的时候一个备选数据源这样

整体的情况嘛意思就是

客户端->服务器获取一个待处理图片批次-》在数据库中标实该批次为我处理/记录开始处理时间/获取该批次数据源路径(数据源路径不在服务器上)->从数据源中获取图片到本地->开始处理->处理完毕-》到服务器数据库中,向请求上传队列提交一个拷贝请求申请,已经拷贝绝对路径,以及信息(a),并对数据库中标市该批次数据已处理完毕,更改当批次运算状态(如待处理是 w ,处理中是,r,待拷贝是c)-》循环-》若已经到图片批次末未,查看之前的行是否存在处理中时间过长的,或待拷贝时间过长的,,,从而进行再次运算

服务器在拷贝客户端数据之前,总是监视自己的上传队列表中是否存在请求-》发现a请求-》验证客户端是否活跃-》拷贝完成的图片数据到服务器->拷贝完毕-》检查是否与客户端提供的拷贝请求申请中的数据大小,或数量一致,不一致就将该批次数据update为待处理,等待其他客户端重新去处理,一致就update状态已完成-》继续监控请求拷贝队列中是否有数据-》若发现循环上面动作
[解决办法]
已一次处理一张图片的颗粒进行程式,,,那个效率必然低得可怜,,,毕竟你一张图片是1秒处理20张
光是去标记数据库行,再从数据源拷贝,,再考虑到并发的等待,,没1秒怕抓不下来吧,,,
这样相当于1/20的效率,,,等于你挂30台电脑
不如把程式拷贝到2个电脑上,,,分别各自运行自己那一半,,,

热点排行