16|本地缓存:用本地缓存做服务会遇到哪些坑?
该思维导图由 AI 生成,仅供参考
虚拟内存和缺页中断
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了在读多写多系统中使用本地缓存时可能遇到的各种问题和解决方案。首先,文章从虚拟内存和缺页中断的角度解释了操作系统底层是如何管理内存的,以及在高并发读写场景下如何提高缓存效率。其次,文章讨论了程序容器锁粒度的重要性,以及在业务缓存中常见的加锁方式,提出了一些优化建议。接着,文章探讨了GC和数据使用类型对缓存性能的影响,指出了在高级语言中做缓存时需要注意的问题。最后,文章提供了一些有趣的项目和组件供读者参考,以应对缓存中可能遇到的挑战。 此外,文章还介绍了内存对齐和SLAB内存管理的相关内容。内存对齐可以提高数据访问效率,减少内存碎片,而SLAB内存管理则是为了提高内存分配的效率和减少碎片。文章还强调了在业务服务缓存中需要关注的多种因素,包括锁争抢、GC原理、内存碎片、缺页等问题,以及在业务稳定后可能需要将服务做降级或考虑使用Redis分片来应对线上压力。 总的来说,本文对于在读多写多系统中使用本地缓存时需要考虑的技术细节和解决方案进行了深入浅出的介绍,对于从事相关领域的技术人员具有一定的参考价值。
《高并发系统实战课》,新⼈⾸单¥59
全部留言(8)
- 最新
- 精选
- 杜杜杜的杜置顶缺页中断: Java程序,向本地缓存插入大数据量时,会频繁触发缺页中断,导致不断申请内存。过程中会占用资源(包括等待申请内存时间),导致服务器响应可能缓慢,甚至系统不稳定。 是这个意思吗?
作者回复: 你好,感觉文中举的例子让你误会了,但是不确定具体,所以我再补充过一下。 Java程序启动后会申请一大块内存,但是这个内存是虚拟的内存,只有实际使用时,linux才会分配给他真实的物理内存,访问没分配内存的虚拟内存空间时内核会产生缺页中断分配真实物理内存。而在应用过程中,如果我们把业务数据放到服务内,如果内存使用过多可能会碰到后面这几种情况。 1.高级语言的GC会定期扫描这些对象,确定哪些可以回收来节省内存,导致服务周期卡顿。 2.内存申请过多,导致系统资源不够,这时linux会偷偷把你不怎么用的内存区域落磁盘,等你用的时候产生缺页再给从磁盘放回来给程序用。 3.有的高级语言底层使用了slab方式,而不是linux管理的内存,这相比malloc方式会高效一些,因为malloc很慢并且如果申请1M以上内存,会请求多次导致卡顿。如果频繁malloc free服务,会从内核卡住,影响响应速度。同时,因为内存碎片会增多,就会导致内存 malloc 操作 分配越来越慢,最后整体表现就是服务体验很差。 综合上面的情况,我们要注意的是,使用内存缓存数据时,要计算好容量,控制好存放的对象类型和数量,尽量避免GC扫描,避免内存使用过多被linux置换。不知道是否解决了你的疑问,可以在留言区继续交流。
2023-02-21归属地:浙江 - piboye微博长年出现挂是什么原因啊?读可以本地缓存,写需要通过热key发现来异步写,是聚合的地方挂吗?
作者回复: 核心是读写并发过高,后来做了相应的调整,当明星出事的时候紧急扩充服务器以及数据缓存层来应对
2023-02-16归属地:广东21 - John如果用大数组管理缓存,应该需要用bitmap或链表来管理哪些地方已使用,哪些未使用。如果修改的数据小于原来的length,则原地更新,或大于,则从空闲列表或bitmap中找到合适的位置存放新的数据,并将原数据标识为删除。是不是可以认为就是自己实现一个简易的内存分配器?
作者回复: 你好,John,这个方式很有趣,即节省空间又方便,并且如果配合slab方式更好
2022-11-28归属地:北京1 - 千锤百炼领悟之极限文中提到如使用 map[int]int,其中 key 是 string 通过 hash 算法转成的 int,value 保存的内容是数据所在的 offset 和长度。 这里map的value是个数组吧,因为要存offset与length,例如:map[int][2]int
作者回复: 没错,这里可以用两个map分别存开始和长度
2023-07-22归属地:广东2 - ARM比如IM场景,A发给B消息,用户A输入后,直接前端显示在页面不管是否落库(用户无感知提升体验感),然后前端异步落库。然后再查询数据库 A发送给B的信息,显示出来。将A-B这两个字段设置为联合索引
作者回复: 你好,ARM,感觉还需要补充下信息~
2023-01-15归属地:河南 - 徐石头所以不推荐在业务层内以map的形式做一级缓存?最近在优化产品Redis缓存的内存占用,考虑在redis前面增加一级缓存,有没有比较好的解决方案吗?或者关于优化Redis内存占用相关的解决方案
作者回复: 你好,不同语言规避GC方式不同,可以先找下相关语言用的人多的组件加入大量数据,压测观测gc性能监控。redis虽然浪费一些但是比自己实现快一些,掏钱就可用,笑,等量级上来后再优化来得及,如果量很大了,本地缓存也行,就是一致性很难
2022-12-16归属地:内蒙古3 - Geek_2c6ea9缓存的容量怎么设置比较好,一直往里面存会不会爆掉啊。
作者回复: 你好,很高兴你关注这里,对于临时缓存一般这里放的数据都需要提前计算好增长量,并且搭配LRU,最后要设计好数据分片规则才行。对于业务缓存最好是放不经常更新的数据。现在这类服务的业务服务器都会配上16g以上内存,相对会好一些
2022-12-06归属地:北京 - 第一装甲集群司令克莱斯特Java 的 volidate ,还是volatile?
作者回复: 你好,克莱斯特,这两个都很有趣~我本意是提及volidate
2022-11-30归属地:北京