探讨一下微信海量 openid 的存储方法

2021-06-26 17:49:00 +08:00
 GM

众所周知,微信用户在不同的公众号、小程序都有不同的 openid 。

假设有 10 亿个微信用户,一百万个微信公众号、小程序,那么就可能存在

10 亿 x 一百万 = 一千万亿个 openid,每个 openid 大约是 30 个字节,那么光是存储这些 openid,就需要 三千万亿字节。

问题来了:

一,这些 openid 是固定生成的,还是通过微信用户 ID 通过一定算法算出来的? 二,如果是固定生成的,那么这么多 openid 如何做到高效存储、查询的? 三,如果是通过算法算出来的,万一算法被破解了(或者秘钥泄露了),那么就永远泄露了,因为有大量第三方系统存储着这些 openid,是不太可能去全部更新的。

3830 次点击
所在节点    编程
19 条回复
daquandiao2
2021-06-26 18:20:32 +08:00
实际没那么多 一个用户才能关注几个公众号
0o0O0o0O0o
2021-06-26 18:37:56 +08:00
一个用户好像最多关注 2000 个公众号
laowai89
2021-06-26 18:39:23 +08:00
你就一个微信?你关注了几个公众号
gwy15
2021-06-26 19:05:36 +08:00
稀疏
qiayue
2021-06-26 19:05:47 +08:00
我猜是生成的,而且是可以反解的。
你有没有发现,同一个公众号下的不同关注者的 openid 前缀是一致的。
我猜,openid 分成前后两部分,前一部分可以解析出公众号唯一 id,后一部分可以解析出微信号唯一 id,甚至中间有一位是校验位,拿到一个 openid 先用校验位判断是否是合法的 openid 。

至于你说算法是否可能被破解,我觉得总有办法可以解决。
leokino
2021-06-26 19:11:42 +08:00
@qiayue 这位大哥大概没学过密码学,生成一定是生成的,但一定不可逆。
zpf124
2021-06-26 19:45:13 +08:00
看起来楼主好像不是搞后端的啊,甚至好像不是搞技术的。
几个部分,
1 、你的固定生成和通过微信 id 算出来,实际想表达的是不是“生成 id 是否与与用户或其他业务数据相关?”。
答:无
与业务数据肯定是无关,因为没意义,但大概率与时间有关,给你两个 id,你可以知道这两个 id 哪个生成的更早,仅此而已。
这世界上有许许多多的随机数生成方法,包括算法层面的伪随机(一般常用),和真正意义上的随机(利用硬件电荷,效率慢,非特殊情况没人用)。

现在常见的各种随机字符串生成方案大多数都是根据 推特公布的雪花 id 生成规则的思路制作的,估计微信很可能也不例外。

2 、和其他数据存数据库没什么差距,数据库 io 写入瓶颈了就升配置或者加机器,查询慢了加缓存。

3 、你知道了规则有什么用, 身份证规则百度就有,但你随便生成一个去银行或者公安局人家又不是查不出来。
而且这种随机 id 生成会给许多不同的地方用,第一个用在用户 1 关注公众号 a,第二个用在用户 1 使用小程序 b,你用 A 公众号知道了 openid 又怎样,你公众号的关联数据里又查不到。
zpf124
2021-06-26 20:00:49 +08:00
发出去之后我突然理解楼主的想法了....

楼主以为 openid 有个大列表, 就个网址短链接一样,一个 id 对应一个值,不论是啥数据都从这查。


然而实际上, 这种 id,生成的服务只管生成,生成的值有没有地方用到对这个服务都无所谓,也没有一个大列表记录每个 openid 对应啥。

我公众号需要用到一个 id, 那我就获取 /生成一个,存我这个表里, 他小程序要用到一个 id,那他就生成一个,存他那,支付用到了支付那边自己再存一个。

不用 openid 用数字自增这功能都不会出安全问题,
我公众号生成了 id=1, 他小程序生成 id=21,你在我这公众号里用 21 查能找到啥?
即便我公众号的表里有个 id=2 的,你查的时候我又不是不判断这个 id 是不是你能看的。
JohnH
2021-06-26 20:55:29 +08:00
小的关系系统可能存储起来更方便。
像微信这种体量,如果把 openid 存起来,我觉得不如有一个固定算法更划算。
一个 openid 维持了一个关系,通过算法来加密解密来计算出关系,在业务上就相当于用户位于应用的 token 。
qiayue
2021-06-26 21:17:43 +08:00
@leokino 的确没学过,但从使用场景来说,能够还原不是更好吗?
nvkou
2021-06-26 21:43:37 +08:00
@qiayue 若无需要,勿增实体。id 只是标识符,没有意义的。只要能验证张三,我就恒定给他发同一个 id 即可。id 本身是阿猫阿狗无所谓,如果本身还自带信息容易引起安全问题。我不记录你的密码原文,但我知道你有没有输错
tianxia
2021-06-26 22:51:50 +08:00
固定生成的可能性大,如果是算法生产的,有办法反解的,那风险是巨大的
pcbl
2021-06-26 22:54:54 +08:00
不得不说微信的这种设计还是挺好的,比 tg 的一个用户 id 全包了好很多
Seanfuck
2021-06-27 00:11:07 +08:00
至少是拼起来的,前 6 位跟公众号关联,第 7 位没有数字,大小写一致;后面的看起来是随机生成的
leokino
2021-06-27 06:29:41 +08:00
@nvkou 我思考了下,确实也有可能是可以还原的,但是从微信的角度来说没有必要,因为微信是在已知用户 id 的情况下提供给小程序。

其次,三千万亿字节听起来很多,但其实也不过 3000 TB,更何况,上亿用户使用的小程序,屈指可数,实际可能几个 TB 都用不到。
qiayue
2021-06-27 10:50:39 +08:00
@leokino 我是这样考虑的,每个微信号的唯一 id 和公众号唯一 id 肯定是在数据库不同的表里分别记录的。
也肯定会有一张表,记录了微信号和公众号(小程序、App 同理)的关系,在首次产生关系时保存一条记录,同时生成一个 openid 。

在实际使用时,对于传过来的每一个 openid,如果都去缓存或数据库中校验 openid 是否合法,没多大必要,第一步直接通过一个固定的算法去校验合法性,之后解开得到公众号 id 和微信号 id,再去处理业务,会不会更好。
melkor
2021-06-27 11:21:37 +08:00
想太多,就是算法生成的而已
leokino
2021-06-27 16:02:55 +08:00
@qiayue ID 本身就是用来查表的东西,即用 ID 去查找关联的其他信息,因此即便储存,不增加复杂度,也不会对系统负载造成本质上的影响,合理分片和索引几乎不增加查找成本。其次算法同样解密消耗 CPU 时间,相较而言,我认为绝对是查找更省钱。
qiayue
2021-06-28 07:20:22 +08:00
@leokino 学习了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/785963

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX