Rails中压缩存储文本数据
可任意转载,但必须在醒目位置以超链接形式标明文章原始出处和作者信息
原文地址:http://www.blogkid.net/archives/2676.html
原文地址:http://www.blogkid.net/archives/2676.html
继续压缩话题。之前写了 Rails生成压缩的静态缓存,以及配置nginx以支持直接发送压缩文件两篇文章。今天谈的是在Rails中,将大段文本内容以压缩格式存在数据库。这也是从公司的一个项目中获得的灵感。
原始需求
手头有一个结构简单的文本库,可以看做是key=>value。约180万条数据,2.8G(确实不算大,见笑了)。
实施过程
整个实施过程做到了无缝转换,不需要停服务。
第一步:将文本字段类型由TEXT修改为BLOB;新增一个is_gzip字段用于标识是否经过压缩,默认为0。
* 需要注意,BLOB和TEXT最长支持65535字节。
第二步,修改Rails相应的Model。代码示例(压缩content字段):
class TextData < ActiveRecord::Model def content if self.is_gzip Zlib::Inflate.inflate(super) else super end end def content=(info_content) super Zlib::Deflate.deflate(info_content, 9) self.is_gzip = true end end
再一次感叹super的便捷。修改代码后,需要重新部署一下Rails应用。
第三步,创建一个rake任务,用来批量做转换。关键部位只消这么做:
text_data.content = text_data.content text_data.save
第四步,在做过修改的表上做一次optimize table,以释放那些不需要的空间。
效果观察
- 经如上处理,2.8G数据只剩1.4G。如果用了Gzip而不用Deflate,有可能更小。
- IOWAIT未见明显下降。压缩前,单条记录理论上可以通过一次IO完成。
- 备份的速度确实有所提升,意料之中。
更多信息
- 这种思路同样适用于PHP、Python以及其他语言下的Web应用,只是在Rails中搞起来更为轻松。
- Mysql提供了Compress/Uncompress两个函数,但是不建议直接使用。一方面会增加数据库服务器计算的压力;另一方面,如果用了主从,每个服务器都得算一次。
- Zlib::Deflate.deflate 的第二个参数是压缩的level。我用随机数据测试,Level 9压缩后的体积比Level 1 小10%。
- 如果用了Sphinx之类的从数据库导出数据的全文检索引擎,此法需慎用。
February 16th, 2010 by 张磊


0 Responses to “Rails中压缩存储文本数据”