掌握之分布式-4.缓存
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了掌握之分布式-4.缓存相关的知识,希望对你有一定的参考价值。
掌握高并发、高可用架构第三章 分布式
本章介绍分布式架构的底层技术。主要说明面试过程中可能被问到的技术点。
第四节 缓存
缓存穿透
缓存学雪崩
Redis
Memcached
Guava
1. 缓存使用中的几个问题
-
缓存穿透:查询缓存和数据库中一定不存在的数据时,每次查询都是直接到数据库的,这种现象称为缓存穿透
此时,如果有大量的请求时,会对数据库造成直接冲击,甚至会导致崩溃
- 缓存空数据
- 使用BloomFilter(布隆过滤器),即缓存数据库中所有存在的Key
-
缓存雪崩:缓存服务器宕机了,那么所有查询直接落在数据库,对数据库造成巨大压力
- 使用缓存集群,增大可用性
- 本地缓存
- 使用Hystrix(熔断器),它通过熔断、降级、限流三个手段来降低雪崩造成的损失
- 持久化机制
-
热点数据集中失效:本身大批量数据同时失效对Redis服务器也会造成影响,可能会出现慢的情形;再者失效期间,所有的用户请求都会落到数据库上,也会对数据库造成巨大的压力
- 使用互斥锁,当发现缓存失效后,第一个请求加锁,然后去查询数据库,把数据存入缓存,这个操作只有一次,其他的请求都是阻塞的,查询执行完成后释放锁,此时已经有了缓存数据,也不会对数据库造成压力了
- 对热点数据设置不同的失效时间,加上时间戳
2. Redis的数据结构
-
string
Redis的最基本的数据结构,可以包含任意数据。一个key对应一个string的value。string类型是二进制安全的。每个string的value最大可以512M
支持的方法:set、get、mset、mget、setex、setnx -
list
列表,一个简单的字符串列表,按照插入的顺序排序,可以向头部(左边)或尾部(右边)添加数据,底层是链表
支持的方法:lpush、lpushx、lpop、lrange、lset、lindex、llen、rpush、rpop -
set
string的无序集合
支持的方法:sadd、scard、sdiff、sinter、sunion、sismember、smembers -
zset(sorted set)
sorted set有序集合,也是string的集合,但是有序的
支持的方法:zadd、zcard -
hash
hash是一个键值对集合,是一个string类型的key(这里叫做field)和value的映射表,key相当于hash的名字,类似于Java中的Map<String, Map<String, String>>
支持的方法:hset、hget、hdel、hexists、hkeys、hlen、hgetall3. Redis适合的场景
- 会话缓存(Session Cache)
- 全页缓存(FPC)
- 队列,利用list数据结构
- 排行榜/计时器,利用zset
- 发布/订阅系统
4. Redis处理并发竞争问题
Redis采用单进程单线程模式,本身没有锁的概念,其对于多个客户端访问不存在并发的问题
通过jedis客户端进行并发访问时会出现连接超时、数据转换错误、阻塞等,通过以下方式解决:
- 客户端与Redis通信时,可以对连接进行池化,每个对Redis的读写操作均采用synchronized
- 服务器端可以使用setnx
5. Redis设置过期时间
- 在set key的时候,可以指定expire time,也就是过期时间
- Jedis有单独的expire方法
redis通过定期删除和惰性删除来删除过期的key
- 定期删除,Redis每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。因为数据量巨大,遍历全部key不现实,太耗CPU,所以是随机的
- 惰性删除,发起查看key时,会查看key是否过期,如果过期则删除
只靠这两种机制还是删除不完全的,此时就需要内存淘汰机制了
6. Redis内存淘汰机制(如何保证热点)
- volatile-lru:从已设置过期时间的数据集合(server.db[i].expires)挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集合中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集合中随机挑选数据删除
- allkeys-lru:在键空间中挑选最少使用的数据淘汰(这种策略最常用)
- allkeys-random:从数据集(server.db[i].dict)中随机淘汰
- no-eviction:禁止淘汰数据,当写入数据时报错处理
4.0新增
- volatile-lfu:从已设置过期时间的集合中挑选最不常用的数据淘汰
- allkeys-lfu:在键空间中挑选最不常用的数据淘汰
7. Redis的持久化策略
支持两种持久化策略:一种是快照(snapshotting,RDB),另一种是只追加文件(append-only file,AOF)
- 快照持久化(RDB),通过创建快照来存储在内存里的数据在某个时间点的副本;创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器,还可以留在本地
是默认的持久化方式。在redis.conf中有以下配置
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,就会触发BFSAVE创建快照 save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,就会触发BFSAVE创建快照 save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,就会触发BFSAVE创建快照
- AOF(append-only file),AOF的实时性更好,默认没有开启,通过以下设置进行开启
appendonly yes
开启AOF后,每执行一条更改数据的命令,Redis就将该命令写入硬盘中的AOF文件
在redis.conf中有三种不同的AOF配置
appendfsync always #每次更改数据都会写入AOF文件,这会严重降低Redis的性能 appendfsync everysec #每秒同步一次,将多个命令同步到磁盘 appendfsync no #由操作系统决定何时同步
8. Redis事务
通过
MULTI
,EXEC
,WATCH
等命令来实现事务功能9. Redis的分布式锁
通过setnx实现
10. Redis与Memcached的区别
- Redis支持丰富的数据结构,Memcached仅支持字符串
- Redis支持持久化,Memcached不支持
- Redis支持主从、哨兵、Cluster的集群模式,Memcached没有
- Redis是单线程多路IO复用模型,Memcached是多线程非阻塞IO复用模型
11. Redis的集群
- 主从模式
主数据库(master)和从数据库(slave)
- 主数据库进行读写操作,当数据发生变化时会自动同步到从数据库
- 从数据库是只读的
-
一个master对应多个slave,一个slave只能有一个master
- 哨兵模式
哨兵的作用是监控Redis系统的运行情况
- 监控主从是否正常运行
- master出现故障时,自动将slave转换为master
- 多哨兵之间也会互相监控
-
多个哨兵监控一个master
- 集群模式
只要将每个节点的cluster-enable配置打开即可,每个集群最少三个节点
Memecached
选择Memcached的理由:简单
本地缓存:Ehcache、Guava
Redis和Memcached的区别
- Redis支持的数据结构更丰富
- Redis支持持久化,Memcached不支持
- Memcached没有原生的集群模式,而Redis有主从、哨兵、集群
- Memcached是多线程、非阻塞IO复用的网络模型,Redis是单线程多路IO复用的网络模型
以上是关于掌握之分布式-4.缓存的主要内容,如果未能解决你的问题,请参考以下文章