本文背景
由于笔者之前在工业类型的互联网公司工作过,曾经参与过一些工业软件应用的开发,因此知晓在当今社会,海量数据的应用实际上还是挺广泛的,特别是一直在说的工业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'], ]
- 支持的格式与转换
数组的元素支持以下数据类型
- number: Int8, UInt8, Int16, UInt16, Int32, UInt32, Float32, Float64
- string
- 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在路上,物联网也在路上,相应的技术方案也会百花齐放,面对海量数据的传输,针对不同类型需要选择合适的解决方案!
本文暂时没有评论,来添加一个吧(●'◡'●)