Bond——大数据时代的数据交换和存储格式
设想我们在一家很大的互联网公司做IT方面的规划、开发和维护,有以下这样的应用场景:
- 公司里有若干个不同的开发团队,开发语言有Java、.net、Python、C++....十来种,还有很多外包团队对项目进行开发,大中小系统已经多的数不过来;并且各个团队、系统间都需要进行海量数据的交换(比如搜索引擎实时的数据,GPS物联网实时数据,电站的实时监控数据等),如何定义一种数据格式,使得各种平台和语言都能够兼容,交换的成本最低?
- 如此多的结构化、非结构化数据都需要进行存储,有几百个哈杜集群、数十万台、百万台服务器,数据存储在Hbase、RocksDb或者其他自己开发的数据库结构中,对查询的实时性很高(内存表个位数毫秒、SSD十几毫秒等)。如何用一种较为统一的格式存放这些数据?
相信在大公司或者在大公司做过外包的童鞋,都接触过这样一种数据对象,那就是Bond格式,目前Bond由M$维护,官方网站:https://github.com/microsoft/bond/,上面提供了各种语言的示例、编译工具等。
一个基本的Bond文件如下所示:
namespace School
struct Student
{
0: string Name;
1: uint8 Age;
2: bool IsBoy;
3: optional vector<string> Interests;
}
这里定义了一个学校的命名空间,里面有个学生类,学生类里面有四个字段,依次是姓名、年龄、是否为男孩、兴趣爱好的列表(可选)。
很容易看出Bond结构实际是与平台和语言无关的,它是一个DSL,在不同的平台上,利用Bond编译工具gbc,可以把Bond文件编译成不同的类,然后就可以赋值、存储和传输了,编译好的Bond原生支持RPC调用。
Bond支持的数据类型有:
- 基本类型:int8, int16, int32, int64, uint8, uint16, uint32, uint64, float, double, bool, string, blob等,需要注意java平台没有uint类型,会编译成带有符号的同类型,数据会丢失精度(正数变成负数);
- 列表 vector、字典 map
- 枚举 enum
- 默认值
- 可选字段 optional,必须字段 required
- 可空字段 nullable
- 支持类的继承
- 支持字段的修饰 Attribute,这对前端验证和数据库存储比较有用,能定义字段长度、范围、列族等
这些类型能很好的满足数据交换和存储的需要;除此以外,Bond是一种非常高效的数据存储格式,它的二进制序列化最大程度去除了元数据的影响,极其紧凑,我们来看一个示例:
ListingItem是一个Bond类型,它的结构定义如下:
struct ListingItem
{
1: required uint64 xxxxxxxxx;
2: required uint8 xxxxxxxxx;
3: optional uint16 score;
4: optional vector<xxxx> xxxxxxxxxxx;
5: optional map<xxxxxx, uint16> xxxxxxxxx;
6: optional xxxxxx xxxxxxxxxxx = Exxxxx;
7: optional bool IsDeleted;
8: optional vector<xxxxxxxx> xxxxxxxxList = nothing;
}
由于牵涉到生产环境的真实数据,所以一些字段和引用使用xxxxx来代替了,这个类的大小中等,有各种字段,还有对其它类的引用和集合等等。
我们用随机化的方式生成一百万个类,类里面的字段和引用都不一样,数值都是随机生成的,然后用Bond序列化和Java中带的Gson序列化方式进行序列化后的二进制长度比较,渣代码如下:
@Test
public void ListingItemTest() throws IOException {
int cycleLength = 1000000;
Random random = new Random();
// Create 1000000 listing item
List<ListingItem> items = new ArrayList<>();
for(int i = 0; i < cycleLength; i ++){
ListingItem item = new ListingItem();
// ...
//赋值省略,利用random.nextLong() nextInt()等给字段赋值
// ...
items.add(item);
}
StopWatch stopWatch = new StopWatch();
int length = 0;
stopWatch.start();
//Serialization Bond Object for 1000000 times
for(int i = 0; i < cycleLength; i ++){
byte[] bytes = BondSerializationUtils.serializeBondToBytes(items.get(i), ProtocolType.MARSHALED_PROTOCOL);
length += bytes.length;
}
stopWatch.stop();
System.out.println(String.format("Bond Serialization %d objects cost %d ms, avg length in bytes is %d", cycleLength, stopWatch.getTime(), length / cycleLength));
//Serialization as Json Object
length = 0;
stopWatch.reset();
stopWatch.start();
for(int i = 0; i < cycleLength; i ++){
String json = gson.toJson(items.get(i));
length += json.length();
}
stopWatch.stop();
System.out.println(String.format("Json Serialization %d objects cost %d ms, avg length in string is %d", cycleLength, stopWatch.getTime(), length / cycleLength));
}
在我的破笔记本(10代i5低功耗u)运行结果如下:
Bond Serialization 1000000 objects cost 1392 ms, avg length in bytes is 60
Json Serialization 1000000 objects cost 8837 ms, avg length in string is 310
由于Java字符串getBytes()后和原长度一样,所以我们可以把字符串长度看作二进制数组长度。
多运行几遍代码,可以看到,Bond序列化的速度比Gson序列化的速度快4到5倍,序列化后的大小也只有json的1/5。(使用不同的序列化协议,比如COMPACT_PROTOCOL可以进一步压缩结果大小和序列化时间,速度能比Json序列化快10倍以上)
这是个了不起的成绩,如果我们生产环境中每天产生上百亿条数据,这些数据用于各种转换、分析与统计,使用Bond结构存储只有使用字符串存储空间的1/5,能够省下4/5以EB、PB计的存储成本;而且由于数据量的减少,传输和计算的成本也进一步压缩,每年在IT基础设施上的投入能节约上百亿上千亿美元,这些节省的成本最后都是利润。
最后,由于Java平台没有自带二进制序列化框架,我们用.net自带的序列化框架测试下二进制序列化和Json序列化,序列化的类如下:
[Serializable]
public class TAListings
{
public string LxxxxxxxxList { get; set; }
public string Titles { get; set; }
public string CxxxxxxxxxxxxxxList { get; set; }
public string CxxxxxxxxxxxxxxxxList { get; set; }
}
代码如下:
TAListings listings = new TAListings() { CxxxxxxxxxxxxxxxxList= "5033333309:-:73333333333334,34444444442:-:744444444442,54444444449:-:744444444444444448,544444443:-:744444444444444" };
var binSerilization = BinaryHelper.Serialize(listings);
var jsonSerilization = JsonHelper.Serialize(listings);
Console.WriteLine(string.Join(" ", binSerilization.Select(f => f.ToString("x2"))));
Console.WriteLine("Binary Serilization Length: " + binSerilization.Length);
Console.WriteLine();
Console.WriteLine(jsonSerilization);
Console.WriteLine("Json Serilization UTF8 Length: " + Encoding.UTF8.GetByteCount(jsonSerilization));
Console.ReadLine();
结果如截图所示:

可以看到,如果只是普通的类,在.net使用二进制序列化后,反而比json序列化大了不少,增加的长度在二到四倍左右不等,这很反常识,是因为.net二进制序列化需要存储更多的元数据吗?
大家对我的文章有什么问题和建议,都希望能够参与讨论,谢谢大家!
Bond——大数据时代的数据交换和存储格式的更多相关文章
- 大数据时代的数据存储,非关系型数据库MongoDB
在过去的很长一段时间中,关系型数据库(Relational Database Management System)一直是最主流的数据库解决方案,他运用真实世界中事物与关系来解释数据库中抽象的数据架构. ...
- 大数据时代的数据存储,非关系型数据库MongoDB(一)
原文地址:http://www.cnblogs.com/mokafamily/p/4076954.html 爆炸式发展的NoSQL技术 在过去的很长一段时间中,关系型数据库(Relational Da ...
- ECharts – 大数据时代,重新定义数据图表
ECharts 基于 Canvas 的纯 Javascript 图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表.创新的拖拽重计算.数据视图.值域漫游等特性大大增强了用户体验,赋予了用户对 ...
- 大数据时代的IT架构设计
大数据时代的IT架构设计(来自互联网.银行等领域的一线架构师先进经验分享) IT架构设计研究组 编著 ISBN 978-7-121-22605-2 2014年4月出版 定价:49.00元 208页 ...
- (原创)大数据时代:基于微软案例数据库数据挖掘知识点总结(Microsoft 决策树分析算法)
随着大数据时代的到来,数据挖掘的重要性就变得显而易见,几种作为最低层的简单的数据挖掘算法,现在利用微软数据案例库做一个简要总结. 应用场景介绍 其实数据挖掘应用的场景无处不在,很多的环境都会应用到数据 ...
- 新书发布《大数据时代的IT架构设计》
<大数据时代的IT架构设计>以大数据时代为背景,邀请著名企业中的一线架构师,结合工作中的实际案例展开与架构相关的讨论.<大数据时代的IT架构设计>作者来自互联网.教育.传统行业 ...
- 跟上节奏 大数据时代十大必备IT技能(转)
新的想法诞生新的技术,从而造出许多新词,云计算.大数据.BYOD.社交媒体……在互联网时代,各种新词层出不穷,让人应接不暇.这些新的技术,这些新兴应用和对应的IT发展趋势,使得IT人必须了解甚至掌握最 ...
- 大数据时代的技术hive:hive介绍
我最近研究了hive的相关技术,有点心得,这里和大家分享下. 首先我们要知道hive到底是做什么的.下面这几段文字很好的描述了hive的特性: 1.hive是基于Hadoop的一个数据仓库工具,可以将 ...
- LinkedIn高级分析师王益:大数据时代的理想主义和现实主义(图灵访谈)
转自:http://www.ituring.com.cn/article/75445 王益,LinkedIn高级分析师.他曾在腾讯担任广告算法和策略的技术总监,在此期间他发明了并行机器学习系统“孔雀” ...
- 移动大数据时代最IN编程语言必读书单
移动大数据时代最IN编程语言必读书单 这是一个快速更迭,快鱼吃慢鱼的时代.从IT 时代演变成 DT 时代,再到现在的智能时代.急速革新的各种新技术.新工具.新平台,需要程序员掌握良好的编程思想和学习方 ...
随机推荐
- .NET有哪些好用的定时任务调度框架
前言 定时任务调度的相关业务在日常工作开发中是一个十分常见的需求,经常有小伙伴们在技术群提问:有什么好用的定时任务调度框架推荐的?今天大姚给大家分享5个.NET开源.简单.易用.免费的任务调度框架,帮 ...
- Nokia 5GC 产品概览
目录 文章目录 目录 Nokia SR OS Nokia NSP NFM-P Nokia 7750 SR-MG 5G User Plane Forwarding Mobile Gateway Non- ...
- 【winform】解决datagridview里放combox,combox不能按下键快速选择的问题
效果图: 一开始,是拖个下拉框到窗体上,用dgv.controls.Add(combox)添加到表格里,在通过表格事件,触发时,改变下拉框的位置和大小,这样做,下拉框是会出现在表格里,但是有问题,不能 ...
- layui-框架学习小总结
主要6点: 1.导航栏变成了类似tab的页签,支持关闭,点击刷新. 2.左侧菜单树可隐藏. 3.树的搜索. 4.表格的新增行,并保存到后台. 5.表格 加载 下拉框,并赋值,选择了值后把值同步到表格对 ...
- 一文详解编辑距离(Levenshtein Distance)
更多博文请关注:https://blog.bigcoder.cn 一. 什么是Levenshtein Distance Levenshtein Distance,一般称为编辑距离(Edit Dista ...
- linux开机出现initramfs无法进入系统
linux开机出现initramfs无法进入系统 开机后进入initramfs模式,无法进入系统时不要慌: 想一想自己根分区的文件系统名是什么,有的人的是/dev/sda1,有的人的是/dev/sda ...
- Part1--软件规范总纲
开发人员规范 软件代码编写规范 套话 目的:统一公司编码风格:提高代码易读性.可靠性和稳定性:减少软件维护成本提高生产力 基本原则:维持代码易读.可维护:保持代码清晰:尽可能复用代码 实用规则 缩进 ...
- 【论文笔记】R-CNN系列之代码实现
代码源码 前情回顾:[论文笔记]R-CNN系列之论文理解 整体架构 由三部分组成 (1)提取特征的卷积网络extractor (2)输入特征获得建议框rois的rpn网络 (3)传入rois和特征图, ...
- 异构数据源同步之数据同步 → DataX 使用细节
开心一刻 中午我妈微信给我消息 妈:儿子啊,妈电话欠费了,能帮妈充个话费吗 我:妈,我知道了,我帮你充 当我帮我妈把话费充好,正准备回微信的时候,我妈微信给我发消息了 妈:等会儿子,不用充了,刚刚有个 ...
- 再谈中断机制(APIC)
中断是硬件和软件交互的一种机制,可以说整个操作系统,整个架构都是由中断来驱动的.一个中断的起末会经历设备,中断控制器,CPU 三个阶段:设备产生中断信号,中断控制器翻译信号,CPU 来实际处理信号. ...