由于某些设计,系统不得不频繁读取整个用户表的数据做统计过滤使用,包括但不限于按部门找匹配员工、按项目找匹配员工等等等,直接查询表,sql优化的情况下查询倒是很快也不过是几百毫秒,But但是由于这些需求本身是服务于底层的比如权限功能,所以是特别高频的调用。直接读取数据库势必会造成数据库的连接暴增,很难保证DB的稳定性,说不定哪天就扛不住挂了。因此前人将他放到Redis的String结构上了,形成了一个大Value。Redis就不用多说了,单线程的,每秒读写都是上万的,但是这种大Value以及大Key都是很容易阻塞Redis的。
实测过Redis读取这样一个9000条(7~8M大小)且不含大文本的表数据表时==getstring获取7~8M左右的大value耗时还可以接受==,只是set进去耗时长点2s多点
改进方案是改成hash(key -field-value,分别是表名-用户id-用户实体),但是hash结构适合查询单个用户id ,想要查询全部fields对应的value就不靠谱了, 用getvalues官方都不推荐,影响性能阻塞Redis,推荐使用HScan用游标分段遍历,我封装过也不适合没有性能,只是用HScan目的是保证Redis高可用不阻塞。适合用于批量的异步删除掉hash中的fields。
那么如何才能设计出一个适合以上场景的高可用方案呢?引出下文,哈哈~
==如果有幸正在阅读的你有过这个思考,并且有更好的方案,欢迎指教~==
解决负载均衡中的服务器内存缓存同步更新问题,保存各服务器内存始终最新且一致
数据每发生改变时,就通过reids设置版本号(incrby),
每个服务器尝试写入ip到这个版本号的set集合中,
写入成功表示没有被同步过,执行同步动作更新本地的内存缓存。
否则跳过直接取内存缓存用
但是可以改进
变化频率高的时候, redis存的数量也多,不过可以优化,版本号自增后就删掉旧版本的缓存
==三部曲==
以上三步,如此便保证了每个服务器获取内存时始终是最新的那份!
// 设置缓存,只需要10毫秒
<List<RedisUser>> DistributeAssistMemoryCacheHelper.SetCache(key, usrslist, 24 * 60 * 60 - 500, isfromChange);
// 读取缓存,几乎不耗时
result = ()DistributeAssistMemoryCacheHelper.GetCache(key);
// 删除缓存
DistributeAssistMemoryCacheHelper.DelCache(key);
附上源码
版权属于:dingzhenhua
本文链接:https://cloud.tencent.com/developer/article/2019362
转载时须注明出处及本声明
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有