ToB企服应用市场:ToB评测及商务社交产业平台

标题: Bond——大数据时代的数据交换和存储格式 [打印本页]

作者: 饭宝    时间: 2024-7-8 15:26
标题: Bond——大数据时代的数据交换和存储格式
设想我们在一家很大的互联网公司做IT方面的规划、开发和维护,有以下这样的应用场景:
相信在大公司大概在大公司做过外包的童鞋,都打仗过这样一种数据对象,那就是Bond格式,现在Bond由M$维护,官方网站:https://github.com/microsoft/bond/,上面提供了各种语言的示例、编译工具等。
一个根本的Bond文件如下所示:
  1. namespace School
  2. struct Student
  3. {
  4.     0: string Name;
  5.     1: uint8 Age;
  6.     2: bool IsBoy;
  7.     3: optional vector<string> Interests;
  8. }
复制代码
这里定义了一个学校的命名空间,里面有个弟子类,弟子类里面有四个字段,依次是姓名、年龄、是否为男孩、爱好爱好的列表(可选)。
很容易看出Bond结构现实是与平台和语言无关的,它是一个DSL,在不同的平台上,利用Bond编译工具gbc,可以把Bond文件编译成不同的类,然后就可以赋值、存储和传输了,编译好的Bond原生支持RPC调用。
Bond支持的数据范例有:
这些范例能很好的满足数据交换和存储的需要;除此以外,Bond是一种非常高效的数据存储格式,它的二进制序列化最大程度去除了元数据的影响,极其紧凑,我们来看一个示例:
ListingItem是一个Bond范例,它的结构定义如下:
  1. struct ListingItem
  2. {
  3.     1: required uint64 xxxxxxxxx;
  4.     2: required uint8 xxxxxxxxx;
  5.     3: optional uint16 score;
  6.     4: optional vector<xxxx> xxxxxxxxxxx;
  7.     5: optional map<xxxxxx, uint16> xxxxxxxxx;
  8.     6: optional xxxxxx xxxxxxxxxxx = Exxxxx;
  9.     7: optional bool IsDeleted;
  10.     8: optional vector<xxxxxxxx> xxxxxxxxList = nothing;
  11. }
复制代码
由于牵涉到生产环境的真实数据,所以一些字段和引用利用xxxxx来代替了,这个类的大小中等,有各种字段,还有对其它类的引用和集合等等。
我们用随机化的方式生成一百万个类,类里面的字段和引用都不一样,数值都是随机生成的,然后用Bond序列化和Java中带的Gson序列化方式举行序列化后的二进制长度比较,渣代码如下:
  1.     @Test
  2.     public void ListingItemTest() throws IOException {
  3.         int cycleLength = 1000000;
  4.         Random random = new Random();
  5.         // Create 1000000 listing item
  6.         List<ListingItem> items = new ArrayList<>();
  7.         for(int i = 0; i < cycleLength; i ++){
  8.             ListingItem item = new ListingItem();
  9.             // ...
  10.             //赋值省略,利用random.nextLong() nextInt()等给字段赋值
  11.             // ...
  12.             items.add(item);
  13.         }
  14.         StopWatch stopWatch = new StopWatch();
  15.         int length = 0;
  16.         stopWatch.start();
  17.         //Serialization Bond Object for 1000000 times
  18.         for(int i = 0; i < cycleLength; i ++){
  19.             byte[] bytes = BondSerializationUtils.serializeBondToBytes(items.get(i), ProtocolType.MARSHALED_PROTOCOL);
  20.             length += bytes.length;
  21.         }
  22.         stopWatch.stop();
  23.         System.out.println(String.format("Bond Serialization %d objects cost %d ms, avg length in bytes is %d", cycleLength, stopWatch.getTime(), length / cycleLength));
  24.         //Serialization as Json Object
  25.         length = 0;
  26.         stopWatch.reset();
  27.         stopWatch.start();
  28.         for(int i = 0; i < cycleLength; i ++){
  29.             String json = gson.toJson(items.get(i));
  30.             length += json.length();
  31.         }
  32.         stopWatch.stop();
  33.         System.out.println(String.format("Json Serialization %d objects cost %d ms, avg length in string is %d", cycleLength, stopWatch.getTime(), length / cycleLength));
  34.     }
复制代码
在我的破条记本(10代i5低功耗u)运行结果如下:
  1. Bond Serialization 1000000 objects cost 1392 ms, avg length in bytes is 60
  2. 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序列化,序列化的类如下:
  1.     [Serializable]
  2.     public class TAListings
  3.     {
  4.         public string LxxxxxxxxList { get; set; }
  5.         public string Titles { get; set; }
  6.         public string CxxxxxxxxxxxxxxList { get; set; }
  7.         public string CxxxxxxxxxxxxxxxxList { get; set; }
  8.     }
复制代码
代码如下:
  1. TAListings listings = new TAListings() { CxxxxxxxxxxxxxxxxList= "5033333309:-:73333333333334,34444444442:-:744444444442,54444444449:-:744444444444444448,544444443:-:744444444444444" };
  2. var binSerilization = BinaryHelper.Serialize(listings);
  3. var jsonSerilization = JsonHelper.Serialize(listings);
  4. Console.WriteLine(string.Join(" ", binSerilization.Select(f => f.ToString("x2"))));
  5. Console.WriteLine("Binary Serilization Length: " + binSerilization.Length);
  6. Console.WriteLine();
  7. Console.WriteLine(jsonSerilization);
  8. Console.WriteLine("Json Serilization UTF8 Length: " + Encoding.UTF8.GetByteCount(jsonSerilization));
  9. Console.ReadLine();
复制代码
结果如截图所示:

可以看到,如果只是普通的类,在.net利用二进制序列化后,反而比json序列化大了不少,增长的长度在二到四倍左右不等,这很反常识,是由于.net二进制序列化需要存储更多的元数据吗?
大家对我的文章有什么问题和建议,都盼望可以或许到场讨论,谢谢大家!
    出处:https://thanks.cnblogs.com/    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面显着位置给出原文连接,否则保留追究法律责任的权利。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4