想象一下,您必须存储大规模涌入量的数据。您的第一个优先级,确保您可以轻松地添加存储容量后,就是尝试减少数据的占用空间。但怎么样?这是Uber Engineering的综合编码协议和压缩算法测试的故事以及该学科如何保存了Suffersaless数据存储中的空间。
截至2016年初,许多数百万的旅行每天在600多个国家的400多个国家的400多个城市每天每天都会通过优步的平台。在服务之间,旅行数据通常通过杰森Blobs,通常占用20千字节(KB)一块。最终,跳闸数据存储在夹层中,优步的备份备份数据存储,用于进一步处理,计费和分析。SmancleAss本质上仅附加存储,所以数据堆积。
让我们做数学:每百万千克的每百万次旅行产生每天20千兆字节(GB)的行程数据。Smancleess将其数据存储在许多物理主机上。如果优步不是超高行公司和旅行增长,而是线性扩展,则为1 TBYTE(TB)的单个磁盘将仅持续51天。减去系统组件使用的〜40%的空间,您每位主机关闭到30天。因此,32 TB的安装持续了100万行程,<1年3百万个旅行,<4个月为1000万次 - 即,如果您存储原始JSON。
由于JSON数据非常适合压缩,我们确信我们可以找到一种可以在不牺牲性能的情况下挤压数据的算法。在一年中,每次旅行中每次旅行回收几百kB会拯救我们很多空间,让我们的房间成长。
协议问题
JSON通过更紧凑的语法桥接人类可读和机器之间的差距而不是SGML.和XML,但它仍然最终ASCII.。优化空间时的第一种自然步骤是使用二进制编码,然后在顶部放置压缩算法。
编码协议分为两个主要类别:使用A的协议idl.而那些没有。基于idl的编码需要模式定义。它们为消费者提供了关于数据格式和验证的安心,同时牺牲了模式发展的灵活性。基于非idl的编码通常是通用的对象序列化规范,它在固定类型系统上定义了紧凑的格式。它们提供了一个灵活的序列化机制,但只提供了对类型的基本验证。我们评估了三种基于IDL的编码协议和七种基于非IDL的编码:
| 编码协议 | 基于架构(IDL) | |
| 1 | 节约 | 是的 |
| 2 | 协议缓冲区 | 是的 |
| 3. | Avro. | 是的 |
| 4. | 杰森 | 没有 |
| 5. | ujson. | 没有 |
| 6. | COR. | 没有 |
| 7. | BSON | 没有 |
| 8. | MessagePack | 没有 |
| 9. | 元帅 | 没有 |
| 10. | 泡菜¹ | 没有 |
对于压缩,我们将三个无损和广泛接受的图书馆放入测试:
Snappy旨在提供高速和合理的压缩。BZ2交易速度以获得更好的压缩,而Zlib则落在它们之间。
测试
我们的目标是找到编码协议和压缩算法的结合,以最高速度最高的结果。我们在2,219伪随机匿名途中测试了编码协议和压缩算法组合优步纽约市(放入文本文件作为JSON)。我们在Python中写了一个测试脚本,以基准测试每个选项(IDL文件从跳闸JSON数据中手工制作,用于节俭,协议缓冲区和Avro)。然后,脚本上班。循环通过所有,脚本测量时间花费编码/解码,压缩/膨胀,以及尺寸的增益或损失。它在这里是伪代码:
通过尺寸和速度比较结果
对于大小,使用zlib压缩的协议缓冲区(PROTOBUF)的组合只比使用BZ2的Thrift稍微好一点,将数据压缩到未压缩JSON的8%以上。令人不安的是,存储pickle数据比只持久化原始JSON更糟糕。
为了速度,通过花费仅1548毫秒,节俭赢得了比赛:使用JSON与本机C ++备份实现需要的6535 MS中的23%,反之亦然。另一方面,本土Python Avro实现,在211,540 ms下运行:比本机JSON编码器慢32倍以上。有一个Fastavro.实施,声称是一个数量级,但它不是完整的功能,因此没有测试。
判决
可以在散点图中彼此互相评估每个编码和压缩选项的权衡。这帕累托前面在图中显示为红线,可能为我们提供最佳的解决方案:
基本上,左下角是我们的目标:小尺寸和短时间来编码和解码。
结论:
- 简单地使用Zlib压缩JSON将在尺寸和速度下产生合理的权衡。结果将只是一个更大的更大,但执行比在JSON上使用BZ2更快。
- 使用基于IDL的协议,用ZLIB或SNAPPY压缩的节俭和协议缓冲区将为我们提供最佳增益尺寸和/或速度。
由于JSON与Zlib压缩以来,事实上是一个很好的候选人,我们决定衡量剩余的竞争者反对该基线。因此,我们立即排除了速度或大小下降到JSON / ZLIB下方的任何选项。我们留下了以下候选名单:
| 编码器 | 编码(MS) | 解码(MS) | 大小(字节) | 尺寸因子 | 速度的因素 |
| protobuf zlib | 2158 | 925. | 10,885,018 | 46% | 34% |
| 节俭BZ2. | 5531. | 2003年 | 11,178,018 | 47% | 82% |
| Protobuf BZ2. | 5111. | 1738 | 12,023,408 | 51% | 75% |
| 节俭Zlib. | 1817. | 1147. | 12,451,285 | 53% | 32% |
| protobuf snappy. | 1224. | 790. | 14,694,130 | 62% | 22% |
| CBOR ZLIB. | 2573 | 2611 | 18,290,630. | 78% | 57% |
| messagepack zlib. | 4231. | 715. | 18,312,106 | 78% | 54% |
| Marshal Zlib. | 2095. | 1416. | 18567296年 | 79% | 38% |
| 节俭时髦的 | 628. | 1011. | 19,003,267 | 81% | 18% |
| ujson zlib. | 2956 | 1165. | 19917716年 | 85% | 45% |
| JSON zlib | 5561. | 3586. | 23,560,699 | 100% | 100% |
在2014年秋季之前,JSON结构通过优步的服务没有严格的架构执法。使用基于IDL的编码协议将要求我们定义IDL架构并在SMAFFALES中强制执行它们。这将原始列表还原为以下竞争者:
| 编码器 | 编码(MS) | 解码(MS) | 大小(字节) | 尺寸因子 | 速度的因素 |
| messagepack zlib. | 4231. | 715. | 18,312,106 | 78% | 54% |
| CBOR ZLIB. | 2573 | 2611 | 18,290,630. | 78% | 57% |
| Marshal Zlib. | 2095. | 1416. | 18567296年 | 79% | 38% |
| ujson zlib. | 2956 | 1165. | 19917716年 | 85% | 45% |
| JSON zlib | 5561. | 3586. | 23,560,699 | 100% | 100% |
Marshal,因为只是Python,默认是不存在的。带有zlib的JSON比包中的其他部分更大更慢,虽然这使得UJSON成为最快的候选,但它的大小仍然比CBOR和MessagePack稍大一些。最后一轮的评估在MessagePack和CBOR之间进行。CBOR被证明是较慢的,所以当脚本和判断结束时,带有zlib的MessagePack被保留。
MessagePack / Zlib是一个比使用没有压缩的Python JSON编码器的更好的选择。在编码较慢时,解码更快,相对尺寸是更好的数量级:
| 编码器 | 编码(MS) | 解码(MS) | 大小(字节) | 尺寸因子 | 速度的因素 |
| 杰森 | 3260. | 3275. | 132852837年 | 564% | 71% |
| messagepack zlib. | 4231. | 715. | 18,312,106 | 78% | 54% |
我们学到了什么
有太多的编码协议,以及丰富的压缩算法。我们在zlib定居了MessagePack。我们觉得这是我们Python的基于分布数据存储的最佳选择,没有严格的架构执法(艺术)。我们只发现了这种组合,因为我们采取了学科的方法来测试实际数据和生产硬件上的各种协议和算法组合。第一课学到:疑问时,投资基准。
我们在这种情况下保存了多少?让我们再次做数学,这次将20 KB减少86%以获得2,822个字节,尺寸增益由MessagePack + Zlib over原始JSON产生。乘以一百万的旅行,并且存储空间仅在3 GB下增加,而20 GB无压缩。1 TB磁盘现在将近一年(347天)(347天),与一个月(30天)相比没有压缩。假设具有32个TB容量和线性生长的平面安装,我们现在有足够的空间来维持超过30年与1年内相比,感谢挤压数据。
编码和压缩数据是一个聪明的举动,就像米其林三星餐厅一样,它值得一试。它不仅节省了空间;它还显著减少了花费在处理数据上的时间。在日常操作中,这直接转化为硬件,不需要购买、供应和配置。
¹Marshal和泡菜仅是Python。一般来说,它确认将数据的持久代表与任何特定语言系联系起来,但我们决定将它们包含在测试中以供参考。
Kåre Kjelstrøm是一名软件工程师和工程经理概要项目并在工作Uber Engineering.办公室在亚马,丹麦。
标题的照片学分:“蟒蛇,大西洋森林,东北巴伊亚,巴西“ 经过Alex Popovkin,巴伊亚,巴西许可CC-BY 2.0。图像裁剪的标题尺寸和颜色校正。
标题说明:蟒蛇收缩器固定和丧失攻击猎物把挤压在他们身上压力超过100KPA.(相同数量级A.香槟酒瓶爆裂。)
喜欢你在读什么?注册我们的通讯对于Uber Engineering Blti8 竞猜雷竞技appog的更新。雷竞技到底好不好用








