Redis基础
Redis基础
Redis介绍
Redis是一个开源(BSD许可)的使用ANSI C语言编写的,支持网络,可以基于内存亦可持久化的日志型,key-value数据库(也叫NoSql数据库),并提供多种语言的API。
基本数据结构:
字符串(strings)
散列(hashes)
列表(lists)
集合(sets)
有序集合(sorted sets)
特点:
性能极高:能读的速度是110000次/s,写的速度是81000次/s。
丰富的数据类型:支持二进制的Strings, Lists, Hashes, Sets及Sorted Sets数据类型操作。
原子性:所有的操作都原子性的,单个操作支持事务,多个操作也支持事务。
丰富的特性:支持publish/subscribe, 通知, key过期等特性。
使用场景
内容缓存:由于Redis访问速度比较快,将热点数据放到Redis里,提升查询速度。
消息队列:Redis有list push和list pop这样的命令,所以很方便的执行队列操作。但是需要注意持久化,同时因为还没有ack, 可能存在丢消息的情况。
分布式锁:基于Redis的原子性,可以用来做分布式锁(就是在string中放一个key,成功了再执行具体操作,完了后释放key;具体可以参照幂等性中的范例)
原子计数:原子性意思是我们对一个数+1其实是分三步的(就是先读出数,然后给数+1,然后再写回去),【原子会保证着3步所有操作要么不间断地全部被执行,要么一个也没有执行】,这样可以避免多线程下对数据的错误操作。redis中incr、incrby、decr、decrby属于string数据结构,它们是原子性递增或递减操作【比如扣减库存等】。
常用操作方法
通用操作方法
命令 | 操作含义 |
---|---|
keys pattern | 返回匹配模式的所有 |
keys keys * | 查看该数据库中所有的key |
type key | 查看key类型 |
ttl key | 返回key的剩余过期时间,-1表示key不存在或者没有设置过过期时间 |
exists key | 测试key是否存在 |
del key | 删除key |
randomkey | 返回当前数据库随机选择的一个key,如数据库是空的,则返回空串 |
persist key | 取消掉key的过期时间 |
exprie key seconds | 为key设置过期时间,单位s。返回1成功,0表示key已设置过过期时间或者不存在 |
操作String
字符串类型是Redis中最基本的数据存储类型,它是一个由字节组成的序列,在Redis中是二进制安全的。这意味着该类型可以接受任何格式数据,如JPEG图像数据和Json对象说明信息。它是标准的key-value,通常用于存储字符串、整数和浮点。Value可容纳高达512MB的数据。
应用场景:分布式锁、session共享、全局序列号、计算站点访问量、当前在线人数等、计数器(incr命令);或者是常见的缓存(一般存储json数据)。
命令 | 操作含义 |
---|---|
set key value | 设置 key 对应的值为 string 类型的 value,返回 1 表示成功,0 失败 |
setnx key value | 同上,如果 key 已经存在,返回 0 。nx 是 not exist 的意思 |
get key | 获取 key 对应的 string 值,如果 key 不存在返回 nil |
getset key value | 原子的设置 key 的值,并返回 key 的旧值。如果 key 不存在返回 nil |
mset key1 value1 ... keyN valueN | 一次设置多个 key 的值,成功返回 1 表示所有的值都设置了,失败 返回 0 表示没有任何值被设置 |
mget key1 key2 ... keyN | 一次获取多个 key 的值,如果对应 key 不存在,则对应返回 ni |
incr key | 对 key 的值做加加操作,并返回新的值。注意 incr不是 int 的 value 会返回错误,incr 一 个不存在的 key,则设置 key 为 1 |
decr key | 同上,但是做的是减减操作,decr 一个不存在 key,则设置 key 为-1 |
incrby key integer | 同 incr,加指定值,key不存在时候会设置 key,并认为原来的value是 0 |
decrby key integer | 同 decr,减指定值。decrby 完全是为了可读性,我们完全可以通过 incrby 一个负 值来实现同样效果,反之一样。 |
操作list
list类型实质是一个每个元素都是string类型的双向链表,所以push和pop命令的算法时间复杂度都是O(1),另外list还会记录链表的长度,所以llen操作也是O(1)。链表的最大长度是(2的32次方-1)。我们可以通过push,pop操作从链表的头部或者尾部添加删除元素。这使得list既可以用作栈,也可以用作队列。
应用场景:栈、队列、消息队列
命令 | 操作含义 |
---|---|
lset key index value | 设置 list 中指定下标的元素值,成功返回 1,key 或者下标不存在返回错误 |
lpush key string | 在 key 对应 list 的头部添加字符串元素,返回 1 表示成功,0 表示 key 存在且不是 list类型 |
rpush key string | 同上,在尾部添加 |
lpop key | 从 list 的头部删除元素,并返回删除元素。如果 key 对应 list 不存在或者是空返回 nil,如果 key 对应值不是 list 返回错误 |
rpop key | 同上,从尾部删除 |
llen key | 返回 key 对应 list 的长度,key 不存在返回 0,如果 key 对应类型不是 list 返回错误 |
操作set
redis 的 set 是 string 类型的无序集合。 set 元素最大可以包含(2 的 32 次方-1)个元素。 set 的是通 过 hash table 实现的,所以添加,删除,查找的复杂度都是 O(1)。 hash table 会随着添加或者删除自 动的调整大小。需要注意的是调整 hash table 大小时候需要同步(获取写锁)会阻塞其他读写操作。
set类型唯一的特点使得其适合用于存储好友/关注/粉丝/感兴趣的人集合(去重),集合中的元素数量可能很多,每次全部取出来成本不小,set类型提供了一些很实用的命令用于直接操作这些集合
应用场景:集合去重、集合计算
命令 | 操作含义 |
---|---|
sinter | 获得A和B两个用户的共同好友 |
sismember | 判断A是否是B的好友 |
scard | 获取好友数量 |
smove | 将B从A的粉丝集合转移到A的好友集合 |
操作zset
和 set 一样, sorted set 也是 string 类型元素的集合,不同的是每个元素都会关联一个 double 类型 的 score ,元素顺序有score决定。 所以sorted set可以根据score进行排序,特别适合榜单等应用。
应用场景:排行榜、延时队列
命令 | 操作含义 |
---|---|
zadd key score member | 添加元素到集合,元素在集合中存在则更新对应 score,当该member已存在时,返回0,并更新该member的score值 |
zrem key member | 删除指定元素, 1 表示成功,如果元素不存在返回 0 |
zincrby key n member | 增加对应 member 的 score 值,然后移动元素并保持 skip list 保持有序。返回更新后的 score 值 |
zrank key member | 返回指定元素在集合中的排名(下标) ,集合中元素是按 score 从小到大排序的 |
zrevrank key member | 同上,但是集合中元素是按 score 从大到小排序 |
zrange key start end | 类似 lrange 操作从集合中去指定区间的元素。返回的是有序结果 |
zrevrange key start end | 同上,返回结果是按 score 逆序的 |
zrangebyscore key min max | 返回集合中 score 在给定区间的元素 |
zcount key min max | 返回集合中 score 在给定区间的数量 |
操作hash
redis hash 是一个 string 类型的 field 和 value 的映射表。它的添加,删除操作都是 O(1) (平均).hash特别适合用于存储对象。相较于将对象的每个字段存成单个 string 类型。将一个对象存储在 hash 类型中会占用更少的内存,并且可以更方便的存取整个对象。省内存的原因是新建一个 hash 对象时开始是用 zipmap(又称为 small hash)来存储的。这个 zipmap 其实并不是 hash table,但是 zipmap 相比正常的 hash 实现可以节省不少 hash 本身需要的一些元数据存储开销。尽管 zipmap 的添加,删除,查找都是 O(n),但是由于一般对象的 field 数量都不太多。所以使用 zipmap 也是很快的,也就是说添加删除平均还是 O(1)。如果 field 或者 value 的大小超出一定限制后, redis 会在内部自动将 zipmap替换成正常的 hash 实现.
Redis哈希对象常常用来缓存一些对象信息,如用户信息、商品信息、配置信息等,就是一般缓存key-value的结构,例如根据用户的手机号返回用户的相关信息。
应用场景:对象缓存、购物车
命令 | 操作含义 |
---|---|
hset key field value | 设置 hash field 为指定值,如果 key 不存在,则先创建 |
hget key field | 获取指定的 hash field |
hmset key filed1 value1 ... filedN valueN | 同时设置 hash 的多个 field |
hmget key filed1....fieldN | 获取全部指定的 hash filed |
hincrby key field integer | 将指定的 hash filed 加上给定值 |
hexists key field | 测试指定 field 是否存在 |