分布式缓存的选择和问题
如今,缓存系统得到了广泛的应用,可以用来提高并发数、数据吞吐量和快速响应能力。然后,当数据量达到某个程序时,独立环境似乎不堪重负,需要一个分布式缓存系统。
1.缓存系统的选择
图1-1
如上图所示,首先,缓存大致可以分为四类。
CDN缓存:CDN是一个内容分发网络,CDN边缘节点缓存数据。
反向代理缓存:如Nginx缓存。
本地缓存:显示了EhCache和番石榴缓存
分布式缓存:每个缓存系统
本文主要讨论各种分布式缓存系统,如下图所示,其中列出了五种类型:
然后比较MemCache、Tair和Redis
其中,使用场景没有那么普遍和广泛。
EvCache:网飞基于memcached & spymemcached的缓存方案。
Aerospike:是一个基于固态硬盘的K-V NoSQL数据库。
此外,还有三种常见的缓存系统。
Tair:阿里是开源的,跨机房,性能随着节点的增加线性增加。它适用于大量数据。Tair也有三个引擎
LDB:基于google levelDB,支持kv和hashmap类结构,性能更低,持久可靠性最高。
MDB:基于memcache,支持kv和类hashMap,性能最好,不支持持久存储。
RDB:基于Redis。
Memcache:不支持数据同步,分布式支持较差。
Redis:社区活跃,使用最多。
综上所述,总的来说,考虑到适用性和稳定性,Redis是构建缓存系统的最佳选择。以下将基于Redis的介绍。
2.Redis集群缓存方案
如图所示,列出了Redis集群的高可用性方案,基本上可以分为三种类型。
主从机制
普通集群架构搭建简单,主要实现读写和备份分离。主机可以负责读写,从机负责备份。但也存在故障恢复复杂、层次拓展困难、写作能力有限等问题。结构图如下:
哨兵机制
Redis Sentinel是社区版推出的原生高可用解决方案。一个或多个sentinel实例监控任何master和slave服务器,当Master宕机时,宕机服务器下的Slave服务器会自动升级为主服务器,从而保证系统的可用性。与主从监控和主机选择相比。但主要问题是保证Master的HA切换。结构图如下:
“已分发”
事实上,以上两种机制只能算作“集群”,而不是严格意义上的“分布式”。接下来,让我们看看分布式解决方案。
"
集群强调高可用性,而分布式强调协作。
3.Redis分布式缓存方案
任何分布式存储系统面临的第一个问题是分片问题,可以分为三种方式,如顶部的图1-1所示。
客户端碎片
顾名思义,数据分片的路由功能是给客户端的,但这是一个静态分片,可维护性差。基本上不会考虑。
代理碎片
通过代理分发到具体的redis实例。有两种常见的解决方案。-Twemproxy Twitter开源轻量,但不再维护,无法顺利扩容/缩容。它的操作维护不是很友好,性能一般。-Codis在豌豆荚中是开源的,具有扩展的支持级别、完善的运维平台以及比Twemproxy更快的性能。Codis在国内应用广泛,很多公司基于代理碎片化的思想开发了自己的二次方案。但是Codis不再被维护。
其实这两种代理分片方案都是Redis官方未能推出好的分布式方案时的策略,官方更新后不再维护。
服务器端碎片
这是关于Redis的官方计划,Redis-cluster。
在Redis3.0之前,没有更好的分布式解决方案,这也是第三方解决方案出现的原因。从3.0开始,政府推出了分散的分布式解决方案。集群中有16384个哈希槽,每个节点负责其中的一些。
先看拓扑图:
每个节点打开两个TCP连接,一个负责向客户端提供服务,另一个负责节点间的通信。
现在我们来谈谈CAP:一致性、可用性和分区容忍度。对于分布式系统,CAP必须牺牲一个。Redis集群的设计目标主要是高性能、高可用性和高可扩展性,所以我们不得不放弃一些数据一致性。
数据一致性:由于Redis群集使用异步复制,在某些情况下,例如主节点关闭但未同步到从节点,写入可能会丢失。当绝对需要支持同步写入时,可以通过WAIT命令来实现,这样可以大大降低漏写的可能性。
可用性:当集群中的一些节点出现故障时,整个集群可以响应客户端的读写请求。
节点定期相互ping通。当超过一半的Master判断某个节点失败时,会标记为fail,节点离线的消息会广播到集群。如果下面的线路节点是带有插槽的主节点,请从其从节点中选择一个替换节点。
高性能和扩展性:操作一个密钥时,处理前不会找到节点,而是直接重定向到节点,同时相比代理分片,会减少代理的连接丢失。
但是在操作的时候,需要位于同一个插槽上,所以需要使用,为了方便,用力把一些按键映射到每个插槽上。
在扩展方面,Redis Cluster支持多达1,000个节点的线性扩展。向群集添加新节点后,可以通过命令从现有节点分配插槽。
3.缓存常见问题
以上介绍简要介绍了常见的缓存系统,并详细列举了基于Redis的集群方案。先说说缓存系统的常见问题。
如下图所示,列出了七个常见问题。
3.1.缓存穿透
它指的是访问不存在的数据,从而绕过缓存,直接向数据源请求。当请求太多时,会给数据库带来压力。
空键:是指对于不存在的数据,将空键存储到缓存系统中,以便返回下一次访问。但只适用于空密钥有限、重复密钥请求概率高的数据。如果数字很大且不重复,将会创建许多无用的密钥。
布隆过滤器:布隆过滤器是一个长二进制向量和一系列随机映射函数。一种筛选器,可用于搜索元素是否向集合中添加了一对空值。空和时间之间的效率非常高。但是哈希引起的冲突可能会被误判,密钥因为没有存储而无法删除。适用于空不同密钥、重复请求概率低的数据。
3.2.缓存故障
缓存崩溃实际上是缓存雪崩的一种特殊情况。这意味着当一些热点密钥过期时,大量请求将渗透到数据库中。
当缓存失败时,互斥锁不会立即加载数据库。您可以使用SETNX等命令设置互斥键。当操作成功返回时,意味着获得了锁。此时,线程执行加载数据库操作并更新缓存。否则,重试get cache方法而不获取锁。但要注意死锁风险。
过时的
这里过期有两个概念,一个是没有过期时间,真的过期了,没事~ ~
二是通过业务逻辑存储密钥的到期时间。请求是判断是否小于该值,如果小于,则在后台异步更新。
3.3.缓存雪崩
同时大量缓存失败,请求到达DB。
随机时间:设置到期时间时,可以在基础时间上增加一个随机时间,意味着实现批量到期。
后台更新:把更新失效的工作交给后台定时线程。
限流+本地缓存:比如ehcache本地缓存+Hystrix限流。
双缓存:类似于设置缓存,永不过期。
3.4.缓存更新和一致性
如果数据一致性得到保证。列出四种更新策略:
一旁缓存:最常用的。当失败时,返回源获取数据并更新;命中时,返回缓存的数据;首先更新数据源,然后与您一起更新缓存。
回写:更新数据时,只更新缓存,不更新数据源。缓存异步批处理更新数据库
读/写通过
直写:当有数据更新时,如丢失缓存,直接更新数据库并返回。如果它命中缓存,请更新缓存,然后由缓存本身更新数据库。
通读:数据源由缓存系统更新。如果读取数据时缓存失败,将检索源数据来更新缓存。
3.5.热门数据
如何处理热点数据?
拆分复杂结构:如二级数据结构,拆分,使热键被拆分成若干个键并分布到不同的节点。
迁移热点:对于Redis Cluster来说,热点密钥所在的插槽可以独立迁移到一个节点上,从而减轻其他节点的压力。
多副本:复制多个缓存副本,将请求分发到多个节点,减轻单个缓存服务器的压力,适合多读少写。
3.6.缓存预热
这意味着一些缓存的数据可以提前加载到缓存系统中。提前避免在热点对库的大量数据请求。
3.7.缓存退化
意味着当访问量急剧增加,服务问题或非核心服务影响核心流程的性能时,仍然需要保证主要服务的可用性。可以根据一些关键数据自动降级,也可以由交换机手动降级。
4.Redis集群的使用
Redis集群环境的建立和基本使用非常简单。
不管是什么方法,只要设置了N个redis服务,所有服务都可以相互通信,随意进入一个redis服务。类型:
动手吧。之后,您可以使用和查看集群和节点信息。
对于JAVA服务器端开发,Spring Data Redis从1.7开始就支持Redis集群,只需要配置Master节点地址。
加入依赖项
它可以通过RedisTemplate使用。
5.摘要
从缓存系统的选择出发,介绍了几种基于Redis的集群方案,重点介绍了Redis集群方案。然后列举了缓存系统常见的问题和解决方法,最后简单说明了使用方法。
当然,如何落地,如何解决这些问题,需要根据实际场景来分析处理。
版权声明:内容来源于网络,版权归原创作者所有。除非我们无法确认,否则我们将标记作者和来源。如有侵权,请告知,我们将立即删除并道歉。谢谢你
感谢阅读