键空间
在 Redis 中管理键:键过期、扫描、修改和查询键空间
Redis 键是二进制安全的;这意味着您可以使用任何二进制序列作为键,从像 "foo" 这样的字符串到 JPEG 文件的内容。空字符串也是有效的键。
关于键的一些其他规则
- 非常长的键不是个好主意。例如,一个 1024 字节的键不仅在内存方面是个坏主意,而且因为在数据集中查找键可能需要多次代价高昂的键比较。即使手头的任务是匹配大值的存在,对其进行哈希(例如使用 SHA1)也是一个更好的主意,特别是从内存和带宽的角度来看。
- 非常短的键通常不是个好主意。如果您可以写成 "user:1000:followers",就没有必要写成 "u1000flw" 作为键。后者更具可读性,并且增加的空间与键对象本身和值对象使用的空间相比微不足道。虽然短键显然会消耗更少的内存,但您的工作是找到正确的平衡点。
- 尽量坚持一种命名模式。例如,"对象类型:id" 是个好主意,比如 "user:1000"。点或破折号常用于多词字段,例如 "comment:4321:reply.to" 或 "comment:4321:reply-to"。
- 允许的最大键大小为 512 MB。
修改和查询键空间
有些命令不是针对特定类型定义的,但对于与键空间交互很有用,因此可以与任何类型的键一起使用。
例如,EXISTS
命令返回 1 或 0 来指示数据库中是否存在给定的键,而 DEL
命令删除键及其关联的值,无论值是什么。
> set mykey hello
OK
> exists mykey
(integer) 1
> del mykey
(integer) 1
> exists mykey
(integer) 0
从示例中您还可以看到,DEL
本身会根据键是否被移除(它存在)或未被移除(没有那个名称的键)返回 1 或 0。
有许多与键空间相关的命令,但上面两个与 TYPE
命令一样是基本命令,TYPE
命令返回指定键存储的值类型。
> set mykey x
OK
> type mykey
string
> del mykey
(integer) 1
> type mykey
none
键过期
在继续之前,我们应该看看 Redis 的一个重要特性,它与您存储的值类型无关:键过期。键过期允许您为键设置超时时间,也称为“生存时间”或“TTL”。当生存时间到期时,键会自动销毁。
关于键过期的一些重要注意事项
- 它们可以使用秒或毫秒精度进行设置。
- 然而,过期时间的精度始终是 1 毫秒。
- 过期信息会被复制并持久化到磁盘上,当您的 Redis 服务器停止运行时,时间实际上仍然会过去(这意味着 Redis 保存了键将要过期的日期)。
使用 EXPIRE
命令设置键的过期时间
> set key some-value
OK
> expire key 5
(integer) 1
> get key (immediately)
"some-value"
> get key (after some time)
(nil)
在两次 GET
调用之间键消失了,因为第二次调用延迟了 5 秒以上。在上面的示例中,我们使用了 EXPIRE
来设置过期时间(它也可以用于为已经设置了过期时间的键设置新的过期时间,就像 PERSIST
可以用来移除过期时间并使键永久存在)。然而,我们也可以使用其他 Redis 命令创建带有过期时间的键。例如,使用 SET
的选项:
> set key 100 ex 10
OK
> ttl key
(integer) 9
上面的示例设置了一个键,其字符串值为 100
,过期时间为十秒。稍后调用 TTL
命令来检查该键的剩余生存时间。
要以毫秒为单位设置和检查过期时间,请查看 PEXPIRE
和 PTTL
命令,以及完整的 SET
选项列表。
遍历键空间
Scan
为了以高效的方式在 Redis 数据库中增量迭代键,您可以使用 SCAN
命令。
由于 SCAN
允许增量迭代,每次调用只返回少量元素,因此可以在生产环境中使用,而不会像 KEYS
或 SMEMBERS
命令那样,在处理大量键或元素时长时间阻塞服务器(甚至几秒钟)。
然而,虽然像 SMEMBERS
这样的阻塞命令能够在特定时刻提供集合中的所有元素。SCAN
系列命令对于返回的元素只能提供有限的保证,因为我们增量迭代的集合在迭代过程中可能会发生变化。
Keys
另一种遍历键空间的方法是使用 KEYS
命令,但这种方法应谨慎使用,因为 KEYS
会阻塞 Redis 服务器直到返回所有键。
警告:请将 KEYS
视为只能在生产环境中极其谨慎使用的命令。
当针对大型数据库执行时,KEYS
可能会严重影响性能。此命令仅用于调试和特殊操作,例如更改键空间布局。请勿在您的常规应用程序代码中使用 KEYS
。如果您正在寻找在键空间子集中查找键的方法,请考虑使用 SCAN
或 sets。
支持的 glob 风格模式
h?llo
匹配hello
、hallo
和hxllo
h*llo
匹配hllo
和heeeello
h[ae]llo
匹配hello
和hallo
,但不匹配hillo
h[^e]llo
匹配hallo
、hbllo
等,但不匹配hello
h[a-b]llo
匹配hallo
和hbllo
如果您想字面匹配特殊字符,请使用 \
进行转义。