Redis键(key)

命令 描述
keys * 查看当前库所有key
exists <key> 判断某个key是否存在
type <key> 查看key是什么类型
del <key> 删除指定的key数据
expore <key> <time> 为给定的key设置过期时间time(单位秒)
ttl <key> 查看还有多少秒过期,-1表示永不过期,-2表示已过期
select <index> 切换当前数据库(共16个数据库,0为默认库)
dbsize 查看当前数据库key的数量
flushdb/flushall 清空当前库/全部库

Redis字符串(String)

String类型是二进制安全的,意味着Redis的String可包含任何数据,比如jpg图片或者序列化的对象。

一个Redis中字符串value最多可以是512M。

命令 描述
set <key> <value> 添加键值对
get <key> 查询对应键值
append <key> <value> 将给定的value追加到原值的末尾
strlen <key> 获得key的长度
setnx <key> <value> 只有在key不存在时,才能设置key的值
incr/decr <key> 将key中储存的数字值增/减(+/-) 1
incrby/decrby <key> <步长> 将key中储存的数字值增/减,自定义步长
mset <key1><value1><key2><value2>… 同时设置一个或多个key-value对
mget <key1><key2>… 同时获取一个或多个value
msetnx <key1><value1><key2><value2>… 同时设置一个或多个key-value对,当且仅当所有给定key都不存在
getrange <key> <起始位置><结束位置> 获得值的范围(全部:get key 0 -1)
setrange <key><起始位置><value> 用value覆写key所储存的字符串值,从起始位置开始(索引从0开始)
setnx <key> <过期时间><value> 设置键值的同时,设置过期时间(单位秒)
getset<key><value> 设置新值同时获得旧值

Redis列表(List)

单键多值,双向链表

命令 描述
lpush/rpush <key> <value1> <value2>… 从左边/右边插入一个或多个值
lpop/rpop <key> 从左边/右边吐出一个值。
rpoplpush <key1> <key2> 从key1列表右边吐出一个值,查到key2列表右边
lrange <key> <start> <stop> 按照索引下标获得元素(从左到右)<br>(全部:lrange key 0 -1)
lindex <key> <index> 按照索引下标获得元素(从左到右)
llen <key> 获得列表的长度
linsert <key> before/after <value> <newvalue> 在value的前/后面插入newvalue值
lrem <key> <n> <value> 从左边删除n个value(从左到右)
lset <key> <index> <value> 将列表key下标为index的值替换成value

Redis集合(Set)

Redis的集合Set是String类型的无序集合,与list类似是一个列表的功能,但Set可以自动数据排重。底层是一个value为null的hash表,所以添加、删除、查找的复杂度都为O(1)

命令 描述
sadd <key> <member1> <member2>… 将一个或多个member元素加入到集合key中,已存在的member将被忽略
smembers <key> 取出该集合的所有值
sismember <key> <member> 判断集合key是否含有该member值,有则1,无则0
scard <key> 返回该集合的元素个数
srem <key> <member1> <member2>… 删除集合中的某个元素
spop <key> 随机从该集合中吐出一个值
srandmember <key> <n> 随机从该集合中取出n个值。值不会从集合中删除
smove <source> <destination> <member> 把集合中的一个member值从一个集合移动到另一个集合中
sinter/sunion <key1> <key2> 返回两个集合的交集/并集元素
sdiff <key1> <key2> 返回两个集合的差集元素(key1中的,不包含key2中的)

Redis哈希(Hash)

Redis的Hash是一个String类型的field和value的映射表,hash适合用于存储对象,类似Java中的Map<String, Object>

当key存储的value过多时,往往为了提高查询效率,例如用户ID为key,field有姓名、年龄、职业等信息,这是我们可以选择通过key(用户ID)+field(属性标签)就可以操作对应属性的数据。

类似于map套娃:<String, <Map<key, value>>>

好处:既不需要重复存储数据,避免了数据冗余,也不会带来序列化和并发修改控制的问题。

命令 描述
hset <key> <field> <value> 给key集合中的field键赋值value,例:hset user:001 name zeker
hget <key> <field> 从key集合中的fild中取出value
hmset <key> <field1> <value1> <field2> <value2>… 批量设置hash的值
hexists <key> <field> 查看哈希表key中,给定field是否存在
hkeys <key> 列出该hash集合的所有field
hvals <key> 列出该hash集合的所有value
hincrby <key> <field> <increment> 为哈希表key中的field的值加上增量increment(例:1 -1)
hsetnx <key> <field> <value> 将哈希表key中的field的值设置为value,当且仅当field不存在

Redis有序集合(Zset)

Redis有序集合Zset与普通集合Set相似,都是一个没有重复元素的字符串集合。

不同之处在于有序集合Zset的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。

集合中的成员是唯一的,但评分可以是重复的。这里例子可以为:排行榜

命令 描述
zadd <key> <score1> <member1> <score2> <member2>… 将一个或多个memeber元素及其score值加入到有序集key中
zrange <key> <start> <stop> [withscores] 返回有序集key中,下标在start与stop之间的元素(withscores可让分数与值返回到结果集
zrangebyscore key min max [withscoers] [limit offset count] 返回有序集key中,所有score值介于min和max之间(包括等于min或max)的成员,有序集成员按score值递增(从小到大)次序排列
zrevrangebyscore key max min [withscoers] [limit offset count] dev:反转。意思同上,次序从大到小排列
zincrby <key> <increment> <member> 为元素member的score加上增量increment
zrem <key> <member> 删除该集合下指定值的元素
zcount <key> <min> <max> 统计该集合中分数区间内的元素个数
zrank <key> <member> 返回该元素member在集合中的排名,从0开始

Zset底层中使用了两种数据结构:hash表与跳跃表

  1. hash表,作用就是关联元素value和权重score,保障元素value的唯一值,可以通过元素value找到相应的score值。
  2. 跳跃表,目的在于给元素value排序,根据score的范围获取元素列表,从而比普通列表查询效率更快。

Redis新数据类型

Bitmaps

Redis提供Bitmaps这个”数据类型“可以实现对位的操作:

(1)Bitmaps本身不是一种数据结构,实际上就是字符串,但是它可以对字符串的位进行操作。、

(2)Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。可以Bitmaps想象成一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在Bitmaps中叫做偏移量。单个Bitmaps的最大长度是512MB,即2^32个比特位。

合理地使用操作位能够有效地提高内存使用率和开发效率,并且可以极大地节省内存空间。
例如:用户访问,统计不同电话号码的个数以及布隆过滤法(URL的排重、垃圾邮箱地址的过滤)…

命令 描述
setbit <key> <offset> <value> 设置Bitmaps中某个偏移量offset的值value
getbit <key> <offset> 获取Bitmaps中某个偏移量offset的值value
bitcount <key> [start end] 统计字符串从start字节到end字节比特值为1的数量
bitop and(or/not/xor) <destkey> [key…] 多个Bitmaps的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在destkey中

HyperLogLog

在工作当中,经常会遇到与统计相关的功能需求,比如统计网站PV(PageView页面访问量),可以使用Redis的incr、incrby轻松实现。
但像UV(UniqueVisitor,独立访客)、独立IP数、搜索记录数等需要去重和计数的问题如何解决?而这种求集合中不重复元素个数的问题称为基数问题。

解决基数问题方案:

(1)数据存储在MySQL表中,使用distinct count计算不重复个数

(2)使用Redis提供的hash、set、bitmaps等数据结构来处理

以上的方案结果精确,但随着数据不断增加,导致占用空间越来越大,对于非常大的数据集是不切实际的。

为了能够降低一定的精度来平衡存储空间,Redis推出了HyperLogLog,一种用来做基数统计的算法。

其优点在于:

在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。

每个HyperLogLog键只需要花费 12 KB内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

基数 = 数据集元素个数 - 重复数字个数

但是,因为HyperLogLog只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog不能像集合那样,返回输入的各个元素。

命令 描述
padd <key> <element> [element…] 添加指定元素element到HyperLogLog中
pfcount <key> [key…] 计算key中的基数
pfmerge <destkey> <sourcekey> [sourcekey…] 将一个或多个key合并后的结果储存在另一个destkey中

Geospatital

Redis GEO,Geographic,地理信息的缩写。

主要用于存储地理位置信息,即经纬度(二维坐标),基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等常见操作。

命令 描述
geoadd <key> <longitude> <latitude> <member> [longitude latitude member…] 添加地理位置(经度、维度、名称)(有效经度:-180度到180度;有效纬度:-85.05112878度到85.05112878度)
geopos <key> <member> [member…] 获得指定地区member的坐标
geodist <key> <member1> <member2> [m|km|ft|mi] 获取两个指定地区位置之间的直线距离(单位:米|千米|英尺|英里,默认单位米)
georadius <key> <longitude> <latitude> radius m|km|ft|mi 以给定的经纬度为中心找出某一半径radius内的元素

Redis事务命令

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务
  • 命令入队
  • 执行事务
命令 描述
multi 标记一个事务块的开始,开始对命令的组队阶段
exec 执行所有事务块内的命令,开始执行阶段
discard 取消事务,放弃执行事务块内的所有命令
watch <key> [key…] 监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令锁改动,那么事务将被打断
unwatch 取消watch命令对所有key的监视

组队阶段中某个命令出现了命令报错,执行阶段整个的所有队列都会被取消。

而当组队阶段无报错,执行阶段某一命令出现了命令报错,则只有报错的命令不会被执行,其他命令不受影响。

当出现事务冲突时,Redis往往呈现出乐观锁的形式进行处理,即在使用完数据修改版本号等机制,提高吞吐量,而Redis就是利用这种check-and-set机制实现事务。

事务三特性

特性 描述
单独的隔离操作 事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断
没有隔离级别的概念 队列中的命令没有提交之前都不会实际地被执行,因为事务提交前任何指令都不会被实际执行
不保证原子性 Redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚