摘要:優(yōu)化結(jié)果計(jì)算機(jī)器六代內(nèi)存時(shí)間秒優(yōu)化版本使用存放用戶(hù),通過(guò)命令獲取下級(jí)時(shí)間復(fù)雜度,是所有給定集合的成員數(shù)量之和。
0x01
我們有一個(gè)業(yè)務(wù)場(chǎng)景是需要將用戶(hù)邀請(qǐng)的下級(jí)用戶(hù)根據(jù)其用戶(hù)等級(jí)給統(tǒng)計(jì)出來(lái)(不止統(tǒng)計(jì)一級(jí)).
現(xiàn)有的解決方案:
mysql中一張用戶(hù)表
主要的3個(gè)字段:user_id, parent _id,level,
典型的一個(gè)樹(shù)形結(jié)構(gòu).
因?yàn)閿?shù)據(jù)量很大,查詢(xún)次數(shù)很多,所以重算這數(shù)據(jù)基本上重算一次要花個(gè)幾分鐘.
優(yōu)化版本1:
假如我將沒(méi)所有用戶(hù)對(duì)應(yīng)的所有直接下級(jí)用戶(hù)的id取出,存放到redis中的數(shù)組,像這樣
U:110->[111,112,113,...]
將用戶(hù)等級(jí)也放到redis中,像這樣
L:110->0
然后通過(guò)map的方式取到下級(jí)的下級(jí)用戶(hù)并合并起來(lái),再通過(guò)用戶(hù)等級(jí)進(jìn)行分組。
users.stream.map(u-> jedis.lrange(0,-1)).flatMap(u-> u).collect(grouppingBy(u-> jedis.get("L:" + u)))...
LRANGE
時(shí)間復(fù)雜度:O(S+N),?S?為偏移量?start?,?N?為指定區(qū)間內(nèi)元素的數(shù)量。`
優(yōu)化結(jié)果:
計(jì)算機(jī)器:I5 六代 8G內(nèi)存
時(shí)間:25秒
優(yōu)化版本2:
使用Set存放用戶(hù),通過(guò)SUNION命令獲取下級(jí)ID
時(shí)間復(fù)雜度:O(N),?N?是所有給定集合的成員數(shù)量之和。
獲取當(dāng)前下級(jí)的用戶(hù)代碼則更簡(jiǎn)單了,首先將當(dāng)前用戶(hù)通過(guò)CPU并行的方式把SET的key計(jì)算出來(lái),然后通過(guò)SUNION將所有的用戶(hù)取出來(lái):
</>復(fù)制代碼
private Set downLevelAllUser(Set users) {
return jedis.sunion(users.parallelStream().map(s ->
"U:" + s
).collect(Collectors.toList()).toArray(new String[0]));
}
這些用戶(hù)的等級(jí)都查出來(lái),那就獲取他們的用戶(hù)等級(jí)并進(jìn)行分組.
</>復(fù)制代碼
private Map> groupUser(Set users) {
return jedis.mget(users.parallelStream().map(u -> "L:" + u)
.collect(Collectors.toList()).toArray(new String[0]))
.parallelStream().collect(Collectors.groupingBy(r -> r));
}
主要功能都實(shí)現(xiàn)了,那么試試計(jì)算8級(jí)所花時(shí)間
</>復(fù)制代碼
public List
Set u1 = downLevel1Users(start_user);
Map> m1 = groupUser(u1);
Set u2 = downLevelAllUser(u1);
Map> m2 = groupUser(u2);
Set u3 = downLevelAllUser(u2);
Map> m3 = groupUser(u3);
Set u4 = downLevelAllUser(u3);
Map> m4 = groupUser(u4);
Set u5 = downLevelAllUser(u4);
Map> m5 = groupUser(u5);
Set u6 = downLevelAllUser(u5);
Map> m6 = groupUser(u6);
Set u7 = downLevelAllUser(u6);
Map> m7 = groupUser(u7);
Set u8 = downLevelAllUser(u7);
Map> m8 = groupUser(u8);
return Arrays.asList(m1, m2, m3, m4, m5, m6, m7, m8).parallelStream().map(m -> {
Map newMap = new HashMap<>();
m.forEach((k, v) -> newMap.put(k, v.size()));
return newMap;
}).collect(Collectors.toList());
}
優(yōu)化結(jié)果:
總用戶(hù)數(shù)為:120W
計(jì)算機(jī)器:I5 六代 8G內(nèi)存
時(shí)間:4秒
好了,優(yōu)化完畢了,大神們還有什么高招,歡迎來(lái)指導(dǎo)!!!!!!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/65930.html
閱讀 3615·2021-11-23 09:51
閱讀 1488·2021-11-04 16:08
閱讀 3559·2021-09-02 09:54
閱讀 3625·2019-08-30 15:55
閱讀 2604·2019-08-30 15:54
閱讀 966·2019-08-29 16:30
閱讀 2054·2019-08-29 16:15
閱讀 2327·2019-08-29 14:05