一想到 只要业务活着,日志数据就永远不会停止流到 hdfs上,可是 hdfs 容量是有限的,虽然时刻都有可能会扩容,我们要做的就是用有限的空间 解决无限 的数据存储,要想解决 空间问题,最主要的思想就是置换,用时间来置换空间,放在存储上,就是数据压缩 ,数据压缩要消耗时间,压缩后的数据 在计算时 如果不支持分片 会消耗更多时间,不能责怪。谁让你 穷逼一个,买不起机器 买不起硬盘
步入正题
正常来说 ,我们的日志数据在线上web服务器上生成 通过数据流管道输出到hdfs上,为了方便 日志的回溯,在线上机器上 日志会压缩备份。
如果读取实时日志,就都是原始的,scp put 会有 一个小时的延迟
使用 flume logstash kafka 可以做到 接近实时
如果修补数据 可以直接把之前天的 day.tar.gz scp put到 hdfs上,然后在hdfs上直接解压,可以做到 只解压部分文件,由于 一个tar有多种类型的文件 ,hadoop 在mapReduce 时直接读取 tar包类型输入文件还是支持不够友好的
然后解压后的日志 本身太大,需要再压缩成理想的格式,减少对空间的占用
有时候 感觉 某种压缩格式 对自己的需求不够友好,有需要转为另一种压缩格式
有时候我们希望 在 hadoop做一下 归档,把一个目录的文件再打成一个包包 tarball
总结一下,假设都是发生在hdfs上的
1.multi file type in one tar.gz To origin Files && could select file type for compress or decompress
- origin files To compress codec files
- one Compress Codec file To other Compress Codec file
- multi origin files To one Tar.gz
- compress Codec files To origin files
所以单纯数据压缩 解压缩 就有这些需求,另外解决上述问题就有三种方式 ,虽然都是需要编程,其中两种都有致命的缺点
第一种 就是使用 mapReduce 来做压缩和解压缩,
局限是不能操作 多文件类型的tar包,而且 生成的数据文件 命名 全部错乱,数据也会被打乱顺序,优点是利用集群资源 快,这个老大尝试了,但是我坚持没有尝试,主要是我认为 这个伤害太大,做了就没有后悔药了,无法撤回 对数据的影响
第二种 就是使用本地资源完成 压缩和解压缩,原理 其实就是 把hdfs 数据 get到本地,在本地 tar -zxvf unzip ,然后再 put到 hdfs 上 虽然也是编程实现的,能保证数据单个文件的完整性 正确,但是缺点 显然就是 超级慢,而且容易丢掉多个数据文件,我的尝试是一个目录下解压缩,最后总是有一些没有被put到hdfs ,修补数据让我非常恼火,需要一个个比对,超级繁琐。另外 这个 由于 使用append 的map类型,会造成数据的 格式稍微影响,所以耽搁文件的完整性并不能很好的保证,
第三种 简直是最完美的方案,利用集群资源 计算 传输解压缩 和压缩,使用hadoop 暴露出来的 操作 hdfs的接口 及hadoop本身自带的支持的压缩类完成数据压缩解压缩,不能太好了。稳定,验证数据也是完全完整,不丢数据,
快 准 稳 ,当然 从我大致翻遍 gayhub 上的资源,基本上没有非常合适这些场景的,看来给我留的时间就是 把这些开源了,造福广大人类 /手动微笑/,我在 尝试第三种方式时,其实还碰到了 写入的数据不完整性,总是少 几千行 几百行 但是我坚持认为 第三种方式必然是最完美的解决方案,通过不断拍错,debug,我找到了 符合预期的效果,并且也加深了我对 jvm上 inputsream outstream bufferStream
FSDataStream CompressionInputStream 等 流对象的深入了解。
好了,我把主要思想 都讲明白了 ,具体代码我择日 选择开源 供大家fork 膜拜 ,争取让你们用到生产环境中,我想 对于大部分公司,我们120T的都可以用,大家也不愁 不好使