键基础

Redis 键基础操作

Key | 键基础

Redis 的 key 是二进制安全的,也就是说你可以使用任何二进制的序列作为 key,从一个”foo”字符串到一个 JPEG 文件的内容都可以;空字符串也同样是一个有效的 key。

  • 使用非常长的 key 并不是好的主意,例如使用一个 1024 字节(bytes)长度的 key 就很烂,其不仅仅耗费内存,而且在数据集中查找这个 key 时也需要很高的比较成本。即使当前处理的任务是匹配存在的大值,采用哈希来处理(例如使用 SHA1) 会是一个更好的主意,特别是从内存和带宽的角度来看。

  • 使用很短的 key 通常也不是一个好主意。将”u1000flw”作为一个 key 几乎是毫无意义的,如果你可以将其替换成”user:1000:followers”,则它会更具可读性,而由此增加的空间与 key 对象和值对象使用的空间比起来微乎其微。当简短的 key 将明显的消耗一小部分内存,你的工作就是寻找到一个正确的平衡点。

  • 尝试去坚持一个模式。例如使用”object-type:id”做为 key 就是一个好的想法,像”user:1000″。点或者虚线经常被用作多单词字段的连接符,例如”comment:1234-reply.to”或”comment-1234:reply-to”。

  • key 最大可分配 512MB。

Key 查询

遍历

有一些命令并未定义特定类型,但是在与 key 进行交互时是很有用的,因为它们没有定义特定的类型,所以它们可以用于任何类型的 key。例如,EXISTS 命令返回 1 或者 0 来表示一个给定的 key 在数据库中是否存在,DEL 命令将删除一个 key 以及其关联的任何值。

> set mykey hello
OK
> exists mykey
(integer) 1
> del mykey
(integer) 1
> exists mykey
(integer) 0
> keys *
//查询所有的key值

从这个例子中可以看到,DEL 命令返回 1 或者 0 取决于要删除的这个 key 是被删除了(当它存在时)还是没有(不存在给定名字的 key)。有很多与 key 相关的命令,但是上面介绍的这两个是与 TYPE 命令结合使用的基本部分,TYPE 将返回指定 key 所存储的值的类型。

> set mykey x
OK
> type mykey
string
> del mykey
(integer) 1
> type mykey
none

Iteration

Keys are returned in incremental iterations with constant time guarantee for each iteration. A cursor (an integer is this case) is returned when the iterations is initialized and an updated cursor is returned and every iteration. An iteration cycle begins when the cursor is set to 0 in the SCAN request, and terminates when the cursor returned by the server is 0. Due to nuances of Redis architecture and the cursor algorithm implementation here are some peculiarities of this approach:

  • A full iteration always retrieves all the elements that were present in the collection from the start to the end of a full iteration.

  • A full iteration never returns any element that was NOT present in the collection from the start to the end of a full iteration.

  • A given element may be returned multiple times. It is up to the application to handle the case of duplicated elements

  • Elements that were not constantly present in the collection during a full iteration, may be returned or not: it is undefined.

  • A number of elements returned during each count varies and can be 0 too. However, the iteration is not complete until the server returns the cursor value of 0.

  • The COUNT option can be used to limit the number of elements returned in each iteration. The default value is 10. However, it is considered only a suggestion and not enforced in all cases. COUNT value can be changed during each iteration call.

  • The MATCH option allows specifying of patterns like the KEYS command allows.

  • The cursor implementation is completely stateless on the server side. That allows (potentially) infinite iterations to start in parallel. Also, there are no requirements of ensuring that an iteration continues up to the end and can be stopped anytime.

Key 操作

删除 Key

DEL 命令 在删除单个集合类型的 Key 时,命令的时间复杂度是 O(M),其中 M 是集合类型 Key 包含的元素个数。

DEL key Time complexity: O(N) where N is the number of keys that will be removed. When a key to remove holds a value other than a string, the individual complexity for this key is O(M) where M is the number of elements in the list, set, sorted set or hash. Removing a single key that holds a string value is O(1).

Key Expire

Key 的存活时间

在继续介绍复杂的数据结构之前,我们需要讨论另外一个与值类型无关的特性,它叫做 Redis 的过期。基本上,你可以为一个 key 设置一个过期时间,也就是 key 的存活的期限。当达到存活的时间,这个 key 将会自动销毁,它跟用户在一个 key 上调用 DEL 命令是完全一样的。

几个关于 Redis 过期的快捷信息:

  • 它们可以被设置为秒或者毫秒。

  • 过期时间的精确度始终为 1 毫秒。

  • 过期的信息会复制和保存在硬盘上,当你的 Redis 服务停止后,时间也是在走的(意思是 Redis 保存的是 key 的过期日期)。

过期的设置很简单:

> set key some-value
OK
> expire key 5
(integer) 1
> get key (immediately)
"some-value"
> get key (after some time)
(nil)

这个 key 在两个GET调用中间消失了,由于第二个调用延迟了 5 秒以上。在这个例子中使用EXPIRE 来进行过期设置(它同样可以用来为一个已经设置过期的 key 设置一个不同的过期时间,就像 PERSIST 可以用来移除一个过期而使这个 key 永久的保存)。然而, 我们同样可以使用其他的 Redis 命令来创建带过期的 key。例如使用 SET 的选项:

> set key 100 ex 10
OK
> ttl key
(integer) 9

以上的例子,是将一个 key 设置为一个字符串的值 100,并且过期时间设置为 10 秒。接下来的 TTL 命令是检查这个 key 剩余的存活时间。如果需要采用毫秒来设置和检查过期时间,请查看 PEXPIRE 和 PTTL 命令,以及 SET 选项的完整列表。

不过,要注意一点,随着 Redis 中数据量的增加,因为处理过期的 Key 的时间复杂度是 O(N)。

LRU 缓存