一道海量日志的随机选取问题
原题是这样的:
假设有100G的日志存在于磁盘之上,其中每条日志占用的空间不多于100个字节,现在从日志随机选取N条日志,保证每条日志的选取概率相同。
解1:
最简单且严格的做法是扫描日志两遍。
第一遍:统计出日志的总条数,M。
第二遍:扫描每条日志以N/M的概率选择该条日志,直到满足N条日志。
解法2:
由于每条日志的最大长度为100字节,因此日志数量至少有K = 1G条,因此可以在扫描日志的时候进行随机抽样,使用一个较大的概率比如 10 * N / K。 这样选择出的日志条数肯定会大于N,并且总量远小于100G。 接下来可以按第一种方法从样本中随机选择出N条日志。
PS: 解法1和2都比较简单,但是会存在一个非常严重的问题,都需要读取所有的日志,100G的数据在读取时会非常耗时,最理想情况下以厂商的标准最快可以达到80M/s,这样读取100G的数据同样需要1250s,即20多分钟。那有没有一种方法减少读取磁盘的数据量?
解法3:假设文件的总大小为S=100G,在逻辑上将文本分成B=100W块,则每个块的实际大小为K=S/B, 然后在逻辑上遍历这100W个块,给每个块1/1000的选择概率。这样按偏移量从中选取1000个块,在这1000个块中随机抽取N条日志。这样实际读取的数据量大小为100M, 这已经非常小。
注:第三种方法可以会在每个日志的选取概率上出现细微的区别,但是由于数据量巨大,故这种差别可以忽略。