简单聊缓存

  在服务端编程当中,缓存主要是指将数据库的数据加载到内存中,之后对该数据的访问都在内存中完成,从而减少了对数据库的访问,解决了高并发场景中数据库容易成为性能瓶颈的问题;以及基于内存的访问速度高于磁盘的访问速度的原理(数据库读取数据一般需要从磁盘读取),提高了数据的访问速度和程序性能。
  根据缓存是否与应用进程属于同一进程,可以将内存分为本地缓存分布式缓存
  本地缓存是在同一个进程内的内存空间中缓存数据,数据读写都是在同一个进程内完成;
  分布式缓存是一个独立部署的进程并且一般都是与应用进程部署在不同的机器,故需要通过网络来完成分布式缓存数据读写操作的数据传输。

本地缓存

优缺点

  1. 访问速度快,但无法进行大数据存储
    本地缓存相对于分布式缓存的好处是,由于数据不需要跨网络传输,故性能更好,但是由于占用了应用进程的内存空间,如 Java 进程的 JVM 内存空间,故不能进行大数据量的数据存储。

  2. 集群的数据更新问题
    本地缓存只支持被该应用进程访问,一般无法被其他应用进程访问,故在应用进程的集群部署当中,如果对应的数据库数据,存在数据更新,则需要同步更新不同部署节点的本地缓存的数据来包保证数据一致性,复杂度较高并且容易出错,如基于 Redis 的发布订阅机制来同步更新各个部署节点。

  3. 数据随应用进程的重启而丢失
    由于本地缓存的数据是存储在应用进程的内存空间的,所以当应用进程重启时,本地缓存的数据会丢失。所以对于需要持久化的数据,需要注意及时保存,否则可能会造成数据丢失。

适用的场景

  所以本地缓存一般适合于缓存只读数据,如统计类数据。或者每个部署节点独立的数据,如长连接服务中,每个部署节点由于都是维护了不同的连接,每个连接的数据都是独立的,并且随着连接的断开而删除。如果数据在集群的不同部署节点需要共享和保持一致,则需要使用分布式缓存来统一存储,实现应用集群的所有应用进程都在该统一的分布式缓存中进行数据存取即可。

常用的本地缓存

手动编写(map)或是第三方框架Encache,Guava cache等等

分布式缓存

优缺点

  1. 支持大数据量存储,不受应用进程重启影响
    分布式缓存由于是独立部署的进程,拥有自身独立的内存空间,不会受到应用进程重启的影响,在应用进程重启时,分布式缓存的数据依然存在。同时对于数据量而言,由于不需要占用应用进程的内存空间,并且一般支持以集群的方式拓展,故可以进行大数据量的数据缓存。

  2. 数据集中存储,保证数据一致性
    当应用进程采用集群方式部署时,集群的每个部署节点都通过一个统一的分布式缓存进行数据存取操作,故不存在本地缓存中的数据更新问题,保证了不同节点的应用进程的数据一致性问题。

  3. 数据读写分离,高性能,高可用
    分布式缓存一般支持数据副本机制,可以实现读写分离,故可以解决高并发场景中的数据读写性能问题。并且由于在多个缓存节点冗余存储数据,提高了缓存数据的可用性,避免某个缓存节点宕机导致数据不可用问题。

  4. 数据跨网络传输,性能低于本地缓存
    由于分布式缓存是独立部署的进程,并且一般都是与应用进程位于不同的机器,故需要通过网络来进行数据传输,这样相对于本地缓存的进程内部的数据读取操作,性能会较低。

适用的场景

  • 多应用需要共享一份缓存

分布式缓存比较:Memcache VS Redis

  1. Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。而memcache只支持简单数据类型,需要客户端自己处理复杂对象
  2. Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用(PS:持久化在rdb、aof)。
  3. 由于Memcache没有持久化机制,因此宕机所有缓存数据失效。Redis配置为持久化,宕机重启后,将自动加载宕机时刻的数据到缓存系统中。具有更好的灾备机制。
  4. Memcache可以使用Magent在客户端进行一致性hash做分布式。Redis支持在服务器端做分布式(PS:Twemproxy/Codis/Redis-cluster多种分布式实现方式)
  5. Memcached的简单限制就是键(key)和Value的限制。***键长为250个字符。可以接受的储存数据不能超过1MB(可修改配置文件变大),因为这是典型slab 的***值,不适合虚拟机使用。而Redis的Key长度支持到512k。
  6. Redis使用的是单线程模型,保证了数据按顺序提交。Memcache需要使用cas保证数据一致性。CAS(Check and Set)是一个确保并发一致性的机制,属于“乐观锁”范畴;原理很简单:拿版本号,操作,对比版本号,如果一致就操作,不一致就放弃任何操作cpu利用。由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更 高。而在100k以上的数据中,Memcached性能要高于Redis 。
  7. memcache内存管理:使用Slab Allocation。原理相当简单,预先分配一系列大小固定的组,然后根据数据大小选择最合适的块存储。避免了内存碎片。(缺点:不能变长,浪费了一定空间)memcached默认情况下下一个slab的***值为前一个的1.25倍。
  8. redis内存管理: Redis通过定义一个数组来记录所有的内存分配情况, Redis采用的是包装的malloc/free,相较于Memcached的内存 管理方法来说,要简单很多。由于malloc 首先以链表的方式搜索已管理的内存中可用的空间分配,导致内存碎片比较多。

Amazon 对于使用缓存给出的建议和注意事项

  • 确保从成本、延迟和/或可用性改善方面来看确实有合理的需求来引入缓存。确保数据可以缓存,这表示可以跨多个客户端请求来使用数据。对缓存将带来的价值持怀疑态度,并通过仔细评估来确定收益将超过缓存带来的额外风险。
  • 计划按照与服务组和基础设施其余部分相同的严格流程来操作缓存。不要低估这项工作。发送有关缓存利用率和命中率的指标,以确保对缓存进行适当调整。监控关键指标(例如 CPU 和内存),以确保外部缓存队列处于正常状况和适度扩展。设置这些指标的相关警报。确保不必停机或造成大规模的缓存失效即可扩展缓存队列(即验证一致性哈希是否按预期工作)。
  • 运用实证方法仔细选择缓存大小、过期策略和移出策略。执行测试,并使用前一个要点中提到的指标来验证和调整这些选择。
  • 确保服务灵活应对缓存不可用的情况,其中包括各种会导致无法使用缓存数据来满足请求的情况。这些情况包括冷启动、缓存队列中断、流量模式变化或下游服务长时间中断。在许多情况下,这可能意味着要舍弃一些可用性来确保服务器和依赖服务不会断流(例如,通过卸除负载、限制对依赖服务的请求或提供过时的数据)。在禁用缓存的情况下运行负载测试,以便验证这一点。
  • 考虑维护缓存数据所涉及的安全问题,包括加密、与外部缓存队列通信时的传输安全性以及缓存投毒攻击和侧信道攻击的影响。
  • 设计让缓存的对象随着时间推移而演变的存储格式(例如使用版本号),并且编写能够读取较旧版本的序列化代码。请提防缓存序列化逻辑中的致命错误。
  • 评估缓存处理下游错误的方式,并考虑维护具有不同 TTL 的负缓存。不要通过反复要求获得同一个下游资源和丢弃错误响应来造成或扩大中断问题。

  •参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值