Protobuf: 大数据开发中的高效数据传输利器

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

在这里插入图片描述

目录

    • 故事背景
    • Protobuf 简介
          • 优点:
    • 实战案例
      • 示例一:传感器数据
      • 示例二:用户信息
      • 示例三:复杂数据结构
      • 性能对比
    • 版本说明
    • 总结

故事背景

在我们团队的一个项目中,我们需要从多个传感器收集实时数据,并将这些数据传输到集中式服务器进行分析。起初,我们使用的是 JSON 格式,因为它易于阅读和调试。然而,随着数据量的增加,我们遇到了性能瓶颈:数据传输的速度越来越慢,服务器的处理负荷也越来越重。

在这种情况下,我们开始寻找一种更高效的数据传输方案。经过调研和比较,我们最终选择了 Google 的 Protocol Buffers(简称 Protobuf)。

Protobuf 简介

Protobuf 是一种灵活、高效的序列化工具,由 Google 开发。它可以将结构化的数据序列化为二进制格式,这种格式比 JSON 或 XML 更加紧凑和高效。

image.png

优点:
  1. 高效的二进制格式:Protobuf 使用二进制格式进行数据传输,比 JSON 更小、更快。
  2. 强类型定义:通过 .proto 文件定义数据结构,保证了数据的严格类型约束。
  3. 多语言支持:支持多种编程语言,如 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}")

image.png

示例二:用户信息

假设我们需要传输用户信息,包括用户 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 早就过时了
image.png

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

image.png

总结

通过这些示例,我们可以看到 Protobuf 在大数据传输中的强大优势。它不仅提高了数据传输的效率,还保证了数据的类型安全。

如果你的项目中也需要处理大量的数据传输,不妨尝试一下 Protobuf,如果不大量还是 json 吧~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/45115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uView、ColorUI与Vant框架的深入分析与案例实践

摘要: 随着移动开发技术的不断发展,框架的选择对于项目的成功至关重要。本文将对uView、ColorUI和Vant这三个主流移动端框架进行深入分析,探讨它们的优缺点,并通过实际案例展示如何根据项目需求选择合适的框架。 一、引言 在移动…

【人工智能】-- 受限玻尔兹曼机

个人主页:欢迎来到 Papicatch的博客 课设专栏 :学生成绩管理系统 专业知识专栏: 专业知识 文章目录 🍉引言 🍉受限玻尔兹曼机 🍈RBM的结构 🍍RBM的架构图 🍍RBM的经典实现 &…

Python中对asyncio的实际使用

前言:一般涉及异步编程我都无脑用celery,但是最近在做一个项目,项目不大,也不涉及定时任务,所以就用了asyncio。 asyncio是python自带的模块,比celery轻量,使用起来也简单。以前学习过&#xf…

论文阅读【时空+大模型】ST-LLM(MDM2024)

论文阅读【时空大模型】ST-LLM(MDM2024) 论文链接:Spatial-Temporal Large Language Model for Traffic Prediction 代码仓库:https://github.com/ChenxiLiu-HNU/ST-LLM 发表于MDM2024(Mobile Data Management&#xf…

ArrayList----源码分析

源码中的简介: List接口的可调整数组实现。实现所有可选列表操作,并允许所有元素,包括null。除了实现List接口之外,这个类还提供了一些方法来操作内部用于存储列表的数组的大小。(这个类大致相当于Vector,只是它是不同…

TC软件许可优化解决方案

TC功能说明 Teamcenter 软件是西门子面向全球范围开发的数字化全生命周期管理(PLM)系统,将人员、产品、流程、知识有机联系在一起,以帮助企业实现数字化协同、数字化赋能、 数字化转型,从而推动企业产品创新与效率提升…

Java链表LinkedList经典题目

一.LinkedList的方法 首先先看一下链表的方法: 方法解释boolean add(E e)尾插void add(int index, E element)将 e 插入到 index 位置boolean addAll(Collection c)尾插 c 中的元素E remove(int index)删除 index 位置元素boolean remove(Object o)删除遇到的第一…

【EIScopus稳检索-高录用】第五届大数据与社会科学国际学术会议(ICBDSS 2024)

大会官网:www.icbdss.org 大会时间:2024年8月16-18日 大会地点:中国-上海 接受/拒稿通知:投稿后1-2周内 收录检索:EI,Scopus *所有参会者现场均可获取参会证明,会议通知(邀请函)&…

2022 RoboCom省赛题目解析

题目解析&#xff1a;这就是一题很简单的模拟&#xff0c;直接上代码&#xff1b; #include<iostream> using namespace std; const int N 10010; int arr[N]; int main() {int n , m;cin >> n >> m;int sum 0;int res 0;for(int i 0; i < n;i ) cin…

系统服务综合作业01

题目&#xff1a; 现有主机 node01 和 node02&#xff0c;完成如下需求&#xff1a; 1、在 node01 主机上提供 DNS 和 WEB 服务 2、dns 服务提供本实验所有主机名解析 3、web服务提供 www.rhce.com 虚拟主机 4、该虚拟主机的documentroot目录在 /nfs/rhce 目录 5、该目录由 no…

程序使用多进程,打包.exe后,程序陷入死循环

最近写了一个深度学习程序&#xff0c;用cxfreezee打包exe后&#xff0c;在本地运行突然出现死循环&#xff0c;明明在pycharm运行一切正常。 排查了问题&#xff0c;怀疑是多进程的原因&#xff0c;解决办法&#xff1a; 在你的主程序前添加一行代码&#xff1a; if __name_…

Pandas数学函数大揭秘:让数据处理变得如此简单高效,轻松玩转数据分析新纪元!

1.导包 # 导包 import numpy as np import pandas as pd2.聚合函数 df pd.DataFrame(datanp.random.randint(0,100,size(5,3))) df01203550281552376231419335895434679917 # 列非空元素的数量 df.count()0 5 1 5 2 5 dtype: int64# 行非空元素的数量 df.count(ax…

多输入多输出 | Matlab实现Transformer多输入多输出预测

多输入多输出 | Matlab实现Transformer多输入多输出预测 目录 多输入多输出 | Matlab实现Transformer多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现Transformer多输入多输出预测&#xff08;完整源码和数据&#xff09; 1.da…

二分查找算法——部分OJ题详解

目录 关于二分查找算法 部分OJ题详解 704.二分查找 一&#xff0c;分析题目 二&#xff0c;细节处理 三&#xff0c;题目代码 四&#xff0c;*总结朴素模板 *34.在排序数组中查找元素的第一个和最后一个位置 一&#xff0c;查找左端点 二&#xff0c;处理左端点细…

Socks5代理为何比HTTP代理快?

在网络世界中&#xff0c;代理服务器扮演着重要的角色&#xff0c;它们能够帮助我们访问被限制的网站、提高网络安全性以及优化网络性能。其中&#xff0c;Socks5代理和HTTP代理是两种常见的代理类型。然而&#xff0c;很多用户发现&#xff0c;相较于HTTP代理&#xff0c;Sock…

【两大3D转换SDK对比】HOOPS Exchange VS. CAD Exchanger

在现代工业和工程设计领域&#xff0c;CAD数据转换工具是确保不同软件系统间数据互通的关键环节。HOOPS Exchange和CAD Exchanger是两款备受关注的工具&#xff0c;它们在功能、支持格式、性能和应用场景等方面有着显著差异。 本文将从背景、支持格式、功能和性能、应用场景等…

嵌入式ARM控制器在AGV里的应用

随着ARM技术以及芯片加工工艺的迅猛发展&#xff0c; ARM工业计算机得到了越来越广泛的应用&#xff0c;尤其在工业智慧城市、智能设备以及工业自动化控制等领域。本文将为大家详细介绍ARM控制器在AGV控制系统中的应用&#xff0c;来供大家学习和参考&#xff0c;欢迎大家一起来…

Linux磁盘-创建分区

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux磁盘涉及到的命令不是很多&#xff0c;但是在实际运维中的作用却很大&#xff0c;因为Linux系统及业务都会承载到硬盘…

【PTA天梯赛】L1-003 个位数统计(15分)

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法刷题 &#x1f43e;或许会很慢&#xff0c;但是不可以停下来&#x1f43e; 文章目录 题目题解总结 题目 题目链接 题解 使用string把长度达1000位的数字存起来开一个代表个位数的数组 a[11]倒序计算最后一位&#xff0c;…

进度条提示-在python程序中使用避免我误以为挂掉了

使用库tqdm 你还可以手写一点&#xff0c;反正只要是输出点什么东西都可以&#xff1b; Demo from chatgpt import time from tqdm import tqdm# 示例函数&#xff0c;模拟长时间运行的任务 def long_running_task():total_steps 100for step in tqdm(range(total_steps), …