先说下之前的需求吧:
两个文件,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])