如题,服务器是64G内存,16个cpu, redis有一个大约200M左右的有序集合,每次读取其中一个元素,然后更新它相对应的分值,在访问量稍稍大一点的时候,就会内存暴涨,实测会在几分钟之内redis内存占用会从几百兆飙到30多个G。 我的疑惑是,这个有序集合最大只有200M,所以不论怎样频繁的读写,都只是操作这200M的内存而已,为什么会占用那么高的内存呢?有大佬能给解惑一下吗?谢谢!
会不会读取的代码有问题,比如一次读取过多,弄成了读取全部元素之类,这样redis打包数据比较消耗内存
把字符串 parse 成 JSON 对象内存耗费可不止 200M 哦
考虑异步了吗?
async function commonChangeDeviceId() {
let setName = `vspOrderDevice.185.SortSet`;
let realSdkVersion = 20;
let deviceIdArray = await redisCli.zrangebyscore(setName,realSdkVersion,realSdkVersion);
let changeDeviceId = _.sample(deviceIdArray);
if (!changeDeviceId) {
deviceIdArray = await redisCli.zrangebyscore(setName,15,`(${realSdkVersion}`);
changeDeviceId = _.sample(deviceIdArray);
if (!changeDeviceId) {
deviceIdArray = await redisCli.zrangebyscore(setName,`(${realSdkVersion}`,28);
changeDeviceId = deviceIdArray[0];
}
}
if (changeDeviceId) { await redisCli.zincrby(setName,500,changeDeviceId); }
return changeDeviceId || '';
}
代码是这样的@AnzerWall @hyj1991 @dingyuanwu, 代码大致意思是从有序集合优先随机取分值等于20的一个成员,如果没有,就随机取分值15-19之间的一个成员,如果还没有,就随机取21-28之间的一个成员,取到之后给该成员的分值加上500; 有序集合的单个成员模板是key: “352076091955843”,value:‘20’; 单个集合总共有200万成员,占200M内存,分值在15-28之间大约平均分配。 访问量稍微大一些,内存就爆了
@JustforNode 你一次zrange出来多少个数据量你统计过吗,感觉会很多,访问量多估计直接炸了。。
建议用一些比较取巧的手法,比如给score加上一些小数,然后随机一下选一个(limit 0 1)出来就行了(就以前那种sql经常干的事情,随机选一条数据,类似的手法),range一堆出来再随机选一个的做法很傻
@AnzerWall 应该就是一次range的数据太多了,导致内存爆了,(limit 0 1)是正解,没有注意到zrangebyscore的这个语法,感谢指导!!