基于内存的类似redis的缓存方法
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,项目中需要用到redis,业务起来之后用到的地方更多,问题来了,因为操作redis太频繁,导致操作redis成为整个项目的瓶颈,经过调研和比较这时候基于内存的cache登场,简单来说就是纯内存层面的c
千家信息网最后更新 2026年11月02日基于内存的类似redis的缓存方法
项目中需要用到redis,业务起来之后用到的地方更多,问题来了,因为操作redis太频繁,导致操作redis成为整个项目的瓶颈,经过调研和比较这时候基于内存的cache登场,简单来说就是纯内存层面的cache,可以实现
1、缓存数量的限制(不能无限制的堆内存,会撑爆)
2、能设置过期时间(内存中只缓存高频出现的数据)
放上业务流程的对比图,就是在redis之前加了一层,比较redis虽然基于内存但是连接包括操作还是得产生网络io操作
下面是我做的对比测试:
普通数据:
1、假设全部不命中(内存和redis都没有): [root@master test]# python 6.py 这是100次的结果 内存:[0.006078958511352539, 0.00607609748840332, 0.006433963775634766] redis:[0.00573420524597168, 0.007025003433227539, 0.005178928375244141] 这是1000次的结果 内存:[0.07438397407531738, 0.07421493530273438, 0.0615389347076416] redis:[0.04864096641540527, 0.04749107360839844, 0.05013895034790039] 这是10000次的结果 内存:[0.5369880199432373, 0.48474812507629395, 0.4684739112854004] redis:[0.4230480194091797, 0.5131900310516357, 0.43289995193481445] 这是100000次的结果 内存:[5.565299987792969, 5.5354228019714355, 5.658163070678711] redis:[4.795120000839233, 5.0205230712890625, 4.469913005828857]2、假设全部命中: [root@master test]# python 6.py 这是100次的结果 内存:[0.00040602684020996094, 0.00021195411682128906, 0.00021600723266601562] redis:[0.005956888198852539, 0.005934000015258789, 0.005537986755371094] 这是1000次的结果 内存:[0.0021610260009765625, 0.0020508766174316406, 0.002026081085205078] redis:[0.0546720027923584, 0.04969382286071777, 0.04725193977355957] 这是10000次的结果 内存:[0.014709949493408203, 0.01748490333557129, 0.016735076904296875] redis:[0.500324010848999, 0.6110620498657227, 0.5946261882781982] 这是100000次的结果 内存:[0.20346498489379883, 0.20162200927734375, 0.15467381477355957] redis:[5.065227031707764, 5.543213844299316, 5.167007207870483]json格式的数据:
1、假设全部不命中: [root@master test]# python json_test.py 这是100次的结果 内存 [0.00627589225769043, 0.006350040435791016, 0.006167888641357422] redis [0.00538182258605957, 0.005352973937988281, 0.005239009857177734] 这是1000次的结果 内存 [0.06096196174621582, 0.05894589424133301, 0.0531618595123291] redis [0.04534316062927246, 0.04644417762756348, 0.042047977447509766] 这是10000次的结果 内存 [0.526871919631958, 0.49242496490478516, 0.54292893409729] redis [0.46350693702697754, 0.5339851379394531, 0.514045000076294] 这是100000次的结果 内存 [5.3060479164123535, 5.807142972946167, 4.886216163635254] redis [4.287613153457642, 4.528016090393066, 5.158953905105591]2、假设全部命中: [root@master test]# python json_test.py 这是100次的结果 内存 [0.0005319118499755859, 0.0003058910369873047, 0.0002970695495605469] redis [0.006021022796630859, 0.005857944488525391, 0.006082773208618164] 这是1000次的结果 内存 [0.0028162002563476562, 0.002669811248779297, 0.0026869773864746094] redis [0.07850098609924316, 0.06138491630554199, 0.05786609649658203] 这是10000次的结果 内存 [0.02676105499267578, 0.026623010635375977, 0.026623010635375977] redis [0.6534669399261475, 0.6395609378814697, 0.47389698028564453] 这是100000次的结果 内存 [0.20687103271484375, 0.20745611190795898, 0.19935917854309082] redis [5.537367105484009, 5.8351359367370605, 4.935602903366089]可以看到,当全部不命中(实际情况只有在第一次才会出现,不然也不用加redis了)的情况下,基于内存和基于redis的性能基本相同,但如果命中过之后这个性能就有很大提升了
直接上代码:
#!/usr/bin/env python# -*- coding:utf8 -*-'''Author : mafeiDate : 2019-09-26'''import timeimport weakrefimport collectionsimport ujson as jsonclass Base(object): notFound = {} class Dict(dict): def __del__(self): pass def __init__(self, maxlen=10): self.weak = weakref.WeakValueDictionary() self.strong = collections.deque(maxlen=maxlen) @staticmethod def now_time(): return int(time.time()) def get(self, key): v = self.weak.get(key, self.notFound) if (v is not self.notFound): expire = v[r'expire'] if (self.now_time() > expire): self.weak.pop(key) return self.notFound else: return v else: return self.notFound def set(self, key, value): self.weak[key] = strongRef = Base.Dict(value) self.strong.append(strongRef)class MemoryCache(object): def __init__(self, maxlen=1000 * 10000, life_cycle=5*60): self.memory_cache = Base(maxlen=maxlen) self.maxlen = maxlen self.life_cycle = life_cycle @staticmethod def _compute_key(key): return key def get(self, k): memory_key = self._compute_key(k) result = self.memory_cache.get(memory_key).get('result', None) if result is None: return result return result def set(self, k, v, life_cycle=None): self._set_memory(k, v, life_cycle) def get_json(self, key): res = self.get(key) try: return json.loads(res) except: return res def set_json(self, k, v, life_cycle=None): try: v = json.dumps(v) except: pass self.set(k, v, life_cycle) def set_with_lock(self, k, v, life_cycle=None): self._set_memory(k, v, life_cycle) def _set_memory(self, k, v, life_cycle=None): life_cycle = life_cycle or self.life_cycle memory_key = self._compute_key(k) self.memory_cache.set(memory_key, {'ip': k, r'result': v, r'expire': life_cycle + self.memory_cache.now_time()})调用时只需要传入2个参数:
maxlen : 内存中最多缓存多少条数据
life_cycle: 数据失效时间
优点:
1、高效,比直接调用redis要快很多
2、不会产生网络io和磁盘io
缺点:
1、支持的结构比较单一,当然这个可以自己扩充方式实现
2、如果要更新内存中的值不太方便,可以有其他方式实现
内存
结果
这是
数据
缓存
业务
就是
性能
情况
方式
时间
网络
项目
很大
普通
相同
频繁
不用
业务流程
代码
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网科技公司排名
博彦科技互联网金融
中国互联网科技工作委员会毛军
互联网和科技技术
深圳科技互联网
北京互联网科技
互联网金融科技平台
太原新华互联网科技学校怎么样
天速互联网络科技有限公司
金融科技与互联网金融相同和不同
浙江互联网科技研学营
互联网金融科技元年
黑科技 体验场景 互联网大会
互联网科技资金流入
萌小萌互联网科技河南有限公司
互联网科技企业商标注意事项
唯美互联网科技
陕西彩京云互联网科技有限公司
保山浩联互联网科技有限公司
河南商务圈互联网科技有限公司
互联网科技网
科技信息互联网
互联网科技的
掌上梦互联网科技
左右互联网络科技
蓝色互联网科技
科技赋能互联网健康
剑昆互联网络科技有限公司临桂
宝灵互联网科技有限公司
内蒙古九一互联网科技