目录
- 单线程和多路 I/O 复用模型
- 数据结构
- 基本命令
- 1. 查看所有键
- 2.键总数
- 3.检查键是否存在
- 4.删除键
- 5.设置过期时间
- 6. 查看剩余过期时间
- 7.查看类型
- 五种类型的存储与获取
- string
- hash
- list
- set
- zset
- reids遍历
- keys
- scan
- 概念:
- 用法
单线程和多路 I/O 复用模型
redis是单线程:对于命令的处理是单线程的,也就是说,多个命令到来,会排成队列,逐条处理。单线程省去了很多上下文切换线程的时间,并且排除了并发操作的锁操作,所以号称速度快,redis的瓶颈一般不是cpu而是网络和内存。
多路 I/O 复用模型:“多路”指的是多个网络连接,“复用”指的是复用同一个线程。多路复用主要有三种技术:select,poll,epoll。redis采用的epoll是目前最新最好的多路复用技术。
数据结构
redis是内存型数据库,存储的全都是key-value键值对,其中key一定为string字符串类型,value则有五种类型。
redis对外一共提供5种数据类型
- string(字符串)
- hash(哈希 field-value)
- list(有序列表)
- set(集合)
- zset(有序集合)
redis实现上述数据结构实际上还有一套内部编码,比如字符串的内部编码embstr,列表的内部编码ziplist.
基本命令
1. 查看所有键
keys *
2.键总数
dbsize
dbsize直接获取键总数这个变量,时间复杂度O(1),keys是遍历一遍所有键,时间复杂度O(n),所以redis保存大量键时尽量不要使用keys
3.检查键是否存在
exists <keyName>
4.删除键
del <key> [key]
可以删除一个也可以空格分隔键批量删除
5.设置过期时间
expire <keyName> <seconds>
参数是键名和秒数,如下方设置为10秒
过了10秒之后
6. 查看剩余过期时间
ttl <keyName>
返回值有三种情况:
- 大于零 —剩余的秒钟数
- -1 —存在键,但未设置过期时间
- -2 —不存在键
7.查看类型
type <keyName>
返回值的数据类型,键不存在则返回none
五种类型的存储与获取
以下记录常用的命令,官方有所有指令的中文介绍,更全更详细,推荐查阅redis命令中文文档http://www.redis.cn/commands.html#
string
- 单值操作指令
set <keyName> <value> [EX seconds] [PX milliseconds] [nx|xx] [get]
设置键,不存在则新增,存在则修改get <keyName>
查看键
set命令有几个选项:
* ex ---秒级过期时间
* px ---毫秒级过期时间
* nx|xx:
* nx ---键必须不存在才可以设置成功(新增,等价于setex)
* xx ---键必须存在才可以设置成功(更新,等价于setnx)
* get ---回显修改前的值(等价于getset)
- 批量操作指令
mset key value [key value ...]
—批量设置mget key [key ...]
—批量获取
批量操作和批量单独操作对于redis处理的影响不大,但是网络请求是异步的,所以批量单独操作请求不如批量操作请求效率高,当然如果一次批量操作过大也会造成网络阻塞甚至redis阻塞
- 其他指令
1. incr key ---对值自增,返回自增后结果,若键不存在按0自增。类似的还有decr自减、incrby指定数字自增、decrby指定数字自减、incrbyfloat指定浮点数自增
2. append key value ---向字符串末尾追加值
3. strlen key ---返回字符串长度
4. setrange key offeset value ---将offeset位置的字符替换成value的值
hash
哈希类型和redis的key-value结构一样,为区分在使用hash类型的时候用field-value来表示哈希数据的一个键值对:{ field1:value1 , field2:value2 , ... ,fieldN:valueN}
- 指令
hset key field value
—设置值hmset key field value [ field value ... ]
—批量设置值hget key field
—获取值的某字段值hmget key field [field ...]
—批量获取值的某字段值hdel key field [field ...]
删除值的某字段hlen key
—获取键值的对数hexists key field
—判断field是否存在hkeys key
—虽然指令叫hkeys,实际获取的是所有fieldhvals key
—获取所有value
list
redis列表模型是一个横置的列表,从左到右的下标是0到N-1,从右到左的下标是-1到-N
- 指令
-
rpush key value [value ...]
/lpush key value [value ...]
从右/左插入(压栈) -
linsert key BEFORE|AFTER pivot element
在pivot位置的前/后插入元素element -
lrange key start end
查找start到end区间的元素,注意这里是左闭右闭! -
lindex key index
获取指定下标元素 -
llen key
获取长度 -
lpop key
/rpop key
删除左/右端的第一个元素(从左/右出栈) -
lrem key count value
:
* count>0,从左到右,删除count个值为value的元素
* count<0,从右到左,删除count个值为value的元素
* count=0,删除所有值为value的元素 -
lterm key start end
只保留start到end区间的元素,左闭右闭 -
lset key index newValue
修改指定下标元素
set
集合是无序不重复的列表 ,在普通增删改查的基础上,还有并交差补的操作,很方便
- 增删改查
-
sadd key element [element ...]
添加 -
srem key element [element ...]
删除 -
scard key
获取集合长度 -
sismember key element
是否存在元素 -
smembers key
无序获取所有元素
- 并交差补
-
sinter key [key ...]
返回多个集合交集 -
suion key [key ...]
返回多个集合并集 -
sdiff key [key ...]
返回多个集合差集 - 并没有补集…
- 并交差保存
-
sinterstore destinationKey [key ...]
将多个集合交集保存在destinationKey -
suionstore destinationKey [key ...]
将多个集合并集保存在destinationKey -
sdiffstore destinationKey [key ...]
将多个集合差集保存在destinationKey
zset
有序不重复的列表,排序方式是维护了一个 score分数表,为每一个元素保存一个score,作为排序的依据。
- 增删改查
-
zadd key score element [score element...]
添加element ,score是该元素的分数
zadd 命令有几个选项:
* nx|xx:
* nx ---member必须不存在才可以设置成功(新增)
* xx --member必须存在才可以设置成功(更新)
* ch ---changed ,元素和分数变化的个数
* incr ---对score增加,相当于zincrby
-
zrem key element [element ...]
删除 -
zcard key
获取集合长度 -
zscore key member
获取某成员的排序分数 -
zrank key member
返回某成员排名(按score从低到高) -
zrevrank key member
返回某成员排名(按score从高到低) -
zincrby key increment member
为某member增加increment排序分数 -
zrange key start end [withscores]
返回排名start到end之间的成员(按score从低到高,左闭右闭) -
zrevrange key start end [withscores]
返回排名start到end之间的成员(按score从高到低,左闭右闭)
reids遍历
keys
keys pattern
实际是正则表达式匹配,如keys *
匹配任意字符,
、hkeys…这类全遍历的命令开销很大,尽量不用,官方建议生产环境禁用keys指令,防止单线程阻塞。
而当有相应需求时,可以使用scan
系列命令
scan
SCAN 命令及其相关的 SSCAN, HSCAN 和 ZSCAN 命令都用于增量迭代一个集合元素。
- SCAN 命令用于迭代当前数据库中的key集合。
- SSCAN 命令用于迭代SET集合中的元素。
- HSCAN 命令用于迭代Hash类型中的键值对。
- ZSCAN 命令用于迭代SortSet集合中的元素和元素对应的分值
这几个命令都支持增量式迭代,它们每次执行都只会返回少量元素,所以这些命令可以用于生产环境,而不会出现像 KEYS 或者 SMEMBERS 命令带来的可能会阻塞服务器的问题。
这里只介绍scan
概念:
- SCAN命令是一个基于游标的迭代器。命令每次被调用使用上一次返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程
- 当SCAN命令的游标参数被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。
- 增量式迭代命令不保证每次迭代所返回的元素数量
用法
scan cursor [MATCH pattern] [COUNT count] [TYPE type]
- cursor 表示游标
增量迭代的步骤就是:
·1.scan 0
,返回下标n,和该次查询到的key数组
·2. 如果n=0,迭代结束,否则继续scan n
,返回下标n
·3. 重复2 - MATCH: glob 风格的模式参数, 让命令只返回和给定模式相匹配的元素。
- COUNT :默认为10,作用告知命令,本次查询希望返回多少元素,但不保证一定是这个数。
原理是规定一次查询所遍历的槽位数,这样的话,不同的COUNT会影响游标的值,不过一次轮询的每次查询不一定相同的COUNT,只要记得取用上一次的游标就可以了
例:
- 获取所有key(数据量比较小,所以默认count10一次搞定)
- 限定count为2