ruby建索引解决大数据跨文件联合查询

上一篇 / 下一篇  2013-07-22 10:18:32 / 个人分类:ruby+watir

先说下之前的需求吧:
 两个文件,id和raw.dat.
  其中id文件内容格式如下:(大概存储有100万条数据)
 EF010684905A232CC624822188273588
  52FDAACD8B90F89F78D872746F8FD42
  C6815466197A2C3CF852C72D001E4E16
  4EE995ADEC8A5048FD9D5FB67C7313F5
  BE1F5CF3D30510A5B3BBF7FDF9BB2347
  83A10EC2B2F50DFA520C729E010D0A6C
  D8ED29C674F1985DE355CB6AA42B8132
  46946F7375CAE4D1C67130B597B6B748

  raw.dat文件格式如下:(大致也有150万数据)
 序号    id                                    格式    大小    码率
 1.  C7B645C8D6C7953CE5249FB22BF4A36B        mpeg4   5174630 114     361810
 2. 0ECB62B419BC54B99476515E603743EC        rv40    135320994       1943    557143
 3. 7D3F8B30E6948C1AA9D1158F5E314707        rv40    165899935       1709    776397
 4.  BF4E42F0DDE560AF308B87B2AF8BB702        rv40    345899278       2756    1003817
 5. 41BA03C4CB31B6F83651FEB4D0C76AFB        wmv3    266586561       815     2613609

  需求需要做的可以分两步:
   第一步, 拿id文件中的每一个Id到raw.dat中去找到对应的码率,然后存储起来
   第二步, 直接通过curl 的方式通过接口http://xproxy.ikan.baidu.com/fidinfo?ID=#{fid}获取id文件中的每一个id计算出来的码率
   第三步,将第一步和第二步的结果进行比对,给出两者不一致的地方

 
   因为是大数据的,所以算法很重要,普通算法运行时间太长,之前同事用linux的shell和Php写过一版,运行如此的数据单进程并不运用多线程的情况下需要运行13个小时之多,痛苦( ⊙o⊙ )哇,所以优化之路势在必行。
  好了,我是用ruby来实现的(其它语言都一样),运行完大概需要10分钟,下面说下思路:
   1. 先用ruby的哈希Map算法对raw.dat拿id作为key,码率字段作为value,建立索引并存储到内存,此过程大概需要2分钟,此过程是程序的核心也是最耗费时间的一个模块
   2. 索引建立完成后,然后拿id文件的每一行作为key将每一个id对应的value存储到a中
   3. 拿id文件进行循环,获取curl url的每一个值,存储到b中
   4. 拿a和b进行比对
   5. 循环id文件进行比对

最后,上程序,程序分两块,Base.rb和run.rb。
Base.rb文件内容见下方:
 require 'rubygems'
require 'hpricot'
require 'open-uri'
require 'net/http'
require 'rexml/document'
include REXML
require "rubygems"
require 'json'
module Base
 def createindex(f)
    @book=Hash.new
# File.open("test","r") do |x|
    File.open("raw.dat","r") do |x|
      content=x.readlines
      line=content.size
 
      for i in 0..line-1
 @book[content[i].split(' ')[0]]=content[i].split(' ')[4]
 end ##for end
   
  puts "index creat success!"
###############
puts "-----------------------"
   end
 end

 def get_curl(fid)
  begin
   @valid=[]
   url = URI.parse(URI::encode("http://xproxy.ikan.baidu.com/fidinfo?ID=#{fid}"))
   res = Net::HTTP.get(url)
        res = JSON.load(res)
si=res.size
res.each do |key,value|
@valid<<value
end   
        
countvalue= @valid[1][0]["rate"]
 rescue StandardError=>e
puts "\033[31m #{fid}'s is not the right format !\033[0m \n"
return 1
end
 
 end
end
 
其中run.rb文件内容如下:
  require 'rubygems'
require 'hpricot'
require 'open-uri'
require 'net/http'
require 'rexml/document'
include REXML
require "rubygems"
require 'json'
require 'Base'
include Base

#createindex(1)
def run(fidpath)
createindex(1)
 ###################################################
  File.open(fidpath,"r") do |fids|
 fid=fids.readlines
 n=fid.size
 for j in 0..n-1
 # puts j
 fid[j]=fid[j].strip
          rawvalue=@book["#{fid[j]}"]

 curlvalue=get_curl(fid[j]).to_s
          if rawvalue == nil || rawvalue== ""
 puts "\033[31m #{fid[j]}'s value, raw.dat's value is null!\033[0m \n"
 elsif rawvalue != curlvalue
 puts "\033[31m #{fid[j]}'s value, raw.dat's value is #{rawvalue}, but curl ratevalue is #{curlvalue}!\033[0m \n"
 else
 puts "ok"
 end
 end
  end
 end

  run(ARGV[0])

TAG:

 

评分:0

我来说两句

Open Toolbar