Redis 面试宝典之 Redis 如何处理已经过期的数据?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 面试宝典之 Redis 如何处理已经过期的数据?相关的知识,希望对你有一定的参考价值。

参考技术A 本文讲的是 Redis 的键值过期之后的 数据处理 ,讲的是正常情况下的 数据清理 ,但面试者常常会把两个概念搞混,以至于和期望的工作失之交臂。我们本文的职责之一就是帮读者朋友搞清楚二者的区别,相信看完本文你就会对二者的概念有一个本质上的认识。

我们本文的面试题是,Redis 如何处理已过期的数据?

在 Redis 中维护了一个过期字典,会将所有已经设置了过期时间的键值全部存储到此字典中,例如我们使用设置过期时间的命令时,命令如下:

此命令表示 5s 之后键值为 mykey:java 的数据将会过期,其中 ex 是 expire 的缩写,也就是过期、到期的意思。

过期时间除了上面的那种字符类型的直接设置之外,还可以使用 expire key seconds 的方式直接设置,示例如下:

获取键值的执行流程是,当有键值的访问请求时 Redis 会先判断此键值是否在过期字典中,如果没有表示键值没有设置过期时间(永不过期),然后就可以正常返回键值数据了;如果此键值在过期字典中则会判断当前时间是否小于过期时间,如果小于则说明此键值没有过期可以正常返回数据,反之则表示数据已过期,会删除此键值并且返回给客户端 nil ,执行流程如下图所示:

这是键值数据的方法流程,同时也是过期键值的判断和删除的流程。

本文的面试题考察的是你对 Redis 的过期删除策略的掌握,在 Redis 中为了平衡空间占用和 Redis 的执行效率,采用了两种删除策略,上面的回答不完全对,因为他只回答出了一种过期键的删除策略,和此知识点相关的面试题还有以下这些:

常见的过期策略,有以下三种:

如何处理已弃用的函数'unarchiveObject(with:)'? [关闭]

【中文标题】如何处理已弃用的函数\'unarchiveObject(with:)\'? [关闭]【英文标题】:How to deal with deprecated function 'unarchiveObject(with:)'? [closed]如何处理已弃用的函数'unarchiveObject(with:)'? [关闭] 【发布时间】:2020-04-18 21:52:02 【问题描述】:

尝试从这里实现 KeychainWrapper:https://github.com/jrendel/SwiftKeychainWrapper 它运行良好,但在一段代码中我出错了:“'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead”

我尝试关注discussion,看起来很相似,但没有成功。

这段代码在这里:

open func object(forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> NSCoding? 
    guard let keychainData = data(forKey: key, withAccessibility: accessibility) else 
        return nil
    

    return NSKeyedUnarchiver.unarchiveObject(with: keychainData) as? NSCoding

How to NSKeyedUnarchiver.unarchiveObject

这是更新版本:

open func object(forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> NSCoding? 
guard let keychainData = data(forKey: key, withAccessibility: accessibility) else 
    return nil


let result = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(keychainData) as? NSCoding

return result

【问题讨论】:

请参考***.com/a/59170370/6920041 【参考方案1】:

您可以通过以下方式执行此操作...

let result = jsonDict["result"] as? NSDictionary ?? [:]
let data = try! NSKeyedArchiver.archivedData(withRootObject: result, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "currentUser")

// 从 Userdefault 获取数据

let result = UserDefaults.standard.data(forKey: "currentUser")
    if result != nil
    let dict = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(result!) as? NSDictionary ?? [:]
    print("Current User Details : - \(dict)")

【讨论】:

【参考方案2】:

感谢Himanshu Patel 的提示,它对我有用。这是更新的代码:

open func object(forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil) -> NSCoding? 
    guard let keychainData = data(forKey: key, withAccessibility: accessibility) else 
        return nil
    

    let result = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(keychainData) as? NSCoding

    return result

【讨论】:

欢迎兄弟,请点赞我的回答。 Himanshu Patel 我无法支持您的评论。请写一个简短的答案,我很乐意投票。 这是我的回答***.com/a/59170370/6920041 是的,但您不是由我发布的 :) 我只能对我的问题的答案进行投票。 :)

以上是关于Redis 面试宝典之 Redis 如何处理已经过期的数据?的主要内容,如果未能解决你的问题,请参考以下文章

6. Redis在内存用完时会怎么办?以及Redis如何处理已过期的数据?

如何处理已弃用的函数'unarchiveObject(with:)'? [关闭]

如何处理已发布的持久卷?

Redis基础知识之————如何处理客户端连接

Java面试宝典,java输出double保留两位小数

大厂面试题详解:如何用Redis实现分布式锁?