大佬们如何解决这个问题呢?
1
nulIptr 2023-12-18 19:02:31 +08:00 3
性能很差是多差? cpu 满了吗?
配置更新的频率是多高?必须要每次用都从 redis 中取吗? 5 分钟刷新一次可不可以,发布订阅模式更新可不可以? 每次用都是要整个 json 配置吗,能否拆出高频变化的 key 单独存 redis ? |
2
iyaozhen 2023-12-18 19:06:29 +08:00
具体一点呢 数据呢。json 多大,耗时多久,cpu 占用多少?
|
3
ScepterZ 2023-12-18 19:07:01 +08:00
一般是通过人来解决而不是代码,大家约定好配置只读不可以改。
很在乎这个问题的话,如果调用的频率不是特别高,可以直接换 jsoniter/sonic ,对于大部分业务来说性能足够了 |
4
iyaozhen 2023-12-18 19:08:38 +08:00
|
5
a632079 2023-12-18 19:10:20 +08:00
似乎可以试试 sonic ?不需要你手动做缓存啥的方案了。
https://github.com/bytedance/sonic/blob/main/docs/INTRODUCTION_ZH_CN.md |
6
BeautifulSoap 2023-12-18 19:12:21 +08:00
"如果把 json.Unmarshal() 之后的 object 保存在内存中,减少 json.Unmarhsal() 的操作。不同 goroutine 拿到的 object 就是浅拷贝的,并发不安全。"
你这 json 配置难道解析后还要修改?不修改的话解析完成设置变量的时候上锁写个 singleton 不就好了,怎么会并发不安全 |
7
darkengine 2023-12-18 20:57:19 +08:00
如果配置很大, 可以考虑在 Redis 里加个 config_version 字段, 项目 B 在修改 config 的时候先修改 config_version. 项目 A 先比较内存里的 config_version 和 redis 里的 config_version, 不一致再去更新配置.
|
8
matrix1010 2023-12-18 21:15:23 +08:00
结构固定直接走代码生成不就行了
|
9
iseki 2023-12-18 21:24:22 +08:00 via Android
建议代码生成,Java 的 getter 有点过时了,考虑 Record 模式吧😋😁
|
10
danbai 2023-12-19 08:27:49 +08:00 via Android
Redis 是支持订阅的可以让 a 在更改的时候发布一下
|
11
xuanbg 2023-12-19 08:39:51 +08:00
性能有问题肯定是这个 Json 太大了。这么大的数据,就不能用 hash 存,非得 string ?
|
12
plutome 2023-12-19 09:28:08 +08:00
完全不能理解 因为频繁使用配置文件, 然后 json.Unmarshal 导致 性能差
你一天是要读几百亿次配置文件么, 不然怎么会有性能差的问题? |
13
6581 OP @6581 @BeautifulSoap @ScepterZ @a632079 @danbai @darkengine @iseki @iyaozhen @matrix1010 @nulIptr @plutome @xuanbg 感谢大佬回复。具体细节已 append 了。
其实核心问题是: 每个请求来的时候,需要使用配置,使用配置时是否使用同一个对象 如果使用同一个对象,如何保证没有开发去写这个对象。(比如 config 中有 map ,如何不让开发去写,在代码层面一定程度上控制就行) 如果不使用同一个对象,如何更节省资源地深拷贝一个对象。 |
14
paceewang1 2023-12-19 10:11:58 +08:00
@6581 redis 里的信息有并发问题就加锁呗,不是说你从一个大 string 换成 hash 才出现的问题,即使是使用大 string ,你 unmarshal 后修改,再写进去也有并发问题啊;
另一个方面,json unmarshal 慢是因为用到了反射,如果你事先知道 struct 的具体结构的话,其实用 easyjson 应该是最快的,但是有额外代码生成,op 可以了解一下 easyjson |
15
CloveAndCurrant 2023-12-19 10:13:28 +08:00
要不试试 fastjson: https://github.com/valyala/fastjson
这个不转化为 object ,直接操作 JSON 字符串,占用资源和内存更小,性能也更高。 |
16
MoYi123 2023-12-19 11:27:59 +08:00
写 go 的应该会背 sync map 的八股文吧,
为什么有并发的情况下不抄这个的实现, 而要是每次都 Unmarshal json? |
17
jones2000 2023-12-19 12:52:05 +08:00
外面封装下,修改内容的时候才做一份拷贝, 如果是读取直接引用就可以。
|
18
8355 2023-12-19 21:05:37 +08:00
我就说一个问题吧,配置只要加一个版本号,单独通过 redis 读 versionKey 就可以确保 config 是否修改,是否需要进行一次刷新,你配置不会天天改,5 分钟才检查一次,如果有修改才运行一次你说的慢操作,这有多大开销?
|
19
8355 2023-12-19 21:06:51 +08:00
如果大量业务依赖这个配置本身,需要尽可能的保证实时性,直接上队列消费不是很好嘛。
|
20
kkbblzq 2023-12-19 21:55:30 +08:00
不嫌麻烦其实可以自己在配置的结构体上写个 Copy 方法的,硬编码的 Copy 连反射都不用就没性能问题;
|
21
dyllen 2023-12-20 15:57:14 +08:00
一个配置,竟然会有人往里写?人的问题很大?
|
22
smartdoc647 2023-12-25 17:51:38 +08:00 1
go 官方这个原生 json 库性能确实不太高。普通业务没什么问题,高并发场景官方库性能真不行,比如做日志实时消费不停处理 json 这种,我们压测性能确实一般,不要迷性官方库一定就性能好。
|