Protobuf: 大数据开发中的高效数据传输利器
作为一名大数据开发者,我经常需要处理海量的数据传输和存储。在这个过程中,选择一个高效、可靠的数据序列化工具至关重要。今天,我想和大家分享一下我在项目中使用 Protobuf 的经历。

目录
- 故事背景
- Protobuf 简介
- 优点:
- 实战案例
- 示例一:传感器数据
- 示例二:用户信息
- 示例三:复杂数据结构
- 性能对比
- 版本说明
- 总结
故事背景
在我们团队的一个项目中,我们需要从多个传感器收集实时数据,并将这些数据传输到集中式服务器进行分析。起初,我们使用的是 JSON 格式,因为它易于阅读和调试。然而,随着数据量的增加,我们遇到了性能瓶颈:数据传输的速度越来越慢,服务器的处理负荷也越来越重。
在这种情况下,我们开始寻找一种更高效的数据传输方案。经过调研和比较,我们最终选择了 Google 的 Protocol Buffers(简称 Protobuf)。
Protobuf 简介
Protobuf 是一种灵活、高效的序列化工具,由 Google 开发。它可以将结构化的数据序列化为二进制格式,这种格式比 JSON 或 XML 更加紧凑和高效。

优点:
- 高效的二进制格式:Protobuf 使用二进制格式进行数据传输,比 JSON 更小、更快。
- 强类型定义:通过 .proto 文件定义数据结构,保证了数据的严格类型约束。
- 多语言支持:支持多种编程语言,如 C++、Java、Python、Go 等。
实战案例
以下是几个使用 Protobuf 进行数据传输的示例:
示例一:传感器数据
首先,我们需要定义一个 .proto 文件,描述数据结构。例如,我们的传感器数据包含传感器 ID、时间戳和温度值,可以这样定义:
syntax = "proto3";message SensorData {int32 sensor_id = 1;int64 timestamp = 2;float temperature = 3;
}
然后,使用 protoc 编译 .proto 文件,生成相应语言的代码。假设我们使用 Python,可以运行以下命令:
protoc --python_out=. sensor.proto
接下来,我们可以编写 Python 代码来序列化和反序列化数据:
import sensor_pb2# 创建一个 SensorData 对象
sensor_data = sensor_pb2.SensorData()
sensor_data.sensor_id = 1
sensor_data.timestamp = 1623072023
sensor_data.temperature = 23.5# 序列化为二进制数据
serialized_data = sensor_data.SerializeToString()# 反序列化为对象
sensor_data_parsed = sensor_pb2.SensorData()
sensor_data_parsed.ParseFromString(serialized_data)# 打印结果
print(f"Sensor ID: {sensor_data_parsed.sensor_id}")
print(f"Timestamp: {sensor_data_parsed.timestamp}")
print(f"Temperature: {sensor_data_parsed.temperature}")

示例二:用户信息
假设我们需要传输用户信息,包括用户 ID、用户名和邮箱地址,可以定义如下的 .proto 文件:
syntax = "proto3";message User {int32 user_id = 1;string username = 2;string email = 3;
}
同样地,使用 protoc 编译 .proto 文件,生成相应的 Python 代码:
protoc --python_out=. user.proto
然后,编写 Python 代码来处理用户信息:
import user_pb2# 创建一个 User 对象
user = user_pb2.User()
user.user_id = 123
user.username = "Alice"
user.email = "alice@example.com"# 序列化为二进制数据
serialized_user = user.SerializeToString()# 反序列化为对象
user_parsed = user_pb2.User()
user_parsed.ParseFromString(serialized_user)# 打印结果
print(f"User ID: {user_parsed.user_id}")
print(f"Username: {user_parsed.username}")
print(f"Email: {user_parsed.email}")
示例三:复杂数据结构
如果我们需要传输更复杂的数据结构,例如用户信息包含多个地址,可以定义如下的 .proto 文件:
syntax = "proto3";message Address {string street = 1;string city = 2;string state = 3;string zip = 4;
}message User {int32 user_id = 1;string username = 2;string email = 3;repeated Address addresses = 4;
}
编译 .proto 文件,生成相应的代码:
protoc --python_out=. user.proto
然后,编写 Python 代码来处理复杂数据结构:
import user_pb2# 创建一个 User 对象
user = user_pb2.User()
user.user_id = 123
user.username = "Alice"
user.email = "alice@example.com"# 添加地址
address1 = user.addresses.add()
address1.street = "123 Main St"
address1.city = "Springfield"
address1.state = "IL"
address1.zip = "62701"address2 = user.addresses.add()
address2.street = "456 Oak St"
address2.city = "Metropolis"
address2.state = "NY"
address2.zip = "10001"# 序列化为二进制数据
serialized_user = user.SerializeToString()# 反序列化为对象
user_parsed = user_pb2.User()
user_parsed.ParseFromString(serialized_user)# 打印结果
print(f"User ID: {user_parsed.user_id}")
print(f"Username: {user_parsed.username}")
print(f"Email: {user_parsed.email}")for address in user_parsed.addresses:print(f"Address: {address.street}, {address.city}, {address.state} {address.zip}")
性能对比
为了展示 Protobuf 的优势,我们做了一个简单的性能对比实验。在相同的数据量下,我们分别使用 JSON 和 Protobuf 进行序列化和反序列化,并比较两者的性能。
以下是 Python 代码示例,用于对比 JSON 和 Protobuf 的性能:
import time
import json
import sensor_pb2# 生成样本数据
data = {"sensor_id": 1,"timestamp": 1623072023,"temperature": 23.5
}# JSON 序列化和反序列化
start_time = time.time()
for _ in range(100000):json_data = json.dumps(data)data_parsed = json.loads(json_data)
end_time = time.time()
json_time = end_time - start_time# Protobuf 序列化和反序列化
sensor_data = sensor_pb2.SensorData()
sensor_data.sensor_id = 1
sensor_data.timestamp = 1623072023
sensor_data.temperature = 23.5start_time = time.time()
for _ in range(100000):serialized_data = sensor_data.SerializeToString()sensor_data_parsed = sensor_pb2.SensorData()sensor_data_parsed.ParseFromString(serialized_data)
end_time = time.time()
protobuf_time = end_time - start_timeprint(f"JSON time: {json_time} seconds")
print(f"Protobuf time: {protobuf_time} seconds")
结果显示,Protobuf 的序列化和反序列化速度远高于 JSON,尤其在数据量较大的情况下,这种优势更加明显。
版本说明
2.x 早就过时了

现在都用 4.25x 这样的,甚至是 5.27x,对应的编译器版本是 27x

总结
通过这些示例,我们可以看到 Protobuf 在大数据传输中的强大优势。它不仅提高了数据传输的效率,还保证了数据的类型安全。
如果你的项目中也需要处理大量的数据传输,不妨尝试一下 Protobuf,如果不大量还是 json 吧~
相关文章:
Protobuf: 大数据开发中的高效数据传输利器
作为一名大数据开发者,我经常需要处理海量的数据传输和存储。在这个过程中,选择一个高效、可靠的数据序列化工具至关重要。今天,我想和大家分享一下我在项目中使用 Protobuf 的经历。 目录 故事背景Protobuf 简介优点: 实战案例示…...
MySQL 面试相关问题
写在前面: 不喜勿喷,暴躁作者又不求你给钱【没办法,遇见的狗喷子太多了🐶】欢迎大家在评论区留言,指正文章中的信息错误有一些其他相关的问题,可以直接评论区留言,作者看到会及时更新到文章末尾…...
java org.aeonbits.owner库介绍
org.aeonbits.owner 是一个用于简化Java应用程序配置管理的库。它通过使用接口和注解来定义和读取配置,使得配置管理更加简洁和类型安全。以下是对这个库的一些主要特性和功能的介绍: 主要特性 类型安全的配置: OWNER 库允许开发者使用接口定义配置,从而提供了编译时的类型…...
YOLOv10改进 | 添加注意力机制篇 | 添加LSKAttention大核注意力机制助力极限涨点
一、本文介绍 在这篇文章中,我们将讲解如何将LSKAttention大核注意力机制应用于YOLOv10,以实现显著的性能提升。首先,我们介绍LSKAttention机制的基本原理,它主要通过将深度卷积层的2D卷积核分解为水平和垂直1D卷积核࿰…...
学习笔记——动态路由——IS-IS中间系统到中间系统(特性之路由撤销)
6、路由撤销 ISIS路由协议的路由信息是封装在LSP报文中的TLV中的,但是它对撤销路由的处理和OSPF的处理方式类似。 在ISIS中撤销一条路由实则是将接口下的ISIS关闭: 撤销内部路由: 在ISIS中路由信息是由IP接口TLV和IP内部可达性TLV共同来描…...
智能无人机控制:STM32微控制器与机器学习集成(内附资料)
智能无人机控制结合了STM32微控制器的实时处理能力和机器学习算法的决策能力,以实现更高级的自主飞行和任务执行。以下是智能无人机控制系统的概述,包括系统架构、关键组件、集成方法和示例代码。 系统概述 智能无人机控制系统利用STM32微控制器进行实…...
力扣 454四数相加
这个题给了四个数组,可以两两判断,就类比两数相加那道题了 对于num1 num2 用unordered_map存储,key是num1,num2中数字相加之和,value是值出现的次数 for(int a:num1) {for(int b:num2 {map[ab]; 最后要计算四个数…...
Java面试题系列 - 第9天
题目:深入探讨Java中的设计模式及其应用场景 背景说明:设计模式是软件工程中解决问题的常见方案,它们提供了经过验证的模板,帮助开发者解决在软件设计过程中遇到的特定问题。在Java中,熟悉并正确应用设计模式能够显著…...
数据结构【顺序表】
目录 线性表 顺序表 概念与结构 分类 静态顺序表 动态顺序表 动态顺序表的实现 在头文件中创建结构体 初始化顺序表 销毁顺序表(可以留到后面再看) 尾插数据 申请空间 打印顺序表数据 头插数据 尾删除数据 头删除数据 在指定位置插…...
【JavaScript 报错】未捕获的类型错误:Uncaught TypeError
🔥 个人主页:空白诗 文章目录 一、错误原因分析1. 调用不存在的方法2. 访问未定义的属性3. 数据类型不匹配4. 函数参数类型不匹配 二、解决方案1. 检查方法和属性是否存在2. 使用可选链操作符3. 数据类型验证4. 函数参数类型检查 三、实例讲解四、总结 在…...
html+css+js随机验证码
随机画入字符、线条 源代码在图片后面 点赞❤️关注😍收藏⭐️ 互粉必回 图示 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"…...
WPS打开PDF文件的目录
WPS打开PDF文件的目录 其实WPS中PDF文件并没有像Word那样标准的目录,但是倒是有书签,和目录一个效果 点击左上角书签选项,或者使用Alt Shift 1快捷键即可...
常见 Web漏洞分析与防范研究
前言: 在当今数字化时代,Web应用程序扮演着重要的角色,为我们提供了各种在线服务和功能。然而,这些应用程序往往面临着各种潜在的安全威胁,这些威胁可能会导致敏感信息泄露、系统瘫痪以及其他不良后果。 SQL注入漏洞 …...
暗黑魅力:Xcode全面拥抱应用暗黑模式开发指南
暗黑魅力:Xcode全面拥抱应用暗黑模式开发指南 随着苹果在iOS 13和iPadOS 13中引入暗黑模式,用户可以根据自己的喜好或环境光线选择不同的界面主题。作为开发者,支持暗黑模式不仅能提升用户体验,还能彰显应用的专业性。Xcode提供了…...
【游戏引擎之路】登神长阶(七)——x86汇编学习:凡做难事,必有所得
5月20日-6月4日:攻克2D物理引擎。 6月4日-6月13日:攻克《3D数学基础》。 6月13日-6月20日:攻克《3D图形教程》。 6月21日-6月22日:攻克《Raycasting游戏教程》。 6月23日-7月1日:攻克《Windows游戏编程大师技巧》。 7月…...
在 Windows 平台搭建 MQTT 服务
引言 MQTT 是一种轻量级、基于发布/订阅模式的消息传输协议,旨在用极小的代码空间和网络带宽为物联网设备提供简单、可靠的消息传递服务。MQTT 经过多年的发展,如今已被广泛应用于资源开采、工业制造、移动通信、智能汽车等各行各业,使得 MQ…...
jdevelope安装
准备 1.jdk1.8(已经安装不做记录) 2.下载jdevelope安装包 3.安装包安装jdevelope开发工具 4.创建或导入项目 下载jdevelope安装包 官网下载地址:https://edelivery.oracle.com 安装包安装jdevelope开发工具 cmd管理员权限运行安装脚本…...
排序(一)——冒泡排序、直接插入排序、希尔排序(BubbleSOrt,InsertSort,ShellSort)
欢迎来到繁星的CSDN,本期的内容主要包括冒泡排序(BubbleSort),直接插入排序(InsertSort),以及插入排序进阶版希尔排序(ShellSort)。 废话不多说,直接上正题! 一、冒泡排序 冒泡排序…...
synchronized关键字详解(全面分析)
目录 synchronized关键字详解1、synchronized关键字简介2、synchronized作用和使用场景作用使用场景①、用在代码块上(类级别同步)②、用在代码块上(对象级别同步)③、用在普通方法上(对象级别同步)④、用在静态方法上(类级别同步)总结: 3、synchronized底层原理&am…...
数据建设实践之大数据平台(三)
安装hadoop 上传安装文件到/opt/software目录并解压 [bigdatanode101 software]$ tar -zxvf hadoop-3.3.5.tar.gz -C /opt/services/ 配置环境变量 [bigdatanode101 ~]$ sudo vim /etc/profile.d/bigdata_env.sh export JAVA_HOME/opt/services/jdk1.8.0_161 export ZK_HO…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
