专业的编程技术博客社区

网站首页 > 博客文章 正文

阿里开源的海量数据高性能序列化方案——dimbin

baijin 2024-08-16 11:41:55 博客文章 11 ℃ 0 评论

本文背景

由于笔者之前在工业类型的互联网公司工作过,曾经参与过一些工业软件应用的开发,因此知晓在当今社会,海量数据的应用实际上还是挺广泛的,特别是一直在说的工业4.0时代。当初笔者参与研发的是一个叫做预测性维护平台的BS端互联网应用,每天都数据量都是千万到亿级别的,笔者之前接触的是MessagePack,相信也有人用过,尚且有一定的局限性!



什么是dimbin

dimbin是笔者在逛Github的时候发现的一个海量数据的序列化方案,而之前也对这样的技术需求比较敏感,因此也分享出来,供有此类需求的道友们作为参考,同时也提一下当下序列化选型的一些方案对比!本文提到的一些方案可能只适用于较大数据量级别的需求,如果数据量不大,那么JSON甚至是XML都还是比较好的序列化方案!

Github关键字:dimbin

dimbin是针对大量数据网络传输设计的序列化方案,用于储存多维数组通过直接内存操作实现高于 JSON 多个数量级的性能和更小的传输体积!

使用预览

  • 安装
npm install --save dimbin

  • 引用导入
import DIMBIN from 'dimbin' // v3
// import DIMBIN from 'dimbin/v2' // old version

  • 使用示例
const data = [
 [0, 1, 2, 3], // 普通数值数组 ?
 new Int16Array([1, 2, 3, 4]), // TypedArray ?
 [
 // 更高维度数组 ?
 [0, 1, 2],
 [0, 1, 2, 3, 4],
 ],
 DIMBIN.stringsSerialize(['a', 'bc', '']), // Array<string>
 DIMBIN.booleansSerialize([true, false, true, true]), // Array<boolean>
]
// 序列化为ArrayBuffer
const bin = DIMBIN.serialize(data)
// 反序列化为 Array<TypedArray>
const dim = DIMBIN.parse(bin)
dim[3] = DIMBIN.stringsParse(dim[3])
dim[4] = DIMBIN.booleansParse(dim[4])
/*
[
 Float32Array{0, 1, 2, 3},
 Int16Array{1, 2, 3, 4},
 [
 Float32Array{0, 1, 2},
 Float32Array{0, 1, 2, 3, 4},
 ],
 ['a', 'bc', ''],
 [true, false, true, true]
]
*/

  • 数据结构

DIMBIN 为多维数组而设计, 因此传入的数据结构必须为多维数组, 数组维数没有上限, 每一维度数组的元素个数上线为 2^32 . 维度和数组元素个数受运行环境和设备限制.


// 正确的格式
const input = [
 // Array
 [1, 2, 3],
 // TypedArray
 new Float32Array(1000),
 // higher dimensions
 [
 //
 [4, 5, 6],
 new Float64Array(2000),
 ],
]
const wrong1 = [
 // 必须为多维数组
 1,
 2,
 3,
]
const wrong2 = [
 // - 数组元素必须 *全部为数组* 或者 *全部为数值*
 [1, 2, 3, [4], [5]],
]
const wrong3 = [
 // 非数值数据需要先转换为数值数据
 ['123', 'hello'],
]

  • 支持的格式与转换

数组的元素支持以下数据类型

  1. number: Int8, UInt8, Int16, UInt16, Int32, UInt32, Float32, Float64
  2. string
  3. boolean

默认情况下, 所有的数据将使用 Float32 格式进行保存. 如果需要指定数据格式, 请先转换成 TypedArray. 如需要处理字符串和布尔值, 请使用对应的接口预先转换成 TypedArray

提供的方法(API)

  • serialize

序列化为二进制数据

  • @param {Array<TypedArray|Array<number|TypedArray|Array>>} data 多维数组
  • @param {float} magicNumber 用户控制的标识位
  • @return {ArrayBuffer}
  • parse

反序列化回多维数组

  • @param {ArrayBuffer|Buffer|DataView} buffer 序列化后的二进制数据
  • @return {Array<TypedArray|Array<TypedArray|Array>>}
  • getMeta

读取二进制数据的元数据

  • @param {ArrayBuffer|Buffer|DataView} buffer 序列化后的二进制数据
  • @return {Meta}
interface Meta {
 version: number
 magic_num: number
 seg_meta_bytes: number
 seg_meta_start: number
 len: number
 big_endian: boolean
}
  • stringsSerialize

将 Array 序列化成 TypedArray

  • @param {string[]} strs 元素为字符串的数组
  • @return {UInt8Array} 序列化后的二进制数据
  • stringsParse

将 stringsSerialize 生成的二进制数据解析回 Array

  • @param {UInt8Array} 序列化后的二进制数据
  • @return {string[]} 元素为字符串的数组
  • booleansSerialize

将 Array 序列化成 TypedArray

  • @param {boolean[]} strs 元素为布尔值的数组
  • @return {UInt8Array} 序列化后的二进制数据
  • booleansParse

将 booleansSerialize 生成的二进制数据解析回 Array

  • @param {UInt8Array} 序列化后的二进制数据
  • @return {boolean[]} 元素为布尔值的数组

性能

JS 环境下:当使用纯数值数据时

  • 序列化性能为 JSON 的 3-10 倍
  • 反序列化性能为 JSON 的 十万到百万 倍
  • 体积比 JSON 减小 60%

在 JS 环境中, 性能高于 flatbuffers 30%~100%, 远高于 protocolbuffers

序列化方案对比

  • protocol buffers
  • gRPC 所用的传输协议,二进制存储,需要 IDL,非自描述
  • 高压缩率,表达性极强,在 Google 系产品中使用广泛
  • flat buffers
  • Google 推出序列化方案,二进制存储,需要 IDL,非自描述(自描述方案不跨平台)
  • 高性能,体积小,支持 string、number、boolean
  • avro
  • Hadoop 使用的序列化方案,将二进制方案和字符串方案的优势结合起来,仅序列化过程需要 IDL,自描述
  • 然而场景受限,没有成熟的 JS 实现,不适合 Web 环境,这里不做对比
  • Thrift
  • Facebook 的方案,二进制存储,需要 IDL,非自描述
  • 基本上只集成在 RPC 中使用,这里不做对比
  • DIMBIN
  • 针对多维数组设计的序列化方案,二进制存储,不需要 IDL,自描述
  • 高性能,体积小,支持 string、number、boolean

以上是在DIMBIN作者和其他序列化方案对比,可以在仓库的wiki中查看原文,里面对序列化方案进行了比较深入和详细的对比以及,由于平台限制,不便于直接发出地址,感兴趣的小伙伴可以直接去看这篇文章,个人认为具有不错的参考价值!强烈建议查看原文!以下是动图一览,可能不够清晰!



总结

笔者认为在当今时代,尤其是在互联网和物联网时代,数据传输仍在占有绝对的地位,也出现过很多不错的解决方案,工业4.0在路上,物联网也在路上,相应的技术方案也会百花齐放,面对海量数据的传输,针对不同类型需要选择合适的解决方案!



Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表