第2章 API的理解和使用
2018-05-22 本文已影响19人
leon4ever
理解Redis提供的5种数据结构,以及一些全局命令。
1. 预备
1.1 全局命令
- 查看所有键:
key
复杂度O(n),遍历所有键 - 键总数
dbsize
获取键总数,时间复杂度O(1) - 检查键是否存在
exits key
存在返回1,不存在返回0 - 删除键
del key [key ...]
支持删除多个键 - 键过期
expire key seconds
对键添加过期时间,超过过期时间后,会自动删除键
ttl key
ttl命令返回键的剩余过期时间/-1无过期时间/-2键不存在 - 键的数据结构类型
type key
返回键的类型:string, hash, list, set, zset(有序集合)
1.2 数据结构和内部编码
Redis对每种数据结构都有两种以上的内部编码实现,合适场景选择合适的内部编码,例如list数据结构包含了linkedlist和ziplist两种内部编码,同时有些内部编码,例如ziplist可以作为多种外部数据结构的内部实现。
Redis的5种数据结构.jpg
Redis数据结构和内部编码.jpg
好处:
- 可以改变内部编码
- 多种内部编码在不同场景下发挥优势
1.3 单线程架构
Redis使用单线程架构和I/O多路复用模型来实现高性能的内存数据库服务。
- 单线程队列模型,不存在多个命令同时执行
- 速度这么快?
- 纯内存访问
- 非阻塞I/O
- 单线程避免了线程切换和竞态消耗
2. 字符串
字符串类型的值实际可以是字符串、数字、甚至二进制(最大不超过512MB)。
字符串数据结构.jpg
2.1 命令
设置值
set key value [ex seconds] [px milliseconds] [nx | xx]
ex seconds:秒级过期时间
px milliseconds:毫秒级过期时间
nx:键必须不存在,才可以设置成功,用于添加
xx:与nx相反,键必须存在,用于更新
获取值
get key
批量设置值
mset key value [key value ...]
批量获取值
mget key [key ...]
批量的好处在于,可以避免网络成为性能的瓶颈,提高业务处理效率
计数
incr key
incr命令用于对值做自增操作,返回结果分为三种:
- 值不是整数,错误
- 值是整数,返回自增后结果
- 键不存在,按照值为0,自增后返回1
追加值
append key value
向字符串尾部追加值
字符串长度
strlen key
设置并返回原值
getset key value
getset和set一样会设置值,但不同的是,同时会返回键原来的值
设置指定位置id字符
setrange key offeset value
获取部分字符串
getrange key start end
2.2 内部编码
- int: 8个字节的长整型
- embstr: 小于等于39个字节的字符串
- raw: 大于39个字节的字符串
2.3 典型使用场景
-
缓存功能
Redis+MySQL组成的缓存存储架构.jpg -
计数
-
共享Session,考虑负载均衡情况下,分布式服务会将用户的访问均衡到不同服务器,session会失效
-
限速 限制访问频率,通过设置redis的超时时间
3. 哈希
字符串和哈希类型对比.jpg3.1 命令
hset key field value
hget key field
hdel key field [field ... ]
hlen key
hmget key field [ field ... ]
hmset key field value [field value ... ]
hexists key field
hkeys key //获取所有field
hvals key //获取所有value
hgetall key //获取所有的field-value
hstrlen key field //计算value的字符串长度
哈希类型命令的时间复杂度.jpg
3.2 内部编码
- ziplist(压缩列表):哈希类型元素个数小于512、同时所有value值小于64字节,使用更加紧凑的结构实现多个元素的连续存储,节省内存。
- hashtable(哈希表)
3.3 使用场景
关系型vs哈希类型缓存用户信息.jpg不同之处:
- 哈希类型是稀疏的,而关系型数据库是完全结构化的
- 关系型数据库可以做复杂的关系查询
4. 列表list
用来存储多个有序的字符串,每个字符串称为元素,可以充当栈和队列的角色。
列表的操作.jpg
4.1 命令
//添加
rpush key value [value ... ] //右边插入
lpush key value [value ... ] //左边插入
linsert key before|after pivot value //在某个元素前或后插入元素
//查找
lrange key start end //获取指定范围内的元素列表
lindex key index
llen key
//删除
lpop key
rpop key
lrem key count value //从列表中找到等于value的元素删除,count代表从左到右,删除多少个元素
ltrim key start end //按照索引范围修建列表
//修改
lset key index newValue //修改指定索引下标的元素
//阻塞操作
blpop key [key ...] timeout //timeout = 0,则一直阻塞
brpop key [key ...] timeout
列表命令时间复杂度.jpg
4.2 内部编码
- ziplist
- linkedlist
4.3 使用场景
- 消息队列
lpush+brpop命令组合即可实现阻塞队列 - 文章列表
分页展示文章列表
5. 集合
集合set也是用来保存多个字符串元素,但是和列表不一样,不允许重复元素,并且无序的,不能通过索引下标获取。
5.1 命令
//集合内操作
sadd key element [element ...] //添加元素
srem key element [element ...] //删除元素
scard key //计算元素个数
sismember key element //判断是否在集合中
spop key //随机弹出元素
smembers key //获取所有元素
//集合间操作
sinter key [key ... ] //求多个集合的交集
suinon key [key ...] //求多个集合的并集
sdiff key [key ...] //求多个集合的差集
集合常用命令时间复杂度.jpg
5.2 内部编码
- intset:整数集合
- hashtable:哈希表
5.3 使用场景
标签,比如用户的兴趣点
6. 有序集合
保留了集合不能重复的特性,但可以排序,给每个元素设置一个分数score作为排序依据
有序集合.jpg 列表、集合、有序集合的异同点.jpg6.1 命令
6.2 内部编码
- ziplist(压缩列表)
- skiplist(跳跃表)
6.3 使用场景
排行榜系统,多个维度的榜单
7. 键管理
7.1 单个键管理
- 键重命名:rename key newkey
- 随机返回一个键:randomkey
- 键过期,seconds秒后:expire key seconds
- 秒级时间戳后过期expireat key timestamp
注意:对字符串类型键,set会去掉过期时间!
迁移键
- move key db
- dump key
restore key ttl value - migrate host port key | " " destination-db timeout [copy] [replace] [keys key [key ...] ]
7.2 遍历键
- 全量遍历键:keys pattern
- 渐进式遍历:scan,只扫描一个字典中的一部分键
scan cursor [match pattern] [count number]
7.3 数据库管理
- 切换数据库:select
- 清楚数据库:flushdb/flushall