1
j20001112 2023-04-16 11:40:33 +08:00 via Android
哪个 discord 群呀?
|
2
crysislinux 2023-04-16 11:48:22 +08:00 via Android
json 一眼就能看清是什么内容,大部分网站应该还不到扣这点性能的时候吧。以前看 Google 有些服务就不是 JSON
|
3
adoal 2023-04-16 11:54:11 +08:00
互联网的主流协议,大多都是底层需要效率和精确控制的用 binary ,上层易于理解和观察的用 text ,有特殊场景需要违背时才做反例。
|
4
c1985382 2023-04-16 11:54:25 +08:00 via iPhone
并没有省太多吧,key 还在数据里。要省流的话 protobuf 不是更好。
|
5
knightdf 2023-04-16 12:20:25 +08:00
单纯为了省流的话 protobuf 多好,但是现实是原来好多 protobuf 协议的接口现在都换成 json 了
|
7
Trim21 2023-04-16 12:56:25 +08:00 via Android 4
gzip 一下差不了多少,甚至有可能 json 更小。
而且在浏览器里用 messagepack 还要额外消耗 messagepack 解析库的流量。 |
8
billlee 2023-04-16 13:07:46 +08:00
HTTP 本来就是基于文本的,用 HTTP 的情况下就不考虑这点性能了
|
9
ch2 2023-04-16 13:15:03 +08:00
纯文本压缩太简单了
|
10
shyangs 2023-04-16 13:17:21 +08:00
gzip 之後的比較呢?
|
11
lesismal 2023-04-16 13:17:45 +08:00 10
1. MessagePack 和 Json 都是自释的,都带有了 key 信息,都是相当于动态结构
2. MessagePack 二进制、省去了 Json 的那些双引号、冒号、逗号、括号之类的,能省一些但毕竟 key 信息还在 3. PB 这种是 c/s 各自都持有了消息体的定义,根据消息定义的字段顺序进行序列化、反序列化时根据消息定义的字段顺序从 buffer 里挨个取出来解析就可以了,不需要把 key 信息也放到序列化后的数据里,而且本身也不需要引号冒号那些,所以节省更多。一些数值类型会做一些压缩,比如 int64 需要 8 字节但当前的值比较小、2 字节就够了,那就省一点。MessagePack 是否也有这个数值压缩我不记得了,好像是也有的 4. 不管用哪种,如果消息结构定义的重复率比较高、序列化后的包体 size 比较大,通常 gzip 之类的压缩算法加一道,就省更多了 用 Json 更灵活、自由、方便,版本更新升级做兼容性也容易 用 PB 更严格、工程化、规范,版本升级要考虑协议兼容性的更多、要考虑 c/s 是否必须同步停服维护升级之类的 MessagePack 挺不错,但是不如 Json 那种明文、方便调试之类的,它相比于竞品,优点都是处于中间水平,省流优秀但不是最佳、自释义但不明文,而且出生也晚,所以反倒是用的人最少 |
12
ikas 2023-04-16 13:18:07 +08:00
跨语言用了好几年了,写好序列化通用模块,与 json 一样易用
比如 java 端,直接使用 jackson |
13
Nazz 2023-04-16 13:24:59 +08:00 via Android
MessagePack 性能和便捷都不是最好的
|
14
tool2d 2023-04-16 13:27:20 +08:00 via Android
说到底,还是前端不善于处理二进制流数据。
js 有能完美处理二进制 api ,但是前端真正会的人群,估计不到 10%。 |
15
iseki 2023-04-16 14:19:04 +08:00 via Android
不差这点流量,现阶段人类可读比这点流量重要得多
|
16
akira 2023-04-16 15:03:19 +08:00
是能省,但是为啥要省。。。 而且,真要省流量的话,为啥不上个压缩算法,效果不更好么
|
17
duke807 2023-04-16 15:11:33 +08:00 via Android
msgpack 很好,代替 json 很方便
特别是支持二进制数据传输,图片、文件可以走同一套 api 传输 易用性和扩展性都是常规方案里面最优的,且序列化效率非常高 至于调试,把 msgpack 转字符串很容易,根本就不是借口 至于为何很多人不用 msgpack ,是因为没有眼光,不会选择好东西(也有一些是暂时不需要追求性能和传二进制,已经做好准备需要的时候再切换到 msgpack ) |
19
icyalala 2023-04-16 15:32:06 +08:00 2
如果服务仅限自己使用,那什么格式都无所谓,甚至自定义个私有格式也许在性能上更好。
如果你要给别人用,那当然要考虑最通用的,并不是每个人都有能力或者愿意去兼容其他更小众的格式。 何况 msgpack 在性能上并没有明显优势,不一定比得上 JSON 压缩+simdjson 。 在这个 json 已经是数据交换事实标准的情况下,你给别人提供服务用 msgpack ,那才是没眼光。 |
20
ysjiang4869 2023-04-16 18:41:41 +08:00 via Android
还有个 cbor ,效率更高好像,我之前和下位机对接使用的 cbor
|
21
silentsky 2023-04-16 19:40:02 +08:00 via Android
如果请求量很大的话还是有必要考虑 protobuf ,毕竟带宽也是需要钱的
|
22
weeei 2023-04-16 20:07:47 +08:00
|
23
realpg 2023-04-16 20:18:53 +08:00
brotli 之后比较呢
|
24
wellerman 2023-04-16 21:42:16 +08:00
就拿《我再也不敢装逼了》这个帖来说。一个新用户进去,啥也没干就能消耗掉接近 7M 的流量,json 换 MessagePack 就没什么必要了。
|
26
lolizeppelin 2023-04-16 22:22:49 +08:00
主要是你前端怎么实现....
全用二进制请求得改多少接口呀.... 又没法把 msgpack 结果包 json 里,用 b64 转码二进制的化又变大了反而没意义还不如直接 json 开 gzip |
27
duke807 2023-04-16 22:49:09 +08:00 via Android
@icyalala 给别人用完全可以 json 和 msgpack 同时支持,收到 json 就回 json ,收到 msgpack 就回 msgpack
json 和 msgpack 结构类似,解析出来的数据也是一样的,服务器后面的处理完全相同,同时支持一点都不费事 |
30
xiangyuecn 2023-04-16 22:52:41 +08:00
之前看了一篇文章,b 站直播 客户端之间的 p2p 网络内传输的数据,就是用的 message pack 作为传输协议,也用这个封装一下 hls 切片文件,简单粗暴,节省用户的带宽😅
|
31
lianyue 2023-04-16 22:52:44 +08:00
我做过一个应用
支持 proto 和 json gzip 或 br 后 一般 proto 只比 json 大小浮动 -5%-+1% 小百分之五 到大百分之一 |
32
Logtous 2023-04-16 23:01:58 +08:00
接触过一款国内在线用户百万级别的手游传输协议用的 msgpack
|
33
icyalala 2023-04-16 23:07:08 +08:00
@duke807 如果你同时支持两种格式,那只能让功能向 json 对齐,msgpack 的额外功能就用不到,结果无非就是省些流量。如果再 gzip 一下,那两者连流量的差距都很小了,这只要在 nginx 配一下就行,对应用来说都是透明的。
如果说性能,正是因为 json 流行,现在各个语言都有一堆高度优化甚至 simd 加速的库,其他格式没这个待遇的。有特殊需求的,这里还有一堆二进制格式可选呢: https://en.wikipedia.org/wiki/Comparison_of_data-serialization_formats |
34
duke807 2023-04-17 00:06:11 +08:00 via Android
@icyalala 不,我説了 msgpack 可以简化接口,因为可以传二进制,同一种 api 就可以传输图片文件
同时支持的时候,如果客户选择使用 json ,那么就只能麻烦一些用单独的文件上传下载 api ,由客户自行选择,服务器架构不用往 json 靠 对于文本解析,再怎么加速都没 msgpack 这样的二进制格式效率高 而且,现在很多嵌入式设备,mcu 解析 json 更是亦常的麻烦,譬如在没有 malloc 可用的环境,而此时 msgpack 解析则轻松省事 (对于 ram 很小的 mcu ,需要无损压缩数据的话,压缩格式我会选择 lz4 ,而不选 zip 类,因为前者对 mcu 来说轻量很多) |
35
duke807 2023-04-17 00:13:34 +08:00 via Android
协议虽有很多,但 msgpack 是最简单、最接近 json 的格式,对开发者来説,换一下 序列化 和 反序列化 两个函数名就行了
|
36
icyalala 2023-04-17 00:53:43 +08:00
@duke807 接口方面,你不可能要求后端同学花费力气去专门为小众需求单独开发一个接口。而且即使对齐到 json 格式的话,支持多种格式也需要后端单独做开发和测试,这和运维同学改改 nginx 配置完全不是一个工作量。
我觉得性能方面你想当然了。simdjson 能用 simd 快速教研整个 json 的 UTF-8 编码,实际上现在解析速度也能达到 3GB/s ,甚至还能按需解析性能还会更高。msgpack 里面的字符串也是 UTF-8 的,但我没见有什么库愿意去写 simd 加速或者按需解析的。 如果你把应用范围限定在嵌入式,那和上面我们讨论的完全不是一回事儿了,性能又不是主要考虑的东西。如果你说没有 malloc ,那就算用 JSON 库也有很多允许自定义 allocator 或者自带 fixed memory allocation 功能的库,这完全没问题。 |
37
Aloento 2023-04-17 02:07:02 +08:00
你可以看看 SignalR
|
38
whileFalse 2023-04-17 02:40:02 +08:00
JSON 换 MessagePack 解决了什么问题?代价是什么?
你引用的那个帖子里的例子就是有病,那么大的请求量,连带宽都付不起,趁早倒闭 别什么事儿都想着上奇技淫巧。带宽都付不起的公司,不值得。 |
39
dayeye2006199 2023-04-17 05:12:26 +08:00
这边太多老哥做 2C 业务做的太多,觉得所有程序员都是做这个的。json 序列化 http 协议走天下。
其实见过好多分布式科学计算,高性能计算的框架,就用这个来做序列化的。好多传输的东西是向量,比如 numpy 的对象。这些东西还需要加上压缩之类的算法。json 搞这些其实挺麻烦的。msgpack 倒是处理起来不难。 都是看需求。json 不是万能的。 |
41
kaddusabagei38 2023-04-17 09:40:24 +08:00
这东西主要可能还是平台因素比较大...可能 cs 架构好一点,毕竟 client 本来什么东西都能自己选型,加个其他序列化库也没啥
bs 的话总感觉目前一切都是围绕着 json 去做的...搞这种东西可能成本太大了吧,f12 都不知道怎么去调试.. |
42
duke807 2023-04-17 09:46:41 +08:00 via Android
@icyalala
那是因为 msgpack 反序例化根本就不需要先整体解析 utf8 字串,因为 msgpack 本身就不是字符串格式 其中包含的一些字符串格式的内容,使用各环境自带的 utf8 编解码工具即可,譬如浏览器你怎么用 simdjson ? 至于你原本需要用 simdjson 的环境,你如果不满意现有 msgpack 库的 string 数据的转码速度,你直接把 utf8 转码函数替换一下就行了,搜 utf8 simd 库即可,会找到更多比 simdjson 更好的库,因为 utf8 的使用面可比 json 大多了,各环境的 utf8 编解码应该都已经用的就是 simd 加速过了的。 使用 msgpack 最大的好处是简单、扩展性好、通用性好,譬如要搞一个上传 图片 的 API ,和其它 API 一起共用一个 url 就行,而且除了 get/post 接口,还可以用于 websocket: { "user": "xxxxx", "auth": "tmp_password", "cmd": "upload_img", "image": 图片数据 } 我不是让后端费力开发一个小众接口,而是产品一开始就要选择简单、扩展性好、通用性好的 msgpack 。 至于它是否小众,你可以看一下其他坛友的回覆,很多大厂到在用。 互联网前后端不是最喜欢造轮子、脚手架和追新的吗?怎么到 msgpack 这样真正有意义的东西上,就各种排斥了呢? 当然如何选择是你的事,反正有人喜欢堆屎山也不会影响到我。 |
43
picone 2023-04-17 09:59:20 +08:00
@benrezzagmehamed #6 msgpack 不太可能比 proto 省,因为 msgpack 是自描述的,他还有字段名
|
44
serge001 2023-04-17 10:15:05 +08:00
@dayeye2006199 看场景,楼上已经说了单纯为了节省带宽,这样做不值得,并没有一耙子打死
|
45
Trim21 2023-04-17 10:17:45 +08:00
@dayeye2006199 但楼主的标题就是 web 服务啊...
|
46
cs8425 2023-04-17 10:45:21 +08:00
大概 6~7 年前用过
序列化反序列化的东西不是完全一致 忘了是结构层级变了还是型态变了 改成手搓格式二进制解决 后面也没遇到类似的需求就放置了 |
47
icyalala 2023-04-17 11:49:05 +08:00
@duke807 看来你不明白 simd 是怎么工作的。。simd 在处理较长数据时才会优势显著,如果你把字符串拆分出来,再用 simd 校验每个字符串,就会因为需要额外对齐或者数据过短无法向量化导致性能甚至会下降的。
回头再来看看我们讨论的适用场景:如果你是对外的服务提供者,无论是为前后端还是客户端,那明智的选择是尽可能为`更多人`服务,用 json 是毫无疑问的。所谓小众格式说的并非是没人用,而是 json 已经是事实标准、占据统治地位,其他格式的支持程序、系统生态根本不在一个量级上。 如果你是给自己的系统选择数据传输格式,追修更高读写性能和更小流量,那还有 flatbuffer 和 capn proto 等所谓 0 解码耗时的 zero-copy 方案。选择 msgpack 更多的是那些过去 json 带来的惯性,并不是什么追新。 |
48
duke807 2023-04-17 12:15:35 +08:00 via Android
@icyalala
跟你说 simd 是因为你在意这个 你可以试试 simdjson 和 msgpack ,看看到底哪个性能更好,用数据说话 对 msgpack 来说,我根本就不认为是个事,你非要拿 msgpack 不需要的东西来説事 如果是我提供服务,我会以 msgpack 为主做架构设计,单独外挂 json 给喜欢用 json 的人 至于生态,用 msgpack 是缺少什么了吗?你倒是说说呀 至于其它通讯格式,我当然知道它们的存在,我也知道它们是怎么死的,我一开始就不看好它们,无论是 xml 还是 protobuf 选择 msgpack 是因为它拥有 json 的绝大部份优点,保持简洁的同时,扩展性比 json 好很多,而且很类似,平替很方便 |
49
hengyunabc 2023-04-17 12:55:18 +08:00
我来说下根本原因吧,msgpack 是日本公司发明的,作者一并写了很多的库,比如 Fluentd ,但人力终有限,msgpack 的多语言实现也一般。当年 redis 作者推过一把。
本质上大部分后来的开源软件都要有商业公司背书,没有金钱的支持是玩不转的。 |
50
icyalala 2023-04-17 14:38:16 +08:00
@duke807
我没看出你对 simd 或者其他数据传输格式有了解。你非要数据那我就跑一下。 以最常见的 twitter.json 作为测试数据 https://github.com/simdjson/simdjson/tree/master/jsonexamples 体积:相差并不大 json: 467KB msgpack: 402KB 在手头 M1 上跑 simdjson 和 msgpack-c 来解析,循环 16 次 simd:dom: 759MB/s simd:ondemand: 1604MB/s msgpack-c: 948MB/s msgpack 并没有明显优势,而且也没验证 UTF-8 编码。 另外如果 simdjson 在现代 x86 上跑的更快。 json 缺点一大堆,唯一最大的优点就是人类可读写,msgpack 并没有继承这个优点。 |
51
lesismal 2023-04-17 15:06:38 +08:00
@icyalala
我不是挺 MessagePack ,我自己主业务也基本不用它。 但是单就性能而言,这里还是有个市场占有率的问题。因为 MessagePack 用户没那么多、像 #45 @hengyunabc 所说的,作者也没那么大精力和动力去做更大的性能优化。如果很多很多人用,MessagePack 的性能应该是可以做到比 simdjson 更强的,因为需要处理的字节数、逻辑肯定是比 json 少一点的,simd 指令能用来优化优化 json 也可以用于 MessagePack ,比如 simdjson 作者去实现 MessagePack 。 > 也没验证 UTF-8 编码 MessagePack 本来就是二进制,当然是不需要验证 utf8 的,主要还是 simd 针对性优化太强。 @duke807 > 至于其它通讯格式,我当然知道它们的存在,我也知道它们是怎么死的,我一开始就不看好它们,无论是 xml 还是 protobuf xml 没死,protobuf 更是没死,只是 web 领域用的人少罢了。大规模服务集群之间的 RPC ,pb 占有率还是很高的,游戏行业 pb 的占有率也非常高。 一些传统 c/cpp 领域,不涉及深拷贝的,就是 c struct 1 字节对齐,直接 struct 地址拷贝传输,性能和 buffer size 都是无敌的。 二位没必要争执这些,http1x 性能和流量浪费都那么垃圾也照样统治着互联网。技术栈的市占率都是历史综合因素造成的,自己家的业务选择自己认为适合的、自己喜欢的就行了。 |
52
lesismal 2023-04-17 15:20:50 +08:00
@icyalala
> 体积:相差并不大 > json: 467KB > msgpack: 402KB > 在手头 M1 上跑 simdjson 和 msgpack-c 来解析,循环 16 次 > simd:dom: 759MB/s > simd:ondemand: 1604MB/s > msgpack-c: 948MB/s 另外,这种性能对比是存在一些不合理的: 1. 是应该对比相同结构的序列化反序列化次数,而不是对比每秒处理了多少 MB/GB 2. 这种 size 的结构已经是非常大了,实际的业务中,单个消息体这么大的时候应该是少数场景。所以也应该考虑常规 size 的结构的压测对比,我对 simd 指令没做过什么研究,随便搜了一段: |
53
lesismal 2023-04-17 15:22:54 +08:00
上一楼手滑发布了,接#52
SIMD 的优点?我们普通应用场景中有很多情况下需要对大量数据执行相同的操作,例如图片处理、视频特效等,在这种时候使用 SIMD 指令能取得很大的性能提升。例如 SSE 指令,支持每次对 4 个 FP32 进行操作,那么我们常用的 Vector4 向量加减乘除,皆可使用一个指令完成,效率大大提高。 SIMD 的缺点?有得必有失,为 SIMD 优化的程序在处理分支指令时性能不佳,因为分支指令本质上是一部分数据流根据条件去执行不同的指令,当多个数据流需要运行的分支不同时,需要运行两次程序遍历来完成所有数据流的操作。此外,不是所有情况下都需要很高的并行度,典型例子就是 AVX512 指令。虽然理论上一次能处理 16 个 FP32 ,但很难遇到需要同时处理这么多数据的场景。常见的向量、矩阵计算,操作单位都是 Vector4 ,要适配 AVX512 就需要大改程序流程和算法,去把好几个数凑起来一起操作,边际效应明显。而且在前几代 CPU 上 AVX512 还有降频问题,一跑起来频率上不去,速度还不一定有 SSE 快。 所以,常规主流业务的普通 size 结构场景下,simd 是否还有优势? 3. simdjson 和 MessagePack c 编译优化是如何的,比如都是 O1 还是 O2 还是 O3 ,实际场景允许到 O3 不? |
54
cloudyplain 2023-04-17 16:38:13 +08:00
对于 java 来说 msgpack 官方实现,除了体积有优势(未压缩),jackson-json 性能都比他要好不少(schema-less 场景),jackson 本上有很多性能优化,jackson 支持的二进制 format 比如 cbor 、smile 都比它性能要好。
|
55
Nazz 2023-04-17 16:49:28 +08:00
@lesismal MessagePack 的主要优势还是在于描述二进制数据而不是性能. JSON 已经成为了 Web IDL 的事实标准, 有大量的公司和个人提供优化, 不仅仅是 SIMD, 还有 JIT, ASM.
|
56
lesismal 2023-04-17 17:00:45 +08:00
@Nazz 你没看懂我意思,我说的不是现有的 MessagePack 实现性能有优势
#51 但是单就性能而言,这里还是有个市场占有率的问题。因为 MessagePack 用户没那么多、像 #45 @hengyunabc 所说的,作者也没那么大精力和动力去做更大的性能优化。如果很多很多人用,MessagePack 的性能应该是可以做到比 simdjson 更强的,因为需要处理的字节数、逻辑肯定是比 json 少一点的,simd 指令能用来优化优化 json 也可以用于 MessagePack ,比如 simdjson 作者去实现 MessagePack 。 |
57
swulling 2023-04-17 17:31:15 +08:00
看看 OpenAI 的 stream 返回,什么流量,不重要。
|
58
icyalala 2023-04-17 18:27:37 +08:00
@lesismal 先回复几个问题:
我提 UTF-8 校验说的是 string 类型的值,内部编码是 UTF-8 ,如果为了安全考虑是要做校验的。json 可以预先整个输入都校验一遍,而二进制格式需要解析出来每个 string 值之后再一一校验,不是说二进制就不考虑校验了。 simd 的支持现在都是动态派发的,就是运行时检测一次 cpuid 判断指令集,avx512 进几代 CPU 都是不降频的,不降频时才会用 avx512 ,否则还是 avx256 或继续降级,所以这个不用担心。没有 UB 的代码一般 O3 没问题,即使 O2 也相差不大。但这些都是细节,不重要。json/msgspec 性能对比其实也只能这样简单搞搞,实际应用里如果要转为用户定义的结构或者对象,耗时大头其实是在对象创建上。真要是自己用的服务又在乎性能,在 C/C++ 应用里 flatbuffer 和 capnproto 更合适,至少比自己 struct 序列化要靠谱,现在很多游戏也在用。 我认同你的后面的观点,这是市场占有率的问题。一个标准即使性能上烂,但流行到这种地步就会有越来越多的高手投入到这里来,做性能优化、做生态支持。但是一个标准用的人少,即使设计优秀,也很难吸引足够人才投入其中。 |
59
lesismal 2023-04-17 19:00:28 +08:00
@icyalala
对,大家基本观点是一致的。 string 在传统语言里的设计也是不太友好,支持二进制通用才更舒服,但也确实省了一点标识头。 capnproto 好久以前看到官方自己的数据非常牛,但这个我一直没在自己项目里用过,你们实际项目有用到不?好用不? |
60
duke807 2023-04-17 19:38:05 +08:00 via Android
@icyalala 辛苦了
我不觉得 json 的人类可读可写能算多大的优点 举例:doc 文档的裸数据不需要人类可读可写,但依然可以很方便的人工读写 设计产品架构的时候,以 msgpack 为主,可以不受 json 不能传输二进制的限制,可以设计出更简洁的 api 接口 如果是 json ,要传二进制,要纠结用 base64 还是 单独开一个 api ,单独开 api 的话用户验证又要单独搞一套机制,url 也要搞老长一串 而且要先上传文件,再在 json 里面填文件 url 地址,对方收到 json 之后,又要单独下载这些文件,很多时候都是些不大不小的文件 |
61
yc8332 2023-04-18 09:26:24 +08:00
web 不差这点流量
|
62
sxfscool 2023-04-24 16:44:22 +08:00
https://www.peterbe.com/plog/msgpack-vs-json-with-gzip
对比结论:没有换 msgpack 的理由 gzip 后,体积基本没有优势,速度也没什么优势,二进制反而不直观了 |
64
acctv2 2023-05-11 08:53:11 +08:00
我最近考虑在嵌入式的数据传输中使用 msgpack ,我觉得这个是最大的应用场景。
嵌入式场景往往 CPU 性能低,内存紧张,传输数据不用考虑所谓人类可读的问题,而且没有 SIMD 指令可用,用 msgpack 提升应该比较显著。Web 场景下资源整体还是充裕的,json 换 msgpack 带来的提升比较小,更何况前面有人提到了 simdjson 。 |