用法 :DEL ke [key …]
删除给定的一个或多个 key
。不存在的 key
会被忽略。
用法 :EXISTS key
检查给定 key
是否存在
用法:EXPIRE key seconds
为给定 key
设置生存时间,当 key
过期时(生存时间为 0
),它会被自动删除
用法:KEYS pattern
查找所有符合给定模式 pattern
的 key
。
KEYS *
匹配数据库中所有 key
。
KEYS h?llo
匹配 hello
, hallo
和 hxllo
等。
KEYS h*llo
匹配 hllo
和 heeeeello
等。
KEYS h[ae]llo
匹配 hello
和 hallo
,但不匹配 hillo
。
特殊符号用 \
隔开
用法:TTL key
以秒为单位,返回给定 key
的剩余生存时间(TTL, time to live)。
用法:TYPE key
返回 key
所储存的值的类型。
返回值:
none
(key不存在)
string
(字符串)
list
(列表)
set
(集合)
zset
(有序集)
hash
(哈希表)
SET KEY_NAME VALUE
Redis SET 命令用于设置给定 key 的值。如果 key 已经存储值, SET 就覆写旧值,且无视类型
SETNX key value
解决分布式锁 方案之一
只有在 key 不存在时设置 key 的值。Setnx(SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值
MSET key value [key value …]
同时设置一个或多个 key-value 对
SETEX key seconds value
将值 value
关联到 key
,并将 key
的生存时间设为 seconds
(以秒为单位)。
如果 key
已经存在, SETEX 命令将覆写旧值。
SEXEX是一个原子操作
GET KEY_NAME
Redis GET命令用于获取指定 key 的值。如果 key 不存在,返回 nil 。如果key 储存的值不是字符串类型,返回一个错误。
GETRANGE key start end
用于获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)
MGET key1 [key2…]
获取所有(一个或多个)给定 key 的值
STRLEN key
返回 key 所储存的字符串值的长度
GETSET KEY_NAME VALUE
Getset 命令用于设置指定 key 的值,并返回 key 的旧值,当 key 不存在时,返回 nil
INCR KEY_Name
Incr 命令将 key 中储存的数字值增1。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作
INCRBY KEY_Name 增量值
Incrby 命令将 key 中储存的数字加上指定的增量值
DECR KEY_NAME 或 DECYBY KEY_NAME 减值
decR 命令将 key 中储存的数字减1
Redis hash
是一个string
类型的field
和value
的映射表,hash特别适合用于存储对象。
hash类型类似于Java中对象的概念,允许有多个字段
HSET KEY FIELD VALUE
为指定的KEY,设定FILD/VALUE
HMSET KEY FIELD VALUE [FIELD1,VALUE1]……
同时将多个 field-value (域-值)对设置到哈希表 key 中
HGET KEY FIELD
获取存储在HASH中的值,根据FIELD得到VALUE
HMGET key field[field1]
获取key所有给定字段的值
HGETALL key
返回HASH表中所有的字段和值
HDEL KEY field1[field2]
删除一个或多个HASH表字段
HSETNX key field value
只有在字段 field 不存在时,设置哈希表字段的值
HINCRBY key field increment
为哈希表 key 中的指定字段的整数值加上增量 increment 。
HINCRBYFLOAT key field increment
为哈希表 key 中的指定字段的浮点数值加上增量 increment 。
HEXISTS key field
查看哈希表 key 中,指定的字段是否存在
LPUSH key value1 [value2]
将一个或多个值插入到列表头部(从左侧添加)
RPUSH key value1 [value2]
在列表中添加一个或多个值(从右侧添加)
LPUSHX key value
将一个值插入到已存在的列表头部。如果列表不在,操作无效
RPUSHX key value
一个值插入已存在的列表尾部(最右边)。如果列表不在,操作无效。
LLEN key
获取列表长度
LINDEX key index
通过索引获取列表中的元素
LRANGE key start stop
获取列表指定范围内的元素
描述: 返回列表中指定区间内的元素,区间以偏移量 START
和 END
指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
start:
页大小*(页数-1)
stop :
(页大小*页数)-1
LPOP key
移出并获取列表的第一个元素(从左侧删除)
RPOP key
移除列表的最后一个元素,返回值为移除的元素(从右侧删除)
BLPOP key1 [key2 ] timeout
移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
实例
redis 127.0.0.1:6379> BLPOP list1 100
在以上实例中,操作会被阻塞,如果指定的列表 key list1 存在数据则会返回第一个元素,否则在等待100秒后会返回 nil 。
BRPOP key1 [key2 ] timeout
移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
LTRIM key start stop
对一个列表进行修剪(trim
),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
LSET key index value
通过索引设置列表元素的值
LINSERT key BEFORE|AFTER world value
在列表的元素前或者后插入元素
描述:将值 value
插入到列表 key
当中,位于值 world
之前或之后。
如果有多个相同的值,取第一个
RPOPLPUSH source destination
移除列表的最后一个元素,并将该元素添加到另一个列表并返回
示例描述:
RPOPLPUSH a1 a2
//a1的最后元素移到a2的左侧
RPOPLPUSH a1 a1
//循环列表,将最后元素移到最左侧
BRPOPLPUSH source destination timeout
从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
SADD key member1 [member2]
向集合添加一个或多个成员
SCARD key
获取集合的成员数
SMEMBERS key
返回集合中的所有成员
SISMEMBER key member
判断 member
元素是否是集合 key
的成员(开发中:验证是否存在判断)
SRANDMEMBER key [count]
返回集合中一个或多个随机数
SREM key member1 [member2]
移除集合中一个或多个成员
SPOP key [count]
移除并返回集合中的一个随机元素
SMOVE source destination member
将 member
元素从 source
集合移动到 destination
集合
SDIFF key1 [key2]
返回给定所有集合的差集(左侧)
SDIFFSTORE destination key1 [key2]
返回给定所有集合的差集并存储在 destination
中
SINTER key1 [key2]
返回给定所有集合的交集(共有数据)
SINTERSTORE destination key1 [key2]
返回给定所有集合的交集并存储在 destination
中
SUNION key1 [key2]
返回所有给定集合的并集
SUNIONSTORE destination key1 [key2]
所有给定集合的并集存储在 destination 集合中
赋值语法
ZADD key score1 member1 [score2 member2]
向有序集合添加一个或多个成员,或者更新已存在成员的分数
取值语法
ZCARD key
获取有序集合的成员数
ZCOUNT key min max
计算在有序集合中指定区间分数的成员数
ZRANK key member
返回有序集合中指定成员的索引
ZRANGE key start stop [WITHSCORES]
通过索引区间返回有序集合成指定区间内的成员(低到高)
ZREVRANGE key start stop [WITHSCORES]
返回有序集中指定区间内的成员,通过索引,分数从高到底
删除语法
del key
移除集合
ZREM key member [member ...]
移除有序集合中的一个或多个成员
ZREMRANGEBYRANK key start stop
移除有序集合中给定的排名区间的所有成员(第一名是0)(低到高排序)
ZREMRANGEBYSCORE key min max
移除有序集合中给定的分数区间的所有成员
HyperLogLog是Redis的高级数据结构,是统计基数的利器。
PFADD key element [element …]
将任意数量的元素添加到指定的 HyperLogLog 里面。
PFCOUNT key [key …]
当 PFCOUNT]
命令作用于单个键时, 返回储存在给定键的 HyperLogLog 的近似基数, 如果键不存在, 那么返回 0
。
PFMERGE destkey sourcekey [sourcekey …]
将多个 HyperLogLog 合并(merge)为一个 HyperLogLog , 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合(observed set)的并集。
订阅频道
SUBSCRIBE channel [channel ...]
订阅给定的一个或多个频道的信息
PSUBSCRIBE pattern [pattern ...]
订阅一个或多个符合给定模式的频道。
发布频道
PUBLISH channel message
将信息发送到指定的频道。
退订频道
UNSUBSCRIBE [channel [channel ...]]
指退订给定的频道。
PUNSUBSCRIBE [pattern [pattern ...]]
退订所有给定模式的频道。
FLUSHALL
清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。
FLUSHDB
清空当前数据库中的所有 key。
此命令从不失败。
SELECT INDEX
用于切换到第index个数据库。
Redis 不支持回滚(roll back)
DISCARD
取消事务,放弃执行事务块内的所有命令。
EXEC
执行所有事务块内的命令。
MULTI
标记一个事务块的开始。
UNWATCH
Redis Unwatch
命令用于取消 WATCH
命令对所有 key
的监视。
如果在执行WATCH
命令之后,EXEC
命令或DISCARD
命令先被执行的话,那就不需要再执行UNWATCH
了
WATCH key [key ...]
监视一个(或多个) key
,如果在事务执行之前这个(或这些) key
被其他命令所改动,那么事务将被打断。
redis
提供6种数据淘汰策略:
Redis有两种持久化的方式:快照(RDB
文件)和追加式文件(AOF
文件)
RDB持久化方式会在一个特定的间隔保存那个时间点的一个数据快照。
工作原理
优点
缺点
fork()
产生子进程进行数据的持久化,如果数据比较大的话可能就会花费点时间,造成Redis停止服务几毫秒。如果数据量很大且CPU性能不是很好的时候,停止服务的时间甚至会到1秒。每当Redis接受到会修改数据集的命令时,就会把命令追加到AOF文件里,当你重启Redis时,AOF里的命令会被重新执行一次,重建数据。
优点
redis-check-aof
这个工具很简单的进行修复。FLUSHALL
命令把所有数据刷掉了,只要文件没有被重写,我们可以把服务停掉,把最后那条命令删掉,然后重启服务,这样就能把被刷掉的数据恢复回来。缺点
请求去查询一条压根儿数据库中根本就不存在的数据,也就是缓存和数据库都查询不到这条数据,但是请求每次都会打到数据库上面去。这种查询不存在数据的现象我们称为缓存穿透。
穿透带来的问题
如果有黑客会对你的系统进行攻击,拿一个不存在的id 去查询数据,会产生大量的请求到数据库去查询。可能会导致你的数据库由于压力过大而宕掉。
解决方案
缓存空值
之所以会发生穿透,就是因为缓存中没有存储这些空数据的key。从而导致每次查询都到数据库去了。那么我们就可以为这些key对应的值设置为null 丢到缓存里面去。后面再出现查询这个key 的请求的时候,直接返回null 。
布隆过滤器
这种方案可以加在第一种方案中,在缓存之前在加一层 BloomFilter ,在查询的时候先去 BloomFilter 去查询 key 是否存在,如果不存在就直接返回,存在再走查缓存 -> 查 DB。
在平常高并发的系统中,大量的请求同时查询一个 key 时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去。这种现象我们称为缓存击穿。
击穿带来的问题
会造成某一时刻数据库请求量过大,压力剧增。
解决方案
上面的现象是多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。
缓存雪崩的情况是说,当某一时刻发生大规模的缓存失效的情况,比如你的缓存服务宕机了,会有大量的请求进来直接打到DB上面。
缓存雪崩带来的问题
DB 称不住,挂掉。
解决方案
使用集群缓存,保证缓存服务的高可用
ehcache本地缓存 + Hystrix限流&降级,避免MySQL被打死
开启Redis持久化机制,尽快恢复缓存集群
我们在设置缓存的时候,一般会给缓存设置一个失效时间,过了这个时间,缓存就失效了。
对于一些热点的数据来说,当缓存失效以后会存在大量的请求过来,然后打到数据库去,从而可能导致数据库崩溃的情况。
解决办法
为了避免这些热点的数据集中失效,那么我们在设置缓存过期时间的时候,我们让他们失效的时间错开。
比如在一个基础的时间上加上或者减去一个范围内的随机值。
结合上面的击穿的情况,在第一个请求去查询数据库的时候对他加一个互斥锁,其余的查询请求都会被阻塞住,直到锁被释放,从而保护数据库。
但是也是由于它会阻塞其他的线程,此时系统吞吐量会下降。需要结合实际的业务去考虑是否要这么做。