redis key expired (redis additional feature articles)

Redis additional features

In previous lessons, we continue to introduce six Redis data structures, which are strings, lists, hash, collection, ordered set and HyperLogLog.

In addition, we also explains how to use the database Redis commands to manipulate the database itself: for example, using the DEL command to delete a key database using SCAN command progressively traverse the entire database, using DBSIZE return key database contains the number, and so on.

On the basis of these functions on the database, Redis also provides some additional features, they are: the function keys expired, publish and subscribe functions, pipelining functions, transaction capabilities and Lua scripting capabilities.

These additional functions or is used to solve a specific problem, or is used to enhance the function of the database, so that the database can better set up operations in the next few lesson, we will continue to introduce these additional features.

Key features expired

Let Redis automatically delete a specific key at a specified time.

Key expired functions related commands

Here Insert Picture Description

Setting survival time

Redis provides two key command to set the time to live (TTL, time to live), they are:
Here Insert Picture Description
if the given key does not exist, then the EXPIRE and PEXPIRE returns 0, the setting is a failure; if the command returns 1, then indicating setting finish.
When a key is set survival time, its survival will decrease over time: the last time a millisecond, reducing survival time of one millisecond key; a second time in the past, the survival time of reduced bond a second; and so on.
When a key survival time is reduced to less than 0:00 , Redis will automatically delete the key.

EXPIRE example
redis> SET msg "hello world"
OK
redis> EXPIRE msg 5 # 设置生存时间
(integer) 1
redis> EXISTS msg # 仍然存在
(integer) 1
redis> EXISTS msg # 已被自动删除
(integer) 0

Here Insert Picture Description
Strictly speaking, set the survival time of 5, 6 seconds to make key exists.

PEXPIRE example
redis> PEXPIRE number 5500
(integer) 1
redis> EXISTS number
(integer) 1
redis> EXISTS number
(integer) 0

Here Insert Picture Description
Note 1: a second = 1000 ms
Note 2: Redis checked once every 100 milliseconds, the default key is expired, so that the table is 100 milliseconds per listed.

Set an expiration time

Redis 提供了两个命令用于设置键的过期时间(expire time):
Here Insert Picture Description
如果给定的键不存在,那么 EXPIREAT 和 PEXPIREAT 将返回 0 ,表示设置失败;如果命令返回 1 ,那么表示设置成功。
对于被设置了过期时间的键来说,当键的过期时间小于当前时间的时候,Redis 就会自动地删除该键。

EXPIREAT 示例
 redis> SET msg "time to go"
 OK
 redis> EXPIREAT msg 1000000005
 (integer) 1
 redis> EXISTS msg # 1000000005 之前
 (integer) 1
 redis> EXISTS msg # 1000000005 之后
 (integer) 0

Here Insert Picture Description

PEXPIREAT 示例
redis> SET song "Last Night, Good Night"
OK
redis> PEXPIREAT song 1000000005500
(integer) 1
redis> EXISTS song # 1000000005500 之前
(integer) 1
redis> EXISTS song # 1000000005500 之后
(integer) 0

Here Insert Picture Description

生存时间和过期时间的区别

设置生存时间和设置过期时间都可以让 Redis 自动删除指定的键,它们的区别在于设置“键什么时候要被删除”的方式不同
• EXPIRE 和 PEXIRE 的作用是让键在 N 秒钟或者 N 毫秒之后被删除。
• 而 EXPIREAT 和 PEXPIREAT 的作用则是让键在指定的 UNIX 时间到达之后被删除。
带有生存时间的键就像是一个倒计时器,它会倒数 5、4、3、2、1、0,然后被删掉。
而带有过期时间的键则像是一个定时器,它会在指定的时间来临之后被删掉。

返回键的剩余生存时间

在为一个键设置过期时间或者生存时间之后,用户可以使用 TTL 命令或者 PTTL 命令查看这个键的剩余生存时间,以此来获知键还有多久才会被 Redis 删除:
Here Insert Picture Description

TTL 和 PTTL 示例
redis> SET msg "hello"
OK
redis> EXPIRE msg 10086
(integer) 1
redis> TTL msg
(integer) 10083
redis> PTTL msg
(integer) 10079336
redis> SET number 10086
OK
redis> EXPIREAT number 1408498480
(integer) 1
redis> TTL number # 距离 14...80 的秒数
(integer) 15
redis> PTTL number # 距离 14...80 的毫秒数
(integer) 11651

注意,Redis 并没有提供查看键的过期时间的命令,所以对于一个设置了过期时间的键来说,我们只能使用TTL 和 PTTL 来查看它的剩余生存时间。

移除键的过期时间或生存时间

PERSIST key
移除为键 key 设置的过期时间或生存时间,使得它不会被 Redis 自动删除。
移除成功时命令返回 1 ;如果命令没有设置过期时间或生存时间,那么命令返回 0 。 复杂度为 O(1) 。

PERSIST 命令
redis> SET msg "hello"
OK
redis> EXPIRE msg 30
(integer) 1
redis> TTL msg
(integer) 28
redis> PERSIST msg
(integer) 1
redis> TTL msg
(integer) -1
redis> SET number 10086
OK
redis> EXPIREAT number 1408499100
(integer) 1
redis> TTL number
(integer) 25
redis> PERSIST number
(integer) 1
redis> TTL number
(integer) -1

键过期功能的应用

自动更新缓存、自动刷新排行榜、定时删除的用户 Session。
示例:自动更新的缓存
以下是《字符串》一节介绍过的缓存方法,但这个方法并不实用,因为程序需要通过手动删除旧的缓存来进行缓存更新,否则程序就会一直使用同一个缓存:

@app.route(/)
def index():
 cached_content = GET ‘index’
 if cached_content:
 return cached_content
 else:
 content = fetch_and_create_index()
 SET ‘index’ content
 return content
以下是使用键过期功能实现的,一个每五分钟就会自动更新一次的缓存实现:
@app.route(/)
def index():
 cached_content = GET ‘index’
 if cached_content:
 return cached_content
 else:
 content = fetch_and_create_index()
 SET ‘index’ content
 EXPIRE ‘index’ 5*60 
 return content
SETEX 命令

因为
SET key value
EXPIRE key seconds
这个模式经常出现,所以 Redis 在 2.0 版本新增了 SETEX 命令:
SETEX key seconds value
这个命令相当于原子地执行 SET 命令和 EXPIRE 命令。

PSETEX 命令

在 Redis 2.6.0 ,Redis 开始支持毫秒精度的过期时间和生存时间,并增加了相应的 PEXPIRE、PEXPIREAT、PTTL 三个命令,以及 PSETEX 命令:
PSETEX key milliseconds value
执行这个命令相当于原子地执行以下两个命令:
SET key value
PEXPIRE key milliseconds

SET 命令对生存时间的支持

在 Redis 2.6.12 版本,Redis 又对 SET 命令进行了修改,让它支持可选的 EX 参数和 PX 参数:
SET key value [EX seconds] [PX milliseconds]
执行 SET key value EX seconds 相当于执行 SETEX key seconds value ; 而执行 SET key value PX milliseconds 相当于执行 PSETEX key milliseconds value 。
尽管目前 SETEX 和 PSETEX 都能正常使用,但我个人 还是建议尽量使用 SET 而不是 SETEX 或者PSETEX ,因为使用 SET 来设置生存时间更简洁一些,而比较旧的 SETEX 和 PSETEX 在将来可能会被废弃。

修改之前给出的 cache.py ,增加一个 expire_put(name, content, ttl) ,让被设置的缓存可以在 ttl 秒之后自动被删除。
# coding: utf-8

class Cache:

def __init__(self, client):
self.client = client

def put(self, name, content):
self.client.set(name, content)

def get(self, name):
return self.client.get(name)

# 使用 SETEX 实现
def expire_put(self, name, content, ttl):
self.client.setex(name, content, ttl)

# 使用 SET + EXPIRE 实现
def expire_put2(self, name, content, ttl):
self.client.set(name, content)
self.client.expire(name, ttl)

# 使用 PSETEX 实现
def expire_put3(self, name, content, ttl):
"""
Python 客户端尚未支持 PSETEX 命令,
如果支持的话,我们可以通过将 ttl*1000 来调用 PSETEX
从而实现与 SETEX 相同的效果:

PSETEX name ttl*1000 content
"""
raise

# 使用 SET ... EX seconds 实现
def expire_put4(self, name, content, ttl):
"""
Python 客户端尚未支持 SET 命令的 EX 参数,
如果支持的话,我们可以用以下方法来实现与 SETEX 相同的效果:

SET name content EX ttl
"""
raise

# 使用 SET ... PX milliseconds 实现
def expire_put5(self, name, content, ttl):
"""
Python 客户端尚未支持 SET 命令的 PX 参数,
如果支持的话,我们可以用以下方法来实现与 SETEX 相同的效果:

SET name content PX ttl*1000
"""
raise
示例:自动刷新的排行榜

在介绍有序集合的时候,我们给出了日排行版的实现方法(rank_list.py),通过给日排行榜设置生存时间,我们可以让 Redis 在每个新的一天开始时,自动删除旧的排行榜。实现方法是,在每次添加一个 项到排行榜之后,执行以下检查:

# 如果排行榜还没有设置生存时间
 # 那么将它的生存时间设置为今天剩余的秒数
if TTL(ranklist) == -1:
 EXPIRE ranklist today_remain_seconds()

通过这个设置操作,程序可以让 Redis 自动删除每天的旧排行榜。
Here Insert Picture Description

修改之前给出的 rank_list.py 文件的 RankList.incr() 方法,为每个日排行榜设置恰当的生存时间或过期时间,使得每日的排行榜在一天 过后自动被删除。
# encoding: utf-8

from datetime import datetime, timedelta

def today_remaind_seconds():
    now = datetime.now()
    tomorrow = now + timedelta(days=1) - timedelta(hours=now.hour, minutes=now.minute,seconds=now.second)
    return (tomorrow-now).seconds

class DayRankList:

    def __init__(self, key, client):
        self.key = key
        self.client = client

    def incr(self, item, increment=1):
        # 注意在 redis-py 客户端中
        # zincrby() 方法是先给定元素后给定分值
        # 这和 ZINCRBY 命令规定的顺序正好相反
        self.client.zincrby(self.key, item, increment)

        # 注意 Python 客户端在键没有生存时间/过期时间时返回 None 而不是 -1
        if self.client.ttl(self.key) is None:
            self.client.expire(self.key, today_remaind_seconds())

    def get_top(self, n, show_score=False):
        return self.client.zrevrange(self.key, 0, n-1, withscores=show_score)
示例:实现用户 Session

用户 Session (会话)是一种验证用户身份的手段,通常会分 别储存在服务器端和客户端,一般由用户ID(uid)和 Session ID (sid)组成。

After the user has successfully logged sites, web browsers will return to the site of the Session stored, after each time a browser to view pages on the site, the browser will be stored inside the Session information be sent to the site along with the page request, this makes the site can check whether the client is logged in, and whether the specified user, and so on.

Session generally a week or every month will automatically expire, forcing the user to log in again to prevent the user forgets the password, or Session ID Zaoren crack.

User Session of the API and its implementation

Here Insert Picture Description

Session user uses examples
# 设置客户端,设置 Session 的生存时间为一个月(默认值)
session = Session(client)
# 为 ID 为 10086 的用户创建 Session ID
sid = session.assign(10086)
# 检查 Session ID 是否正确,将返回 True ,表示传入的 Session ID 正确
session.valid(10086, sid)
# 再次检查,这次将返回 False ,表示 Session ID 不正确
session.valid(10086, “WrongSessionID”)

review

Review (1/2)

Use the key feature allows Redis expires automatically delete a specific key at a specified time. Let Redis automatically delete keys in two ways, one is the key to survival time was set, and the other is to set the expiration time for the key:
• survival time as a countdown timer, it will be with the passage of time and dwindling, when survival time is reduced to less than zero, the key is deleted;
• expiration time is like a timer, when after a given time is reached, the key will be deleted.

Review (2/2)

Here Insert Picture Description

Published 252 original articles · won praise 151 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_39885372/article/details/104257445