Bitmap:Redis 中的位图并不是一种新的数据类型,它的底层数据类型是字符串。字符串的本质是二进制大对象(BLOB:Binary Large Object),所以可以视作位图。
Expire:可以通过设置键的过期时间,让 Redis 自动地删除键。
Sort:可以对列表以某种非权重顺序对有序集合的元素进行排序。
Bitmap(位图)
位图:也称为位数组或位向量,是在 String 类型上定义的一组面向位(bit)的操作,是由比特位(bit)组成的数组。Redis 中的位图并不是一种新的数据类型。
Redis 中的字符串本质是二进制大对象 BLOB(Binary Large Object),是二进制安全的,最大长度为 512 MB,因此可以设置 2 的 32 次方个不同的位,所以可以将期视作位图。
因为位图存储的是布尔信息
,在存储数据时通常可以节省大量的内存空间,这是其最大的优势之一。位的操作有两种,一定时间内的单个位操作,如将位设置为 1 或 0,或获取位的值;以及对某一组位进行操作,如计算给定位范围内的设位数(例:人口统计)
- 常用命令
- setbit:设置位图指定偏移处比特位的值。
- getbit:从位图中获取位于指定偏移处比特位的值。
- bitcount:获取位图中设置为 1 的比特数。
- bitop:用于进行位操作,该命令支持四种位操作:
and, or, xor 和 not
,位运算的结果会被存储在一个目标键中。
- 位图在节省存储空间方面具有优势,特别是统计大量数据时体现特别明显。
setbit
设置位图指定偏移处比特位的值
语法:setbit key offset value
示例:记录水果被那些用户买过
# 买过 apple 的用户
127.0.0.1:6379> setbit "fruit:apple" 10001 1
(integer) 0
127.0.0.1:6379> setbit "fruit:apple" 10002 1
(integer) 0
127.0.0.1:6379> setbit "fruit:apple" 10003 1
(integer) 0
127.0.0.1:6379> setbit "fruit:apple" 10004 1
(integer) 0
# 买过 banana 的用户
127.0.0.1:6379> setbit "fruit:banana" 10003 1
(integer) 0
127.0.0.1:6379> setbit "fruit:banana" 10004 1
(integer) 0
127.0.0.1:6379> setbit "fruit:banana" 10005 1
(integer) 0
127.0.0.1:6379> setbit "fruit:banana" 10006 1
(integer) 0
127.0.0.1:6379> setbit "fruit:banana" 10007 1
(integer) 0
getbit
从位图中获取位于指定偏移处比特位的值
语法:getbit key offset
示例:
# 该用户是否买过 apple
127.0.0.1:6379> getbit "fruit:apple" 10003
(integer) 1
127.0.0.1:6379> getbit "fruit:apple" 10005
(integer) 0
127.0.0.1:6379> getbit "fruit:banana" 10003
(integer) 1
# 该用户是否买过 banana
127.0.0.1:6379> getbit "fruit:banana" 10006
(integer) 1
127.0.0.1:6379> getbit "fruit:banana" 10007
(integer) 1
127.0.0.1:6379> getbit "fruit:banana" 10008
(integer) 0
bitop
用于进行位操作,该命令支持四种位操作:and, or, xor 和 not
,位运算的结果会被存储在一个目标键中
语法:bitop operation destkey key [key ...]
示例:
# 位操作, 合并都购买过两种水果的用户
127.0.0.1:6379> bitop and "fruit_all" "fruit:apple" "fruit:banana"
(integer) 1251
# 统计都购买过两种水的用户
127.0.0.1:6379> bitcount "fruit_all"
(integer) 2
bitcount
获取位图中设置为 1 的比特数
语法:bitcount key [start end]
示例:
# 统计都购买过两种水的用户
127.0.0.1:6379> bitcount "fruit_all"
(integer) 2
# 统计分别购买两种水果的用户
127.0.0.1:6379> bitcount "fruit:apple"
(integer) 4
127.0.0.1:6379> bitcount "fruit:banana"
(integer) 5
Expire(过期)
Redis 中删除键可以使用DEL
或UNLINK
命令来主动删除,还可以通过设置键的过期时间让 Redis 自动删除键。
- 常用命令
- EXPIRE:设置过期时间,单位秒。
- TTL:查看剩余时间。
- EXISTS:判断键是否存在。
- 键的过期时间会被存储为一个绝对的
UNIX
时间戳,即使服务器宕机一段时间,时间戳也会被持久化到RDB
文件中。当 Redis 再次启动时会,这个用于判断键是否过期的时间戳并不会发生变化,一旦当前时间超过了这个时间戳时,键就过期了。
当客户端访问已过期键时,Redis 会立即从内存中删除该键。对于那些已经过期且永久不会再被访问的键,Redis 会定期地运行一个基于概率的算法来进行主动删除。更具体地说,Redis 会随机选择设置了过期时间的 20 个键。在这 20 个被选中的键中,已过期的键会被立即删除;如果选中的键中有超过 25% 的键已经过期且被删除,那么 Redis 会再次随机选择 20 个键并重复这个过程。默认情况下,上述过程每秒运行10次(可通过配置文件中 hz 的值进行设置)。 - 清除键的过期时间
- 使用
PERSIST
命令使期成为持久键。 - 被另一个没有过期时间的键重命名。如果键存在但未设置过期时间,则
TTL
命令返回-1
,如果键不存在,则返回-2
。 - 键的值被替换或删除。包括
SET, GETSET
和*STORE
在内的命令会清除过期时间。修改列表、集合或哈希的元素则不会清除过期时间,因为修改元素的操作不会替换键所关联的对象。
- 使用
EXPIREAT
命令与EXPIRE
命令相似,但它可以指定一个绝对UNIX
时间戳为参数做为指定键的过期时间。- 可以使用
PEXIRE
和PEXIREAT
命令以毫秒级的精度指定键的过期时间。 - Redis 对已过期的键的主动删除除不过预测,可能存在已过期的键永远不会被删除的情况。当发现太多已过期的键未被删除时,可以通过执行
SCAN
命令来更加主动地触发被动过期。
EXPIRE
设置过期时间,单位秒
语法:expire key seconds
示例:
127.0.0.1:6379> lpush session_list userid_10001 userid_10002 userid_10003
(integer) 3
127.0.0.1:6379> ttl session_list
(integer) -1
127.0.0.1:6379> exists session_list
(integer) 1
127.0.0.1:6379> expire session_list 20
(integer) 1
TTL
查看剩余时间
语法:ttl key
示例:
127.0.0.1:6379> ttl session_list
(integer) 17
127.0.0.1:6379> ttl session_list
(integer) 14
127.0.0.1:6379> exists session_list
(integer) 1
127.0.0.1:6379> exists session_list
(integer) 0
Sort(排序)
Redis 的有序集合是根据元素的权重进行排序,实际使用中有时需要获取一个 列表或集合的已排序副本,或者以某种非权重顺序对有序集合中的元素进行排序。Redis 为这些需求提供了一个方便的命令 SORT
。
- 常用命令
- SORT:直接使用可对元素都是数值排序,默认是升序(
ASC
)排序, 若要按降序排序可添加修改饰符DESC
。 - SORT...ALPHA:对非数值的元素且想按字典排序的,需增加修饰符
ALPHA
。 - SORT...LIMIT:默认情况下,SORT 排序默认返回所有元素,可使用
LIMIT
修饰符来限制返回元素的数量。 - SORT...GET:Get 选项可被多次使用, Get # 表示获取元素本身。
- SORT...STORE:把排序结果当做列表保存到指定的键中。
- SORT:直接使用可对元素都是数值排序,默认是升序(
数值排序
默认升级,降序添加修饰符DESC
127.0.0.1:6379> lpush fruit 200 365 104 455 333
(integer) 5
127.0.0.1:6379> sort fruit
1) "104"
2) "200"
3) "333"
4) "365"
5) "455"
127.0.0.1:6379> sort fruit desc
1) "455"
2) "365"
3) "333"
4) "200"
5) "104"
非数值排序
非数值元素需要按字典排序,添加修饰符ALPHA
。
127.0.0.1:6379> lpush restaurants "KFC" "Wendy's" "MacDoload" "Dunkin" "Subway"
(integer) 5
127.0.0.1:6379> sort restaurants alpha
1) "Dunkin"
2) "KFC"
3) "MacDoload"
4) "Subway"
5) "Wendy's"
127.0.0.1:6379> sort restaurants alpha desc
1) "Wendy's"
2) "Subway"
3) "MacDoload"
4) "KFC"
5) "Dunkin"
LIMIT限制返回元素
默认情况下,SORT 排序默认返回所有元素,可使用LIMIT
修饰符来限制返回元素的数量
127.0.0.1:6379> lrange fruit 0 -1
1) "333"
2) "455"
3) "104"
4) "365"
5) "200"
127.0.0.1:6379> sort fruit limit 0 3
1) "104"
2) "200"
3) "333"
127.0.0.1:6379> sort fruit limit 0 3 desc
1) "455"
2) "365"
3) "333"
按其它键的权重排序
Redis 还支持按在某些其他键中定义的权重来对元素进行排序
-- 用户喜爱的餐厅列表
127.0.0.1:6379> lpush "user:123:favorite_restaurant_ids" 200 365 104 455 333
(integer) 5
-- 餐厅的评分
127.0.0.1:6379> set "restaurant_rating_200" 4.3
127.0.0.1:6379> set "restaurant_rating_365" 4.0
127.0.0.1:6379> set "restaurant_rating_104" 4.8
127.0.0.1:6379> set "restaurant_rating_455" 4.7
127.0.0.1:6379> set "restaurant_rating_333" 4.6
-- 对用户喜爱的餐厅根据评分排序
127.0.0.1:6379> sort "user:123:favorite_restaurant_ids" by restaurant_rating_* desc
1) "104"
2) "455"
3) "333"
4) "200"
5) "365"
127.0.0.1:6379> sort "user:123:favorite_restaurant_ids" by restaurant_rating_*
1) "365"
2) "200"
3) "333"
4) "455"
5) "104"
-- 餐厅名称
127.0.0.1:6379> set "restaurant_name_200" "Ruby Tuesday"
127.0.0.1:6379> set "restaurant_name_365" "TGI Friday"
127.0.0.1:6379> set "restaurant_name_104" "Applebee's"
127.0.0.1:6379> set "restaurant_name_455" "Red Lobster"
127.0.0.1:6379> set "restaurant_name_333" "Boiling Crab"
-- 根据餐厅评分获取餐厅名称
127.0.0.1:6379> sort "user:123:favorite_restaurant_ids" by restaurant_rating_* desc get restaurant_name_*
1) "Applebee's"
2) "Red Lobster"
3) "Boiling Crab"
4) "Ruby Tuesday"
5) "TGI Friday"
STORE保存到新的键
把排序结果当做列表保存到指定的键中
127.0.0.1:6379> sort "user:123:favorite_restaurant_ids" by restaurant_rating_* desc get restaurant_name_* store sort_by_rating
(integer) 5
127.0.0.1:6379> lrange sort_by_rating 0 -1
1) "Applebee's"
2) "Red Lobster"
3) "Boiling Crab"
4) "Ruby Tuesday"
5) "TGI Friday"
注意:本文归作者所有,未经作者允许,不得转载