Redis事务机制和缓存穿透、雪崩、击穿

1、常用命令

MULTIEXEC命令
以 MULTI 开始一个事务,然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set members 36
QUEUED
127.0.0.1:6379> get members
QUEUED
127.0.0.1:6379> exec
1) OK
2) "36"
127.0.0.1:6379>

DISCARD命令
DISCARD 命令用于取消一个事务, 它清空客户端的整个事务队列, 然后将客户端从事务状态调整回非事务状态, 最后返回字符串 OK 给客户端, 说明事务已被取消。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set username root
QUEUED
127.0.0.1:6379> get username
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> get username
(nil)
127.0.0.1:6379>

WATCH命令
WATCH 命令用于在事务开始之前监视任意数量的键: 当调用 EXEC 命令执行事务时, 如果任意一个被监视的键已经被其他客户端修改了, 那么整个事务不再执行, 直接返回失败。
在窗口一watch password,然后set password

127.0.0.1:6379> WATCH password
OK
127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> set password 123456
QUEUED
127.0.0.1:6379> get password
QUEUED

在窗口二修改password

127.0.0.1:6379> set password 456789
OK
127.0.0.1:6379>

此时回到窗口一,提交事务,执行失败

127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379>

2、Redis事务ACID

原子性(Atomicity)
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。如果一个事务队列中的所有命令都被成功地执行,那么称这个事务执行成功。

一致性(Consistency)
在正常状态下一个事务的所有命令是能按照原子性的原则执行的,但是执行的中途遇到错误,不会回滚,而是继续执行后续命令, 如下:

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set key1 value1
QUEUED
127.0.0.1:6379> sadd key1 value2
QUEUED
127.0.0.1:6379> set key2 value2
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) OK
127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> get key2
"value2"
127.0.0.1:6379>

在set key1 value1之后,执行了一条错误的命令sadd key1 value2,第一条指令并不会回滚,而是继续执行下面一条set key2 value2指令。

隔离性(Isolation)
WATCH 命令用于在事务开始之前监视任意数量的键: 当调用 EXEC 命令执行事务时, 如果任意一个被监视的键已经被其他客户端修改了, 那么整个事务不再执行, 直接返回失败。

持久性(Durability
因为事务不过是用队列包裹起了一组 Redis 命令,并没有提供任何额外的持久性功能,所以事务的持久性由 Redis 所使用的持久化模式决定。

3、缓存穿透、雪崩、击穿

3.1、缓存穿透

什么是缓存穿透?
缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候, 在缓存中找不到对应key的value,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次 无用的查询)。这样请求就绕过缓存直接查数据库。

有什么解决方案来防止缓存穿透?
采用布隆过滤器BloomFilter:将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。
缓存空值:如果一个查询返回的数据为空(不管是数据不 存在,还是系统故障)我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。 通过这个直接设置的默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。

3.2、缓存雪崩

什么是缓存雪崩?
如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。 由于原有缓存失效,新缓存未存储,期间所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU 和内存造成巨大压力,严重的会造成数据库宕机。

有什么解决方案来防止缓存雪崩?
1、加锁排队
互斥锁解决,Redis的SETNX去set一个mutex key, 当操作返回成功时,再去数据库读取数据并回设缓存; 否则,就重试整个get缓存的方法

2、数据预热
缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的key

3、双层缓存策略
C1为原始缓存,C2为拷贝缓存,C1失效时,可以访问C2,C1缓存失效时间设置为短期,C2设置为长期。

4、设置不同的过期时间,让缓存失效的时间点尽量均匀

3.3、缓存击穿

什么是缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

解决方案
1、设置热点数据永远不过期。
2、加互斥锁,保证同一时刻,只能有一个线程去访问数据库。类似线程安全的懒汉单例模式实现。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • redis事务 Redis 通过 MULTI 、 DISCARD 、 EXEC 和 WATCH 四个命令来实现事务...
    全能程序猿阅读 2,154评论 0 11
  • redis中提供了事务处理机制。事务的两个主要特点: 1. 隔离性 ,事务中的命令都会被序列化,按顺序去执行,...
    大步向前blue阅读 523评论 0 0
  • 一、相关命令 1. MULTI (事物的开始) 用于标记事务块的开始。Redis会将后续的命令逐个放入队列中,然后...
    John_Phil阅读 1,244评论 0 0
  • Redis通过MULTI、EXEC、WATCH等命令来实现事务(transaction)功能。事务提供了一种将多个...
    HRADPX阅读 6,122评论 0 4
  • 马来西亚人在上海的常住人口有一万多人. 可以大致分为下列群体: (1)夫妻档一起从马来西亚过来工作/打拼/做生意 ...
    水晶蜜糖阅读 3,542评论 0 2