Redis专题(三) ——Redis事务与过期时间(缓存分析)

Redis专题(三)——Redis事务与过期时间(缓存分析)

(原创内容,转载请注明来源,谢谢)

一、事务(Transaction)

1、概述

事务的定义和关系型数据库一样,保证各个步骤操作的原子性。另外,也保证这几个步骤之间不会插入其他的步骤。但是,redis的事务没有回退的功能。

redis事务开始和结束的命令分别是MULTI和EXEC,在这两个命令之间的其他命令,redis都会先存在队列中,待接收到EXEC后一起执行。会返回一串的内容,返回值的顺序和语句顺序一致。

当输入MULTI,尚未输入EXEC时,如果redis和客户端断线,则multi后面的命令全部不执行,并且redis会清空刚刚还没执行的队列;但是如果已经输入EXEC,则即使后面发生断网,中间的命令也会执行,因为命令已经存储在redis的队列中。

另外,multi和exec之间的命令会同步执行,一起返回结果,所以不能在事务里面先获取上一个命令操作的值进行下一个命令的操作。

2、错误处理

1)语法错误

如果在multi和exec之间有语法错误,则所有的命令都不会执行,包括正确的命令。

2)运行错误

运行错误时,除了错误的命令,其他正确的命令都会被执行。

3、WATCH命令

watch类似锁的功能,当watch某个key后,果在事务之前修改了此key,则在事务中无法操作此key。watch只针对一次的事务,即当匹配到第一个exec后,就不再监听事务。

因此,执行一次exec后,就会取消对所有key的watch。

如果要提前取消watch,则可以在事务命令multi之前,发送一个UNWATCH命令,则取消所有的watch。

但是,如果键是在过期时间后被自动删除,并不会被watch认为键被改变。

4、取消事务

DISCARD命令,使用后会放弃执行事务的所有命令。如果遇到watch,则此时除了放弃事务,还会自动再执行一个unwatch命令,取消监视。

二、过期时间

redis的过期时间使用场景很广泛,当需要设置缓存、令某个值仅在一段时间内有效(如优惠券等)、设置最短访问间隔(防止爬虫太多导致服务器宕机),则都需要设置过期时间。

1、命令

1)设置失效时间

1. EXPIRE keyseconds,seconds是一个数字,即设置key在seconds秒之后失效,second要求是整数,即最少是1秒。当键不存在或者设置失败会返回0,否则返回1。

2. PEXPIRE keymillsecond,相当于设置毫秒,PEXPIRE key 1000 等效于EXPIRE key 1。

3. EXPIREAT keyunixtime,将key的过期时间以unix时间进行设置,单位是秒。

4. PEXPIREAT keyunixmilltime,与3的区别是这个是设置毫秒的。

2)查看还有多久有效

TTLkey,返回值是剩余的时间,单位是秒。如果不存在,则返回-2;如果没有设置过期时间,则返回-1。(这是redis2.8版的,2.6版则不存在和没有设置过期都是-1)

PTTLkey,返回剩余的毫秒数。

3)取消时间限制

1. PERSIST key,则此时再对key进行TTL命令查看,会发现返回-1。

2.重新SET key value,则此时会清除原来的时间限制。因此如果对值进行重新设置,需要重新设置失效时间。

3.重新expire key seconds,则会重置key的失效时间。

4.除了set,其他只对键值进行操作的命令,如lpush、hset、incr等均不会影响过期时间。

2、业务场景

1)缓存

redis是将数据存在内存中,因此可以避免I/O的操作,以加快速度。

通常,在读数据库的时候,会先读缓存,如果有的话则直接返回,如果没有的话会去数据库拉数据,并把数据设置在redis上,再返回。此时,需要对redis的键名进行考量,通常要设置类似:id:title等作为键,把值序列化或者json后进行存储。存储的数据类型也需要考虑,是放于set、hash还是list,或者特殊情况下用sorted set。

但是,也不是所有的操作放入缓存,只有大容量(图片、长评论、文章等)或者频繁改动(如访问量)等放于缓存。相应的失效时间也需要考虑好。

对于新增,通常使用懒加载的配置,即新增数据不更新缓存,会等到查询的时候再更新缓存;但是修改、删除数据的时候,就有很多的解决方案了。

对于修改、删除数据,可以用类unix系统的方式进行处理,称为WriteBehind Caching Pattern,又称Write Back。即当更新、删除数据时,会先查缓存,如果没有查到,则直接操作数据库。如果查到有缓存,则更新缓存,并给缓存增加一个已经被改动的标记;当要删除操作时,则对缓存加一个删除标记。

系统有独立的地方记录上述每一处缓存的改动,当程序执行到结束时,会统一查看缓存的改动情况,并统一对数据库进行操作。

此方法在高并发时,在命中缓存的情况下,必然数据一致性:

当更新了数据,此时如果有其他并发的再来查询,会查询到最新的数据(因为命中缓存,直接从缓存查看结果);如果要更新操作时,由于被加了已经更新的标签,不允许再次更新,则后面的更新会返回错误码;如果要删除,则可以删除,并增加删除标签(也可以根据业务需要,配置成不允许删除)。

当删除了数据,由于数据已经被加上删除标签,则此时再次增删改查,会发现此删除标签,则会返回空结果,不从数据库查询。

程序执行结束后,会根据标签,有修改标签的对数据库相应字段进行update,有删除标签的删除数据库相应数据。

2)设置优惠券

优惠券的存储可以用优惠券:优惠券id:优惠券类型的方式作为键,值可以设置1,并根据优惠券的使用时间定制expire second。当查询优惠券有效期或者使用优惠券时,使用ttl命令查询键,如果过期则该键不存在,此时则返回-2,否则返回优惠券的有效期。

3)最短访问间隔

此场景设置ip:ip值:业务场景为键,值可以设置1,并且设置expire second。当某个ip访问时,在redis中进行查询,如果键存在,则说明在最短访问间隔内,则不允许访问;如果键不存在,则说明不在最短访问间隔,则设置一个值,并且本次允许访问。

4)时间段内访问总数

如果要设置用户某个时间段(如一分钟内)可以访问的页面总数,则可以用列表的方式进行存储。当用户进行访问时,先用llen判断加上这个是否超过10个,如果不是则lpush,并且允许此次访问;如果超过,则要判断这个和最右边的第一个(lrange -1,1)的时间差是否在1分钟内,如果在一分钟内,则不改变此list,并且不允许用户的此次访问;如果超过一分钟,则lpush此次的时间,并且rpop第一个时间,允许用户此次访问。

3、redis用作缓存的时间设置

缓存的时间设置太长,会导致redis占用大量的内存;但是设置的太短,又会使得redis的作用减少。因此,可以通过修改配置文件的maxmemory参数,设置redis的最大占用内存,并且设置maxmemory-policy设置内存超出时的策略。

内存超出时会自动删除数据,删除的规则通常采用LRU(Least Recently Used),最近最少使用原则。另外也可以设置其他规则,如不同的参数值确定是否删除未设置过期时间的键,或随机删除一个键,或删除过期时间最近的一个键,或者不删除仅返回错误。

——written by linhxx 2017.08.05

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-08-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏性能与架构

Mysql 5.7 主从复制的多线程复制配置方式

数据库复制的主要性能问题就是数据延时 为了优化复制性能,Mysql 5.6 引入了 “多线程复制” 这个新功能 但 5.6 中的每个线程只能处理一个数据库,所以...

2704
来自专栏NetCore

Sync Framework 词汇表

Sync Framework 词汇表 此词汇表列出和定义了 Microsoft Sync Framework 涉及的概念和术语。 术语 批处理 (batch...

1876
来自专栏鬼谷君

redis的info

1104
来自专栏运维小白

4.3/4.4 磁盘分区

添加虚拟磁盘 第一步,选择虚拟机中的“设置” ? 第二步,选择“添加硬盘” ? 第三步,选择_SCSI (推荐) # 保持默认 ? 第四...

2005
来自专栏晓晨的专栏

.NET Core 实现 Redis 批量查询指定格式的Key

Redis 作为当前最流行的内存型 NoSQL 数据库,被许多公司所使用,作为分布式缓存。我们在实际使用中一般都会为 key 带上指定的前缀或者其他定义的格式。...

1223
来自专栏Hadoop实操

使用Hive SQL插入动态分区的Parquet表OOM异常分析

当运行“INSERT ... SELECT”语句向Parquet或者ORC格式的表中插入数据时,如果启用了动态分区,你可能会碰到以下错误,而导致作业无法正常执行...

9848
来自专栏Web 开发

深入Sever-Sent Events

Server-Sent Events(SSE)实现了服务器向浏览器单向推送消息的能力,前面文章有提到过,今天这里来详细讲解下。

580
来自专栏决胜机器学习

Redis专题(十二) ——Redis特殊情况处理机制

Redis专题(十二) ——Redis特殊情况处理机制 (原创内容,转载请注明来源,谢谢) 一、内存淘汰 当redis的内存不足时,需要采取内存淘汰的方法,...

3378
来自专栏about云

zookeeper原理

问题导读 1.zk service什么情况下不可用? 2.zk写数据,什么时候才算完成? 3.zk读数据可以在任意一台zk节点上,为什么? 4.zk znod...

2866
来自专栏性能与架构

nginx 缓存机制

Nginx缓存的基本思路 利用请求的局部性原理,将请求过的内容在本地建立一个副本,下次访问时不再连接到后端服务器,直接响应本地内容 Nginx服务器启动后,会对...

4016

扫码关注云+社区