1. 多层次
分布式缓存宕机,本地缓存还可以使用
2. 数据类型
-
简单数据类型
Value
是字符串或整数或二进制,Value
的值比较大(大于100K
),只进行setter
和getter
,可采用Memcached
。
Memcached
纯内存缓存,多线程K-V
-
复杂数据类型
Value
是hash
、set
、list
、zset
,需要存储关系,聚合,计算。
可采用Redis
3. 要做集群
分布式缓存集群方案(Redis)
- codis
- 哨兵+主从
- RedisCluster
4. 缓存的数据结构设计
4.1 与数据库表一致
数据库表和缓存是一一对应的,缓存的字段会比数据库表少一些,缓存的数据是经常访问的;比如:用户表,商品表
4.2 与数据库表不一致
需要存储关系,聚合,计算等;比如某个用户的帖子、用户的评论。
以用户评论为例,DB
结构如下:
如果要取出 UID
为 1000
的用户的评论,原始的表的数据结构显然是不行的。
我们应做如下设计:
key
:UID
+时间戳(精确到天) ;评论一般以天为计算单位
value
:Redis
的 Hash
类型。field
为 id
和 content
expire
:设置为一天
案例:设计拉勾首页缓存职位列表、热门职位
拉勾网(www.lagou.com
),是国内的招聘门户网站,亿万级PV
,单机响应性能QPS
万级。
首页分析:
- 职位时时变化,不能使用静态
html
- 采用模板技术,数据在服务端拿出,不能为空
- 数据不一定实时
架构图如下:
- 静态文件
在nginx
中,放置静态文件,比如css
,js
, 图片等
server {
listen 80 default_server;
server_name localhost;
root /mnt/blog/;
location / {
}
#要缓存文件的后缀,可以在以下设置。
location ~ .*\.(gif|jpg|png|css|js)(.*) {
proxy_pass http://ip地址:90;
proxy_redirect off;
proxy_set_header Host $host;
proxy_cache cache_one;
proxy_cache_valid 200 302 24h;
proxy_cache_valid 301 30d;
proxy_cache_valid any 5m;
expires 90d;
add_header wall "hello";
}
}
-
职位列表
数据特点
:固定数据,一次性读取
方案
:在服务器开启时一次性初始化(从xml
)到服务器本地缓存,采用Guava Cache
,Guava Cache
用于存储频繁使用的少量数据,支持高并发访问,也可以使用JDK
的CurrentHashMap
,需要自行实现 -
热门职位
数据特点
:频繁变化,不必时时同步;但一定要有数据,不能为空
方案
:数据从服务层读取(dubbo
),然后放到本地缓存中(Guava
),如果出现超时或读取为空,则返回原来本地缓存的数据。
注意
:不同的客户端看到的数据有可能不一样。 -
数据回填
从Dubbo
中读取数据时,先读取Redis
集群的缓存,如果缓存命中则直接返回。如果缓存不命中则返回本地缓存,不能直接读取数据库。采用异步的形式从数据库刷入到缓存中。 -
热点策略
对于热点数据我们采用本地缓存策略,而不采用服务熔断策略,因为首页数据可以不准确,但不能不响应。