string(字符串)
常用命令:
set,get,decr,incr,mget 等。
使用SETBIT、GETBIT 实现日活,月活的统计
Redis Setbit 命令用于对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
假如:
日活的 数据格式 是这样的 1101010(取七天的数据) 1为 签到 0为未签到。
只要统计 1的个数 即可知道 该用户这个月(或周,年)的签到次数。
如 1101010 可表示 该月1,2,4,6号该用户进行了签到, 其他时间未签到。
签到时,只修改特定位置的数据即可。
如 源数据 1101010 第七天为未签到 修改为 已签到时。
只需要 修改字符串的 第七个位置 设置为1 即可。
即:1101011
语法
redis Setbit 命令基本语法如下:
redis 127.0.0.1:6379> Setbit KEY_NAME OFFSET
可用版本
>= 2.2.0
返回值
指定偏移量原来储存的位。
实例
redis> SETBIT bit 10086 1
(integer) 0
redis> GETBIT bit 10086
(integer) 1
redis> GETBIT bit 100 # bit 默认被初始化为 0
(integer) 0
hash(哈希)
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
常用命令:
hget,hset,hgetall 等。
使用 hash 的特性 做 数据缓存(用户信息缓存)
# 添加测试数据
127.0.0.1:6379> HMSET user:1 name 'zhangsan' age '16' sex '1'
OK
127.0.0.1:6379> HMSET user:2 name 'lisi' age '18' sex '0'
OK
127.0.0.1:6379> HMSET user:3 name 'wangwu' age '20' sex '1'
OK
127.0.0.1:6379> HMSET user:4 name 'zhaoliu' age '22' sex '0'
OK
127.0.0.1:6379> HMSET user:5 name 'tianqi' age '23' sex '1'
OK
# 获取user:5 的所有信息
127.0.0.1:6379> HGETALL user:5
1) "name"
2) "tianqi"
3) "age"
4) "11"
5) "sex"
6) "0"
# 修改 user:5 的年龄
127.0.0.1:6379> HSET user:5 age "20"
(integer) 0
# 获取 user:5 的所有信息
127.0.0.1:6379> HGET user:5 age
"20"
127.0.0.1:6379>
list(列表)
常用命令:
lpush,rpush,lpop,rpop,lrange等。
应用场景:
Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现。
实现方式:
Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。
可以使用 redis + php 做邮件队列
例如:
在使用 通过邮箱找回密码的功能时,通常邮件不是即时发送的。
如果是即时发送,会造成用户体验不好(延迟),程序耦合等。
这时候 可以使用队列 ,先把要发送的邮箱 通过队列存储,再通过队列脚本来处理队列。这样异步操作会好很多。
set(集合)
Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
常用命令:
sadd,spop,smembers,sunion 等。
应用场景:
Redis set对外提供的功能与list类似是一个列表的功能,
特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,
并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
利用集合成员是唯一的特性 。可以用来做订票系统。
用集合来存储定已经被预定的票的编号。如果有多个用户预定了同一张票,只能有一个成功。
zset(sorted set:有序集合)
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
常用命令:
zadd,zrange,zrem,zcard等。
使用场景:
Redis sorted set的使用场景与set类似,区别是set不是自动有序的,
而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。
当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,
比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。
利用有序集合的特性 来做 排行榜
例如:现在有一个需求就是对 所有用户的钱包金额进行排序,取最富有的前十位用户。
那么redis的有序集合,就可以满足要求了。
像 日榜,周榜,月榜等等 都可以用这个做。
周榜 和 月榜 都可以通过 日榜推算。
榜单的即时性 不强,可以用mysql 在今天凌晨时 统计昨天的数据 再存入 redis的有序集合。
HyperLogLog(是用来做基数统计的算法)
Redis 在 2.8.9 版本添加了 HyperLogLog 结构。
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
常用命令:
PFADD key element [element ...]
添加指定元素到 HyperLogLog 中。
PFCOUNT key [key ...]
返回给定 HyperLogLog 的基数估算值。
PFMERGE destkey sourcekey [sourcekey ...]
将多个 HyperLogLog 合并为一个 HyperLogLog
什么是基数?
比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。
基数就是在误差可接受的范围内,快速计算基数。
实例
以下实例演示了 HyperLogLog 的工作过程:
redis 127.0.0.1:6379> PFADD runoobkey "redis"
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mongodb"
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mysql"
1) (integer) 1
redis 127.0.0.1:6379> PFCOUNT runoobkey
(integer) 3
取最新N个数据的操作
比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的5000条评论的ID放在Redis的List集合中,并将超出集合部分从数据库获取
使用LPUSH latest.comments<ID>命令,向list集合中插入数据
插入完成后再用LTRIM latest.comments 0 5000命令使其永远只保存最近5000个ID
然后我们在客户端获取某一页评论时可以用下面的逻辑(伪代码)
FUNCTION get_latest_comments(start,num_items):
id_list = redis.lrange("latest.comments",start,start+num_items-1)
IF id_list.length < num_items
id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")
END
RETURN id_list
END
如果你还有不同的筛选维度,比如某个分类的最新N条,那么你可以再建一个按此分类的List,只存ID的话,Redis是非常高效的
排行榜应用,取TOP N操作
这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sorted set出马了,将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。
需要精准设定过期时间的应用
比如你可以把上面说到的sorted set的score值设置成过期时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了,不仅是清除Redis中的过期数据,你完全可以把Redis里这个过期时间当成是对数据库中数据的索引,用Redis来找出哪些数据需要过期删除,然后再精准地从数据库中删除相应的记录。
计数器应用
Redis的命令都是原子性的,你可以轻松地利用INCR,DECR命令来构建计数器系统。
Uniq操作,获取某段时间所有数据排重值
这个使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重。
Pub/Sub构建实时消息系统
Redis的Pub/Sub系统可以构建实时的消息系统,比如很多用Pub/Sub构建的实时聊天系统的例子。
构建队列系统
使用list可以构建队列系统,使用sorted set甚至可以构建有优先级的队列系统。
网友评论