全局命令
1.查看所有键 keys*命令会将所有的键输出,遍历O(n),线上禁用
keys *
2.键总数 dbsize命令会返回当前数据库中键的总数(利用Redis内置的键总数变量O(1))。
dbsize
3.检查键是否存在 如果键存在则返回1,不存在则返回0
exists key
4.删除键 返回结果为成功删除键的个数
del key [key ...]
5.键过期 当超过过期时间后,会自动删除键
expire key seconds
ttl命令会返回键的剩余过期时间,大于等于0的整数:键剩余的过期时间,-1:键没设置过期时间,-2:键不存在
6.键的数据结构类型
type key
数据结构和内部编码
string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)
单线程架构
Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务
为什么速度会很快?
第一,纯内存访问,Redis将所有数据放在内存中,内存的响应时长大约为100纳秒,这是Redis达到每秒万级别访问的重要基础。
第二,非阻塞I/O,Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间(可以参考Netty的EventLoop实现)
第三,单线程避免了线程切换和竞态产生的消耗。
字符串
字符串类型是Redis最基础的数据结构,值最大不能超过512MB。
1.命令
set key value [ex seconds] [px milliseconds] [nx|xx]
ex seconds:为键设置秒级过期时间
px milliseconds:为键设置毫秒级过期时间
nx:键必须不存在,才可以设置成功,用于添加(衍生setex和setnx两个命令)
xx:与nx相反,键必须存在,才可以设置成功,用于更新
分布式锁:setnx可以实现分布式锁.
get key
获取值.
mset key value [key value ...]
批量设置值
mget key [key ...]
批量获取值
批量操作命令可以有效提高开发效率(可以节省n-1次网络请求时间)
incr key
incr命令用于对值做自增操作,返回结果分为三种情况,值不是整数,返回错误,值是整数,返回自增后的结果,键不存在,按照值为0自增,返回结果为1
除了incr命令,Redis提供了decr(自减)、incrby(自增指定数字)、decrby(自减指定数字)、incrbyfloat(自增浮点数):
2.典型使用场景
- 缓存功能
- 计数(可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。)
- 共享Session(可以使用Redis将用户的Session进行集中管理)
- 限速(ip访问频率限制,短信频率限制)
哈希
形如value={{field1,value1},...{fieldN,valueN}}
1.命令
hset key field value
设置值.Redis提供了hsetnx命令,它们的关系就像set和setnx命令一样,只不过作用域由键变为field。
hget key field
获取值,不存在返回nil
hdel key field [field ...]
hdel会删除一个或多个field,返回结果为成功删除field的个数.
hlen key
计算field个数
hmget key field [field ...]
hmset key field value [field value ...]
批量设置或获取field-value
hexists key field
判断field是否存在
hkeys key
获取所有field
hvals key
获取所有value
hgetall key
获取所有的field-value
使用场景
三种方法缓存用户信息优缺点
1)原生字符串类型:每个属性一个键。
优点:简单直观,每个属性都支持更新操作。
缺点:占用过多的键,内存占用量较大,同时用户信息内聚性比较差,所以此种方案一般不会在生产环境使用。
2)序列化字符串类型:将用户信息序列化后用一个键保存。
优点:简化编程,如果合理的使用序列化可以提高内存的使用效率。
缺点:序列化和反序列化有一定的开销,同时每次更新属性都需要把全部数据取出进行反序列化,更新后再序列化到Redis中。
3)哈希类型:每个用户属性使用一对field-value,但是只用一个键保存。
优点:简单直观,如果使用合理可以减少内存空间的使用。
缺点:要控制哈希在ziplist和hashtable两种内部编码的转换,hashtable会消耗更多内存。
列表
1.命令
rpush key value [value ...]
从右边插入元素
lrange key 0 -1
可以从左到右获取列表的所有元素
lpush key value [value ...]
从左边插入元素
linsert key before|after pivot value
向某个元素前或者后插入元素,linsert命令会从列表中找到等于pivot的元素,在其前(before)或者后(after)插入一个新的元素value
lindex key index
获取列表指定索引下标的元素
llen key
获取列表长度
lpop key
从列表左侧弹出元素
lrem key count value
删除指定元素
ltrim key start end
按照索引范围修剪列表
lset key index newValue
修改指定索引下标的元素
blpop key [key ...] timeout
brpop key [key ...] timeout
阻塞式弹出 key[key...]:多个列表的键 timeout:阻塞时间(单位:秒)
内部编码
ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节)
linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现.
使用场景
1.消息队列
Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。
2.文章列表
·lpush+lpop=Stack(栈)
·lpush+rpop=Queue(队列)
·lpsh+ltrim=Capped Collection(有限集合)
·lpush+brpop=Message Queue(消息队列)
集合
一个集合最多可以存储23平方-1个元素,无序不重复。
命令
sadd key element [element ...]
添加元素
srem key element [element ...]
删除元素
scard key
计算元素个数.不会遍历集合所有元素,而是直接用Redis内部的变量
sismember key element
判断元素是否在集合中
srandmember key [count]
随机从集合返回指定个数元素 [count]是可选参数,如果不写默认为1
spop key
从集合随机弹出元素
smembers key
获取所有元素,返回结果是无序的
sinter key [key ...]
suinon key [key ...]
sdiff key [key ...]
求多个集合的交集/求多个集合的并集/多个集合的差集
sinterstore destination key [key ...]
suionstore destination key [key ...]
sdiffstore destination key [key ...]
将交集、并集、差集的结果保存
内部编码
intset(整数集合):当集合中的元素都是整数且元素个数小于set-maxintset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。
hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。
使用场景
sadd=Tagging集合类型比较典型的使用场景是标签(tag)
spop/srandmember=Random item(生成随机数,比如抽奖)
sadd+sinter=Social Graph(社交需求,寻找共同爱好)
有序集合
保留了集合不能有重复成员的特性,给每个元素设置一个分数(score)作为排序的依据.
命令
zadd key score member [score member ...]
添加成员
·Redis3.2为zadd命令添加了nx、xx、ch、incr四个选项:
·nx:member必须不存在,才可以设置成功,用于添加。
·xx:member必须存在,才可以设置成功,用于更新。
·ch:返回此次操作后,有序集合元素和分数发生变化的个数
·incr:对score做增加,相当于后面介绍的zincrby。
zcard key
计算成员个数
zscore key member
计算某个成员的分数
zrank key member
zrevrank key member(反着来)
计算成员的排名
zrem key member [member ...]
删除成员
zincrby key increment member
增加成员的分数
zrange key start end [withscores]
zrevrange key start end [withscores]
zrange是从低到高返回,zrevrange反之。
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offset count]
返回指定分数范围的成员,同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和+inf分别代表无限小和无限大
内部编码
ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplistentries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用。
skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的读写效率会下降。
使用场景
有序集合比较典型的使用场景就是排行榜系统。
键管理
rename key newkey
键重命名,如果在rename之前,键java已经存在,那么它的值也将被覆盖,为了防止被强行rename,Redis提供了renamenx命令,确保只有newKey不存在时候才被覆盖
randomkey
随机返回一个键
·expire key seconds:键在seconds秒后过期。
·expireat key timestamp:键在秒级时间戳timestamp后过期。
对于字符串类型键,执行set命令会去掉过期时间,这个问题很容易在开发中被忽视。
Redis不支持二级数据结构(例如哈希、列表)内部元素的过期功能,例如不能对列表类型的一个元素做过期时间设置。
setex命令作为set+expire的组合,不但是原子执行,同时减少了一次网络通讯的时间。
move key db 用于在Redis内部进行数据迁移
dump key dump+restore可以实现在不同的Redis实例之间进行数据迁移的功能
restore key ttl value
migrate host port key|"" destination-db timeout [copy] [replace] [keys key [key 用于在Redis实例间进行数据迁移
1)在源Redis上,dump命令会将键值序列化,格式采用的是RDB格式。
2)在目标Redis上,restore命令将上面序列化的值进行复原,其中ttl参数代表过期时间,如果ttl=0代表没有过期时间。
keys pattern
eg. redis-cli keys video* | xargs redis-cli del 删除所有以video字符串开头的键(不要在线上操作,可以在不对外提供服务的Redis从节点上执行,但会影响主从复制)
全量遍历键
scan cursor [match pattern] [count number]
渐进式遍历,每次scan命令的时间复杂度是O(1),但是要真正实现keys的功能,需要执行多次scan。
为解决诸如hgetall、smembers、zrange可能产生的阻塞问题,redis对应的命令分别是hscan、sscan、zscan
存在问题:在扫描的时候插入新值.新增的键可能没有遍历到,遍历出了重复的键等情况
select dbIndex
切换数据库(默认配置中是有16个数据库),不建议使用该功能.
flushdb 清除当前数据库
flushall 清除所有数据库