Redis简介
Redis的优势:
* 速度快,性能高,每秒可以执行约100,000个Set以及100,000个Get操作
* 丰富的数据结构
* 原子性,因为所有Redis操作都是原子性的,所以多个客户端会并发访问Redis服务器,获取相同的更新值
* 丰富的特性,Redis的使用非常灵活,有很多适应场景,比如缓存、消息队列(Redis支持发布/订阅)等
String
字符串可以支持三种类型:
1. 字符串(byte 或者 string)
2. 整数
3. 浮点数
命令 | 用例和描述 |
---|---|
INCR | INCR key-name —— 将键存储的值加1 |
DECR | DECR key-name —— 键存储的值减1 |
INCRBY | INCRBY key-name amount —— 键存储的值加上整数amount |
DECRBY | DECRBY key-name amount —— 键存储的值减整数amount |
INCRBYFLOAT | INCRBYFLAOT —— 将键存储的值加上浮点数amount |
看下一些操作:
Redis处理子串和二进制位的命令
命令 | 用例和描述 |
---|---|
APPEND | APPEND key-name value —— 将值value追加到key-name键存储值的末尾 |
GETRANGE | GETRANGE key-name start end —— 获取key-name键存储的值,子串从偏移量start至end,包括start跟end |
SETRANGE | SETRANGE key-name offset value —— 从offset开始的紫串设定值value |
GETBIT | GETBIT key-name offset —— 将字节串看作是二进制位串(bit string),并返回位串中偏移量为offset的二进制位的值 |
SETBIT | SETBIT key-name offset value —— 设置offset的二进制位的值 |
BITCOUNT | BITCOUNT key-name [start end] ——统计二进制位位数为1的数量,也可以指定范围(start,end) |
BITOP | BITOP operation dest-key key-name [key-name …] —— 对一个或者多个二进制位执行包括并(AND)、或(OR)、异或(XOR)、非(NOT)在内的任意一种按位运算 |
- 注:bit字串,不是0就是1。如果使用Spring-Data-Redis开发,它的setBit没有1或0的选项,只有True和False
相关操作:
列表
列表的操作可以在两端进行
Redis 中的列表相当于Java的LinkedList,它是一个链表而不是一个数组,所以它的插入删除非常快,时间复杂度为O(1),但索引定位很慢,时间复杂度为O(n)
命令 | 用例和描述 |
---|---|
RPUSH | RPUSH key-name value [value … ] —— 将一个或者多个值推入列表的右端 |
LPUSH | LPUSH key-name value [value …] —— 将一个或者多个值推入列表的左端 |
RPOP | RPOP key-name —— 移除并返回列表的最右端的元素 |
LPOP | LPOP key-name —— 移除并返回列表的最左端的元素 |
LINDEX | LINDE key-name —— 返回列表中偏移量为offset(可以理解为下标) 的元素 |
LRANGE | LRANGE key-name start end —— 返回列表从start 偏移量到end偏移量范围内的所有元素(包括start和end) |
LTRIM | LTRIM key-name start end —— 对列表进行修剪,只保留从start偏移量到end偏移量范围内的元素(包括start和end) |
- 注:lindex相当于Java的LinkedList的get(int index),它需要对链表进行遍历,性能随着index的增大而降低
Redis的列表List有Block(阻塞)的功能,下面是一些阻塞命令列表阻塞命令
命令 | 用例和描述 |
---|---|
BLPOP | BLPOP key-name [key-name … ] timeout —— 从第一个非空列表中弹出位于最左端的元素,或者在timeout秒内阻塞并等待可弹出元素出现 |
BRPOP | BRPOP key-name [key-name … ] timeout —— 从第一个非空列表中弹出位于最右端的元素,或者在timeout秒内阻塞并等待可弹出元素出现 |
RPOPLPUSH | BPOPLPUSH source-key dest-key —— 从source-key 列表中弹出位于最右端的元素并将这个元素插入到dest-key 列表的最左端,并向用户返回这个元素 |
BRPOPLPUSH | BRPOPLPUSH source-key dest-key timeout —— 从source-key 列表中弹出位于最右端的元素,然后将这个元素插入到dest-key列表的最左端,并向用户返回这个元素;如果source-key为空,那么在timeout秒内阻塞并等待元素出现 |
简单的深入探讨列表的内部实现:
如果列表的数据较少的情况下,redis会为它分配一个连续的内存空间供他存储,这个结构就是 ziplist ,即压缩链表
当数据量较多的时候,就会改成quicklist,即快速链表,它是链表+ziplist组合而成,减少了一些指针
集合
插入命令、移除命令、将元素从一个集合移动到另一个集合的命令
Redis的集合相当于Java的HashSet,它内部的键值对是无序且唯一的
命令 | 用例和描述 | |
---|---|---|
SADD | SADD key-name item [itme….] ——将一个或者多个元素添加到集合里面,并返回当前操作被添加元素的数量 | |
SREM | SREM key-name item [item…] —— 从集合里面移除一个或者多个元素,并返回被移除元素的数量 | |
SISMEMBER | SISMEMBER key-name item —— 检查元素item是否在集合key-name里面 | |
SCARD | SCARD key-name —— 返回集合包含的元素的数量 | |
SMEMBERS | SMEMBERS key-name | 返回集合的所有元素 |
SRANDMEMBER | SRANDMEMBER key-name [count] —— 从集合里面随机返回一个或者多个元素。当count为正数时,命令返回的随机元素不会重复;当count为负数时,命令返回的随机元素可能会重复 | |
SPOP | SPOP key-name —— 随机移除集合中的一个元素,并返回被移除的元素 | |
SMOVE | SMOVE source-key dest-key item —— 如果集合source-key包含元素item,那么从集合source-key里面移除元素并将元素item添加到集合dest-key中;如果元素item移动成功,返回1,否则返回0 |
对多个集合执行交集运算、并集运算和差集运算的命令
集合真正牛逼的地方,在于对组合和关联多个集合
命令 | 用例和描述 |
---|---|
SDIFF | SDIFF key-name [key-name … ]——返回那些存在于第一个集合,但不存在于其他集合中的元素(数学上的差集运算) |
SDIFFSTORE | SDIFFSTORE dest-key key-name [ key-name … ]——将那些存在于第一个集合(key-name)但并不存在于其他集合中的元素(数学上的差集运算)存储到dest-key集合中 |
SINTER | SINTER key-name [key-name … ] —— 返回那些同时存在于所有集合的元素(数学上的交集运算) |
SUNION | SUNION key-name [key-name … ] —— 返回那些至少存在于一个集合中的元素(数学上的并集运算) |
SUNIONSTORE | SUNIIONSTORE dest-key key-name [key-name … ] —— 返回那些至少存在于一个集合中的元素(数学上的并集运算)并存储到dest-key集合中 |
Hash 散列
可以把一条散列数据看成是数据库的一行
它跟Java的HashMap差不多,结构也是链表+数组的二维结构,而且数据是无序的
不同的是Redis的Hash只能存储字符串,而且它们的refresh方式不一样。Java的HashMap的refresh是一个耗时的操作,需要一次性全部refresh。而Redis为了提高性能,采用渐进式refresh策略,Redis会生成新旧两个hash,然后循环渐进的将旧hash的内容一点一点的移动到新的hash中,当搬迁完后,就是用新的hash替代旧的hash,如果在这个过程中需要查询数据,会同时查询两个hash,也就是在新旧两个hash里面搜索一遍
命令 | 用例和描述 |
---|---|
HMGET | HMGET key-name key [key … ] —— 从散列里面获取一个或者多个键的值 |
HMSET | HMSET key-name key value [key value …] —— 为散列里面的一个或者多个键设置值 |
HDEL | HDEL key-name key [key … ] —— 删除散列里面的一个或多个键值对,返回成功找到并删除的键值对数量 |
HLEN | HLEN key-name —— 返回散列包含的键值对数量 |
Redis散列的更高级特性
命令 | 用例和描述 |
---|---|
HEXISTS | HEXISTS key-name key —— 检查给定键是否存在于散列中 |
HKEYS | HKEYS key-name —— 获取散列包含的所有键 |
HVALS | HVALS key-name —— 获取散列包含的所有值 |
HGETALL | HGETALL key-name —— 获取散列包含的所有键值对 |
HINCRBY | HINCRBY key-name key increment —— 将键key存储的值加上整数increment |
HINCRBYFLOAT | HINCRBYFLOAT key-name key increment —— 将键key存储的值加上浮点数increment |
有序集合SortSet
可以把它看成是SortSet和HashMap的集合体,一方面它是一个Set,保证了内部value的唯一性,另一方面它可以给每个value赋值score权重
有序集合存储着成员与分值之间的映射,对分值大小的有序获取(fetch)或扫描(scan)成员和分值的命令
常用命令:添加新元素、更新已有的元素…
命令 | 用例和描述 |
---|---|
ZADD | ZADD key-name score member [ score member … ] —— 将带有给定分值的成员添加到有序集合里面 |
ZREM | ZREM key-name member [member …] —— 从有序集合里面移除给定的成员,并返回被移除成员的数量 |
ZCARD | ZCARD key-name —— 返回有序集合包含的成员数量 |
ZCOUNT | ZCOUNT key-name min max —— 返回分值介于min和max之间的成员数量 |
ZINCRBY | ZINCRBY key-name increment member —— 将member成员的分值加上increment,然后返回总分数 |
ZRANK | ZRANK key-name member —— 返回成员member在有序集合中的排名(排名是从0开始的) ,而低到高排列 |
ZSCORE | ZSCORE key-name member —— 返回成员member的分值 |
ZRANGE | ZRANGE key-name start stop [WITHSCORES] —— 返回有序集合中排名介于start和stop之间的成员,如果给定了可选的WITHSCORES选项,那么命令会将成员的分值也一并返回 |
- 注意 : ZADD 是分值在前,键在后
有序集合的高级命令
命令 | 用例和描述 | ||
---|---|---|---|
ZREVERANK | ZREVERANK key-name member —— 返回有序集合里成员member的排名,按分值从大到小排列 | ||
ZREVRANGE | ZREVRANGE key-name start stop [WITHSCORES] —— 返回有序集合给定给定排名范围内的成员,成员按照分值从大到小排列 | ||
ZRANGEBYSCORE | ZRANGEBYSCORE key-name min max [WITHSCORES] [LIMIT offset count] —— 获取有序集合中分值介于min和max之间的素有成员,并按照分值大小从大到小的顺序来返回他们 | ||
ZREMRANGEBYRANK | ZREMRANGEBYRANK key-name start stop—— 移除有序集合中排名介于start和stop之间的所有成员 | ||
ZREMRANGEBYSCORE | ZREMRANGEBYSCORE key-name min max —— 移除有序集合中分值介于min和max之间的所有成员 | ||
ZINTERSTORE | ZINTERSTORE dest-key key-count key [key .. ] [WEIGHTS weight [weight ..] ] [AGGREGATE SUM | MIN | MAX] —— 对给定的有序集合执行类似于集合的交集运算 |
ZUNIONSTORE | ZUNIONSTORE dest-key key-count key [key .. ] [WEIGHTS weight [weight ..]] [AGGREGATE SUM | MIN | MAX] —— 对给定的有序集合执行类似于集合的并集运算 |
- 注:AGGREGATE 后可以注明运算规则,如min表示选取最小值,max选取最大值,sum做和运算
有序结合的底层是使用 跳跃列表 实现的
跳跃列表的实现跟企业内部部门职位的划分差不多,企业那么多人,需要先划分部门,部门那么多人,需要有部长进行管理。Redis的有序集合实现的思路是,最下面一层的素有元素都会被串起来,然后每隔几个元素挑选出一个代表,代表之间用指针连接起来,然后代表很多的话又继续每隔几个代表再挑出二级代表,再串起来。
Sort命令
命令 | 用例和描述 | |
---|---|---|
SORT | SORT source-key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern …]] [ASC | DESC] [ALPHA dest-key] —— 根据给定的选项,对输入列表、集合或者有序集合进行排序,然后返回或者存储排序的效果 |
默认升序排序
最后两条命令,
1 将散列的域filed用作权重,也就是把sort-input的排列按照对应的field排序
2 排序方式同上,只是输出数据输出的是外部数据,也就是输出权重
Redis事务的基本用法
Redis的基本事务(basic transaction):我们需要向Redis发送多个命令,而且希望Redis能够完整的执行的我们的命令,不被其他事情打断,我们称之为事务,这种事务可以让一个客户端在不被其他客户端打断的情况下执行多个命令。需要用到multi命令和exec命令,被multi和exec命令包裹的所有命令,会一个接着一个执行,保证命令的有序性。也就是说,被multi和exec包裹的命令,就是我们的事务
过程:
当Redis从一个客户端那里接收到multi命令时,Redis会将这个客户端之后的所有命令放入到一个队列中,知道这个客户端发送exec命令,Redis就会在不被打断的情况下,一个接一个地执行存储在队列里面的命令。
而且Redis事务还会配合WATCH、UNWATCH、DISCARD另外这三个命令,等学到再说
键的过期时间
expire命令相信大家很熟悉,对某个键设置过期时间(秒),但是对于集合、列表、散列和有序集合这样的容器(container)来说,键过期命令只能为整个键设置过期时时间,不能设置键里面的单个元素设置过期时间(为了解决这个问题,我们可以自己为某个元素设置 存储时间戳的有序集合 来实现对单个元素的过期操作。
命令 | 实例和描述 |
---|---|
PERSIST | PERSIST key-name —— 移除键的过期时间 |
TTL | TTL key-name —— 查看给定键距离过期时间还有多少秒 |
EXPIRE | EXPIRE key-name seconds —— 让给定键在指定的描述之后过期 |
EXPIREAT | EXPIREAT key-name timestamp —— 将给定键的过期时间设置为给定的UNIX时间戳 |
PTTL | PTTL key-name —— 查看给定键距离过期时间还有多少毫秒,这个命令在Redis2.6或以上版本可用 |
PEXPIRE | PEXPIRE key-name milliseconds —— 让给定键在指定的毫秒数之后过期,这个命令在Redis2.6或者以上版本可用 |
PEXPIREAT | PERPIREAT key-name timestamp-milliseconds —— 将一个毫秒级精度的UNIX时间戳设置为给定键的过期时间,这个命令在Redis2.6或者以上版本可用 |
- 注:教程出自《Redis实战》
- 如果有知识上的探讨,欢迎发送邮件1171347956@qq.com