Bond——大数据时代的数据交换和存储格式

news/2024/11/20 13:40:20/文章来源:https://www.cnblogs.com/thanks/p/18289706

设想我们在一家很大的互联网公司做IT方面的规划、开发和维护,有以下这样的应用场景:

  • 公司里有若干个不同的开发团队,开发语言有Java、.net、Python、C++....十来种,还有很多外包团队对项目进行开发,大中小系统已经多的数不过来;并且各个团队、系统间都需要进行海量数据的交换(比如搜索引擎实时的数据,GPS物联网实时数据,电站的实时监控数据等),如何定义一种数据格式,使得各种平台和语言都能够兼容,交换的成本最低?
  • 如此多的结构化、非结构化数据都需要进行存储,有几百个哈杜集群、数十万台、百万台服务器,数据存储在Hbase、RocksDb或者其他自己开发的数据库结构中,对查询的实时性很高(内存表个位数毫秒、SSD十几毫秒等)。如何用一种较为统一的格式存放这些数据?

相信在大公司或者在大公司做过外包的童鞋,都接触过这样一种数据对象,那就是Bond格式,目前Bond由M$维护,官方网站:https://github.com/microsoft/bond/,上面提供了各种语言的示例、编译工具等。
一个基本的Bond文件如下所示:

namespace Schoolstruct 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序列化方式进行序列化后的二进制长度比较,渣代码如下:

    @Testpublic void ListingItemTest() throws IOException {int cycleLength = 1000000;Random random = new Random();// Create 1000000 listing itemList<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 timesfor(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 Objectlength = 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();

结果如截图所示:
image
可以看到,如果只是普通的类,在.net使用二进制序列化后,反而比json序列化大了不少,增加的长度在二到四倍左右不等,这很反常识,是因为.net二进制序列化需要存储更多的元数据吗?

大家对我的文章有什么问题和建议,都希望能够参与讨论,谢谢大家!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/740530.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

订阅arXiv每日最新论文

邮箱订阅论文 arXiv 参考如何利用邮箱订阅 arxiv,接收每日最新的 arxiv 文章 订阅 订阅它的论文,需要用自己的邮箱像 arXiv 发送邮件。To: cs@arxiv.orgSubject: subscribe Your Nameadd Artificial Intelligencedel Systems and Control我们需要从arxiv.org上查找自己对应的方…

ali140滑块

ali140滑块记得加如我们的学习群: 961566389获取更多资讯。 ali 140滑块采用补环境的方式进行逆向,需要的文件主要为这两个,其中collina.js是最主要的环境校验和参数加密的逻辑,这两个文件放本地进行补环境。然后挂上代理,先保证能够正常运行代码,补了些许后能够正常运行…

【日记】我就是世界上最幸福的人!(1124 字)

正文今天想写的内容有点多,就不写在纸上了。首先,最高兴的,还是我们的《艾尔登法环》有了进展。我和兄长终于通过了 “火山官邸:地底拷问所”。我真是不知道,我和他在这个地方被那两个掳人少女人拷问了多少次了。不仅如此,拉塔恩也打过了,去了亚坛高原,反正进展很大。周…

机器学习-决策树算法详解

机器学习 决策树算法 实例决策树算法决策树算法是一种流行且功能强大的工具,用于机器学习、数据挖掘和统计学等各个领域。它们通过对不同变量之间的关系进行建模,提供了一种基于数据的决策的清晰直观的方法。本文将介绍什么是决策树、决策树的工作原理、决策树的优缺点以及…

【已解决】挖矿病毒 logrotate 185.196.8.123

185.196.8.123 logrotate如果你最近也中了这个病毒,看这篇文章就对了。 网上找了几篇类似文章,都是教你杀进程、删文件,但新版的病毒已经进化了,进程杀死复活,文件删掉又有了... 经过本人几天的尝试,最终找到了干掉他的方法。先确定下你的症状是不是跟我一样? 问题现象:…

分片集群平衡器Balancer

分片集群平衡器 MongoDB 平衡器是一个后台进程,用于监控每个分片集合中每个分片的数据量。当给定分片上的分片集合的数据量达到特定的 迁移阈值时,平衡器会尝试在分片之间自动迁移数据,并在尊重区域的情况下使每个分片的数据量达到均衡。默认情况下,平衡器进程始终处于启用…

Pytnon变量print打印计数显示前面补零 0001、0002

前言全局说明Pytnon变量计数显示前面补零 0001、0002一、说明 环境: Windows 11 家庭版 23H2 22631.3737 Python 3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32二、变量print打印计数显示前面补零 0001、0002 >>> fram…

CTF流量分析刷题(1)

简单的一道流量分析题目可以看到是传了一个webshell先URL解码,再进行base64解码可以看到是读取了flag.txt的内容,很容易即可拿到flag。

深耕分析型数据库领域,火山引擎ByteHouse入围《2024爱分析数据库厂商全景报告》

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群。近日,爱分析发布《2024爱分析数据库厂商全景报告》,报告中爱分析将数据市场从上至下划分为数据库服务、数据库运维管理产品、数据库产品三层,其中数据库产品又包括事务型关系数据库、…

AI Agent技术的最新进展与改变世界的典型项目巡礼

AI Agent技术的最新进展与改变世界的典型项目巡礼AI Agent技术的最新进展与改变世界的典型项目巡礼 1. AI Agent 技术发展以及典型项目 1.0 前 AI Agent 时代在学术探索的浩瀚星空中,机器人技术领域的璀璨明珠莫过于Agent技术的深入研究,这一领域历来是创新与突破的温床。回溯…

Unity读取xml文件

在XML中配置字典名称,字典的key和value,目前key和value都是用的string类型,通过ParseXml类的ParseData函数,传递字典名称和key来获取value xml文件内容解析数据类 using UnityEngine; using System.Xml; using System;/// <summary> /// 读取xml信息类 /// </summ…

【比赛】高一小学期2

【比赛】高一小学期2 题解挺唐的比赛,一道数位 dp 原题一道平衡树,然后 T1 数据范围还整错了。。没图了呜呜【比赛】高一小学期2$Rank$赛时日前赛后T1 同类分布 思路 印象里为数不多搞懂了的数位 dp,但过太久忘了,只能赛时打暴力 后来发现跟正解很接近了,只是在 dfs 前的预…