当前位置:

首页 > 编程开发 > Protobuf 的 Bug 竟成为了它的 Feature

Protobuf 的 Bug 竟成为了它的 Feature

大家好,我是了不起。最近我们在项目中,通过使用protobuf格式作为存储数据的一个载体。一个不小心就给自己埋了个大坑,还是过了好久才发现。protobuf简介protobuf全名叫Protocalbuffers.它是由Google研发的,一种可跨语言、可跨平台、可扩展的序列化数据的机制。类似于XML,但是它更小、更快、更简单。你只需要定义一次你希望的数据如何被结构化,然后你可以使用它的生成工具,生成包含一些序列化和反序列化等操作的源代码。可以轻松地从各种数据流和使用各种编程语言写入

本文目录

    大家好,我是了不起。

    最近我们在项目中,通过使用 protobuf 格式作为存储数据的一个载体。一个不小心就给自己埋了个大坑,还是过了好久才发现。

    protobuf 简介

    protobuf 全名叫 Protocal buffers. 它是由 Google 研发的,一种可跨语言、可跨平台、可扩展的序列化数据的机制。类似于 XML ,但是它更小、更快、更简单。你只需要定义一次你希望的数据如何被结构化,然后你可以使用它的生成工具,生成包含一些序列化和反序列化等操作的源代码。可以轻松地从各种数据流和使用各种编程语言写入和读取结构化的数据。

    proto2版本支持在Java、Python、Objective-C和C++中生成代码。使用新的proto3语言版本,你还可以使用Kotlin、Dart、Go、Ruby、PHP和C#,还有更多的语言。

    怎么发现的?

    在我们的新项目中,我们通过使用 protobuf 格式来存储项目运行的数据。这样我们在调试过程中,可能根据现场录制的数据进行本地的调试。

    message ImageData {
    // ms
    int64 timestamp = 1;
    int32 id = 2;
    Data mat = 3;
    }
    
    message PointCloud {
    // ms
    int64 timestamp = 1;
    int32 id = 2;
    PointData pointcloud = 3;
    }
    
    message State {
    // ms
    int64 timestamp = 1;
    string direction = 2;
    }
    
    message Sensor {
    repeated PointCloud point_data = 1;
    repeated ImageData image_data = 2;
    repeated State vehicle_data = 3;
    }

    我们定义了这样一组数据, 然后存储的时候,因为Sensor 这3个数据源的帧率不一样,因此存储的时候,单个 Sensor 中其实只包含了一组数据,另外两个类型的数据并没有包含进去。

    当我们只录制单个 pack 的时候,我们并没有遇到问题。直到我们觉得单个包,不能长时间录制,我们需要找一种解决方法来分割包 。

    当时觉得这个一定是很简单的,我们就设定了一个包达到 500M 的时候,我们就让后面的数据存到新的包中。很顺利的写完,然后放到现场进行数据录制。录制一段时间之后,我们把包拿回来进行模拟测试我们的新程序。发现有些包的数据解析出来是有问题的。程序运行到一半会卡在那里不动。经过多次测试,发现是部分包有这个问题。

    我们一开始怀疑的是,判断文件大小的方式不对,影响到了分包。因为判断文件大小的时候,会去打开文件。但是经过好几种其他的不打开文件的方式判断,从而进行分割。还是遇到了部分录制的包有问题。

    这时我才怀疑到 protobuf 对存储数据会有一些特殊的要求。后来看了一些文章,了解到 protobuf 存储多组数据到一个文件需要有标志符。要不然后面从文件解析回来的时候,protobuf 因为不知道单个数据的停止符在哪里,导致数据解析出错。

    到这里,这个坑出现了。我们存储了一系列的数据到单个包中,没有做任何分隔符的操作。protobuf在解析的时候,把文件中所有的内容都解析成了单个Sensor。Sensor 中包含里所有数据, protobuf 主动合并了所有存储的数据。

    在这时,我才发现以前单包录制的时候,数据都是对的,那真的是我运气好。protobuf恰好解析成功了。

    怎么解决呢?

    既然知道 protobuf 会这么操作,那我们就只要知道 protobuf 怎么分割就行了。这个方法还真不好找,因为像我们这样使用的人太少了。中文搜索完全搜不到这一块的内容,可能大家都不会使用protobuf来存储数据吧,大家使用的方式应该都是多个服务中进行交互的场景吧。

    最终通过stackoverflow上的一些回答找到了答案,从回答中得知,这个解决办法在 protobuf 3.3 的时候,才正式被合并进去。看起来这个功能真的很少用啊。

    bool SerializeDelimitedToOstream(const MessageLite& message,
     std::ostream* output);
    bool ParseDelimitedFromZeroCopyStream(
    MessageLite* message, io::ZeroCopyInputStream* input, bool* clean_eof);

    通过这一对方法,可以对文件进行按照数据流一个一个的存储读取。再也不用担心数据被合并读取。

    当然通过这种方式存储的数据,不能被原来的解析方式所解析,存储的而进行格式完全变了。这种方式会先存储二进制数据的大小,再存储二进制数据。

    结束语

    经过一番折腾,终于搞定了这个分割的坑。使用场景可能比较小众,导致了很多资料根本找不到。靠自己看源码才发现这些问题。C++ 的源码真不好读,有很多的模板方法、模板类容易错过一些细节。最后还是看的C#的代码,才完全确认的。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    快影剪辑教程:分割、变速、字幕和音乐实用操作
    快影剪辑教程:分割、变速、字幕和音乐实用操作

    本文详解快影剪辑核心流程:导入素材后先完整播放标记断点,利用“分割”删除多余片段并保留半秒呼吸声;变速时重点动作保持1倍速,等待过程加快,需检查动作是否踩准音乐鼓点;最后添加字幕(置于画面下方偏中)并压低背景音乐音量,确保开头三秒有信息点且无错字黑屏。

    C++使用protobuf序列化数据教程
    C++使用protobuf序列化数据教程

    首先定义.proto文件描述数据结构,再用protoc生成C++代码,接着在程序中包含头文件并调用SerializeToOstream和ParseFromIstream进行序列化与反序列化,最后链接protobuf库完成构建。

    gRPC与Protobuf性能优化全攻略
    gRPC与Protobuf性能优化全攻略

    微服务通信性能优化的核心在于减少数据大小、提高序列化效率和优化网络传输。1.ProtobufSchema优化包括:优先使用int32、int64等基本类型,避免用string存储数字;将频繁字段放前面以提升Varint编码效率;列表元素少时使用packed=true减少overhead;互斥字段使用oneof避免冗余传输;用枚举代替字符串减少体积;删除无用字段。2.gRPC配置优化包括启用压缩(如gzip)减少传输量,合理使用连接池复用连接,采用流式传输处理大数据,配置keepalive参数维持长连接。3

    PHP开发:使用 Grpc 和 Protobuf 实现高性能 RPC 服务
    PHP开发:使用 Grpc 和 Protobuf 实现高性能 RPC 服务

    随着互联网技术的不断发展,分布式系统架构也变得越来越常见。RPC(RemoteProcedureCall,远程过程调用)作为一种面向分布式系统架构的通信方式,越来越受到开发者的关注。而在RPC服务的实现中,如何提高性能成为关键问题。本文将介绍如何使用Grpc和Protobuf实现高性能RPC服务。一、什么是Grpc和Protobuf

    PHP中如何使用array_chunk函数将数组分割成指定大小的块
    PHP中如何使用array_chunk函数将数组分割成指定大小的块

    在PHP中,经常需要对数组进行操作,其中一个常见的操作就是将数组分割为指定大小的块。这时,我们可以使用PHP内置函数array_chunk()来实现这一目的。array_chunk()函数的语法为:arrayarray_chunk(array$array,int$size[,bool$preserve_keys=FALSE])其中

    Vue 中的代码分割及懒加载技巧详解
    Vue 中的代码分割及懒加载技巧详解

    随着前端技术的快速发展,现代web应用已经变得越来越复杂。这些应用需要处理更多的数据和更复杂的业务逻辑,这就使得JavaScript应用程序的体积变得越来越庞大。这可能会导致应用启动速度下降,用户体验差。为此,Vue提供了一些高级特性来帮助优化你的应用程序。其中最重要的是代码分割和懒加载技巧。本文将详细解释Vue中的代码分割和懒加载技巧。我们将

    Go语言中字符串转换为数组的方法有哪些?
    Go语言中字符串转换为数组的方法有哪些?

    Go语言作为一门非常流行的编程语言,在处理字符串和数组之间的转换时提供了许多方便的方法。下面我们将介绍一些常用的方法,包括具体的代码示例。方法一:使用strings包的Split方法packagemainimport("fmt""strings")funcmain(){s

    闪电音频格式转换器怎样对音频进行分割处理-闪电音频格式转换器对音频进行分割处理的方法
    闪电音频格式转换器怎样对音频进行分割处理-闪电音频格式转换器对音频进行分割处理的方法

    很多人都会使用到闪电音频格式转换器软件,那么你们知道闪电音频格式转换器怎样对音频进行分割处理吗?下文小编就为你们带来了闪电音频格式转换器对音频进行分割处理的方法,感兴趣的用户快来下文看看吧。打开软件,在左侧选择“音频分割”功能,将需要处理的音频拖拽到软件中;将音频文件添加进来后,在右下角分割格式中选择需要的格式;分割模式目前支持以下两种,平均分割和按时长分割两种,可根据实际情况选择;以平均分割为例,输入需要分割的份数,点击右侧的√;设置输出目录,可选择自定义目录或原文件目录;最后点击选择右上角的“开始分割

    减小Win10录屏文件尺寸的解决方案
    减小Win10录屏文件尺寸的解决方案

    许多的小伙伴都需要录屏进行办公或者传输文件,但是有时候会出现文件过大的问题制造了很多麻烦,下面就给大家带来了文件过大的解决方法,一起看看吧。win10录屏文件太大怎么办:1、下载软件格式工厂来进行压缩文件。下载地址>>2、进入主页面,点击“视频-MP4”选项。3、在转换格式页面中点击“添加文件”,选择要压缩的MP4文件。4、点击页面“输出配置”,通过输出质量来压缩文件。5、下拉配置列表选择“低质量和大小”点击“确定”。6、点击“确定”完成视频文件的导入。7、点击“开始”进行转化。8、完成后即可

    MobileSAM:轻量级图像分割模型,为移动设备带来高性能
    MobileSAM:轻量级图像分割模型,为移动设备带来高性能

    一、引言随着移动设备的普及和计算能力的提升,图像分割技术成为了研究的热点。MobileSAM(MobileSegmentAnythingModel)是一种针对移动设备优化的图像分割模型,旨在在保持高质量分割结果的同时,降低计算复杂度和内存占用,以便在资源有限的移动设备上高效运行。本文将详细介绍MobileSAM的原理、优势和应用场景。二、MobileSAM模型的设计思路MobileSAM模型的设计思路主要包括以下几个方面:轻量级模型:为了适应移动设备的资源限制,MobileSAM模型采用了轻量级的神经网络

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。