在hadoop上构建版本化的文件存储

background: 我最近在做SEO项目,说实际点就是生成sitemap.xml给搜索引擎,但是百度最近给我提了一个新需求,让我把delete接口也合并到sitemap.xml中。也就是说,虽然我的sitemap.xml是一个全量数据,包含了我想提交给百度的所有url,但是如果,我今天4点生成的比3点生成的少了10条,那么这10条要依然保留在4点的xml中,并标记为is_deleted。于是,我的想法就是把历史生成的所有xml都保存起来,放在hadoop中,然后做diff。

然后我就实现了第一个版本的VersionedFolder。它在根目录下有一个名为VERSIONS的sequence file,key是版本号,value是时间(只是给人读)。然后在这个目录下有很多按照版本号命名的子目录,里面是具体存放数据。版本号是从1开始递增。写入的时候先读VERSIONS文件,得到最新的版本号,然后写数据,然后写VERSIONS文件。读的时候先读VERSIONS文件,然后fetch相应的数据。于是,以很简单的方式,就实现one-writer/multiple-reader。

我的生成程序会先读后台的数据库,然后把sitemap.xml写入hadoop中,然后写了一个很通过的fs_get工具,把这个文件download到httpd的目录下。

这个工具刚上线半天就救我于水火。事情是这样,baidu说我把一个不可播的视频输出给它了,我说我没有!我把sitemap.xml下载下来然后grep,找不到!百度说,你虽然现在没有,但是曾经有过,所以我要封你!然后我就背黑锅了。

我在开发这个新需求的时候,程序执行前,把输入数据在hadoop上存了一份,执行后,输出数据也在上面。然后baidu斥责我的时候,我拿着这些历史数据grep一下,问题立刻明了。我觉得我这个经验值得大力推广,尤其是数据的来源和输出涉及到跨部门、跨公司的时候。

我下一步的想法就是把这个VersionedFolder完善,把locking加进去。这样的话万一有多个进程同时写入也不会造成太恶劣的结果。然后拿它来备份mysql、备份线上程序包,瞬间我就有了一个容量无限大的time machine,有木有!!再下一步就是把写入完成后的notify加入进去,这样我就不是定时抓取,而是watch、fetch、mv。瞬间就改变了原本的apache啊!总之有了这层分离,我可以很轻松的把前端server交给运维去管。

再下一步就是我把我的seo程序挪到hadoop上去。之所以要这么做是因为我实在申请不到新机器,所以我尽量的用公共平台的存储、CPU,哪怕把原本一个20秒就能执行完的程序拖成5分钟。谁叫我是外包公司派来的呢。

此博客中的热门博文

少写代码,多读别人写的代码

在windows下使用llvm+clang

tensorflow distributed runtime初窥