Book1:Redis 入门指南(100/100)
1、Redis 虽然是作为数据库开发的,但由于其提供了丰富的功能,越来越多的人将其用作:缓存、队列系统等。
缓存:Redis可以为每个键设置生存时间(Time To Live, TTL),生存时间到期后键会自动被删除。
Redis还可以限定数据占用的最大内存空间,在数据达到空间限制后可按照一定的规则自动淘汰不需要的键。
队列:Redis的列表类型键可以用来实现队列,并支持阻塞式读取,可以很容易的实现一个高性能的优先级队列。
2、关系数据库中要获取posts表内id为1的记录的title字段的值,可以用如下sql:
select title from posts where id = 1 limit 1
相应的,在Redis中要读取键名为post:1的散列类型键的title字段的值,可以使用如下命令:
HGET post:1 title
3、命令
redis > SET bar 1 建立一个名为bar的键 set key value
redis > get bar 获取一个名为bar的键的值 get key
redis > KEYS * 获得redis中所有的键
redis > KEYS bar 获得redis中键为bar
redis > KEYS ba* 获得redis中所有以ba开头的键
redis > EXISTS bar 如果键存在返回整数类型1,否则0
redis > del bar 删除键 返回的是删除键的个数
redis > type key 获取键值的数据类型:string hash list set zset
redis > incr key 递增key对应的值,不存在此key开始默认0,key类型不是整数时报错
redis > incrby key 8 指定加多少
redis > decr key
redis > decrby key 8
redis > incrbyfloat key 3.4
redis > append key value 向键值的末尾追加value,返回值是追加后的字符串的总长度
redis > strlen key
redis > mset key1 v1 key2 v2 key3 v3 同时设置多个键值
redis > mget key1 key2 key3 同时获得多个键值
4、散列类型 hash
字段值只能是字符串,不支持其他数据类型嵌套。适合存储对象使用对象类别和id构成键名
例子:键 字段(filed) 字段值
car:2 color white
name aodi
price 900000
相比于关系数据库,我们可以为任何一条记录新增属性,而不需要考虑其他记录。
命令:
hset key field value
hget key field
hmset key field value field1 value1 field2 value2
redis > hset car price 500
redis > hset car name BMW
redis > hget car name
redis > hmget car price name
redis > hgetall 获取键中所有字段和字段值
redis > hexists key field 判断字段是否存在 存在返回1否则0
redis > hincby key field 5
redis > hdel key field
redis > hkeys key 只获取字段名
redis > hvals key 只获取字段值
redis > hlen key 获取字段数量
5、列表类型 list
可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素、或者获得列表的某一个片段。
列表类型内部使用双向链表实现,
lpush key value 向列表左边增加元素
rpush key value 向列表右边增加元素,返回值表示增加元素后列表的长度
lrange queue 0 3 查询队列元素,queue是队列名,从0位置开始,查询三个元素
lpop key 从列表左边弹出一个元素
rpop key 从列表右边弹出一个元素 返回被移除的元素值
llen key 列表长度
lrange key start end 获取列表片段,从0开始计数,包含两段
lrem key count value count大于0,从左边开始删除前count个值为value的元素,小于0从右边,等于0,删除所欲。
redis > lpush numbers 1 [1]
redis > lpush numbers 2 [2 1]
redis > lpush numbers 3,4 [4 3 2 1]
redis > rpush numbers 5,6 [4 3 2 1 5 6]
6、集合类型 set
集合中的元素,无序、不重复,而列表类型是有序、重复,正好相反。
由于集合类型在redis内部是使用值为空的散列表 hash table 实现的,所以加入、删除、查找元素的时间复杂度都是o(1)
还可以多个集合类型键之间并集、交集等等。
SADD key member 增加元素
SREM key member 删除元素
SISMEMBER key member 判断元素是否在集合中 存在返回1,否则0
SMEMBERS key 获取集合中的所有元素
redis > sadd set1 a
redis > sadd set1 a b c
redis > srem set1 b
集合间运算
sdiff key key1 差集
redis > sadd setA 1 2 3
redis > sadd setB 2 3 4
redis > sdiff setA setB 返回1
sinter key key1 交集
redis > sinter setA setB 返回2 3
sunion key key1 并集
redis > sunion setA setB 返回1 2 3 4
redis > sadd letters a
redis > sadd letters b
redis > smembers letters 返回所有元素 a b
redis > scard letters 返回个数 2
redis > sdiffstore destination setA setB :A和B差集存在destination
redis > srandmenber key 随机获取一个元素
7、有序集合类型 zset
在集合类型的基础上,为每个元素都关联一个分数
zadd key score member
zscore key member 获得元素的分数
zrange key start end 获得排名在某个范围的元素列表
zrangebyscore key min max 获得指定分数范围的元素
zincrby key increment member 为某个元素增加分数
redis > zadd socreboard 100 zhengchao 90 liuzhen 80 china
redis > zscore scoreboard zhengchao
redis > zrange socreboard 0 2
redis > zrangebyscore scoreboard 80 100
redis > zincrby scoreboard 20 zhengchao
redis > zcard key 获得集合中元素的数量
redis > zcount scoreboard 90 100 获得指定分数范围内的元素个数
redis > zrem scoreboard china 删除一个或多个元素
8、事务
redis > multi 声明一个事务开始
redis > sadd key value
redis > sadd key1 value1
redis > exec 提交
语法有错误,整个执行都不会生效
运行错误,成功的就成功了
9、生存时间
Redis中可以使用expire命令设置一个键的生存时间,到时间后,redis会自动删除它
语法:
expire key seconds ,其中seconds参数表示键的生存时间,单位是秒
redis > set session:95528 “普法银行”
redis > expire session:95528 900 15分钟有效期,返回1表示成功
查询一个键剩余时间:
ttl key 返回还剩余生存时间,单位秒
取消设置生存时间(即设置为永久):
persist key
10、设置redis的最大可用内存
修改配置文件的maxmemory参数,单位字节。
当超过了这个限制,redis会依据maxmemory-policy 参数指定的策略来删除不需要的键,直到redis占用的内存小于指定的内存。
maxmemory-policy支持的规则:
lru:最近最少使用。least recently used
11、排序
sort key:只能处理list set 和有序集合
redis > zadd myset 59 34 23 24 20
redis > sort myset 返回:20 23 24 34 50
redis > sort myset desc 返回:50 34 24 23 20
支持分页:limit offset count,表示跳过前offset个元素,并获取之后的count个元素
redis > sort miser desc limit 1 2 返回:34 24
12、任务队列
使用redis实现任务队列:说到队列,自然想到了redis的列表类型 :lpush rpop
生产者将任务使用lpush命令加入到某个键中,另一边的消费者不断的使用rpop从该键中取出任务即可。
rpop无法判断列表中是否还有任务,可以使用brpop,当列表中没有元素时brpop命令会一直阻塞连接,直到有新元素加入。
brpop 两个参数 键名 和 超时时间 单位秒
当超过了超时时间仍然没有新元素的话就返回nil。设置为0表示不限制等待时间,即如果没有新元素加入列表就会永远阻塞下去。
13、优先级队列
使用brpop 可以同时监听多个键的功能,brpop key1 key2 timeout,如果多个键都有元素则按照从左往右的顺序读取第一个键中的一个元素
14、发布/订阅 模式
15、管道
客户端和redis使用tcp协议连接,都需要经过网络传输,发到接受:往返时延。
通过管道可以一次性发送多条命令并在执行完后一次性将结果返回。多条命令要互相不依赖对方的返回结果。
可以减少客户端与redis的通信次数来实现降低往返时延累。
15、节省空间
redis是基于内存的数据库。所有的数据都存储在内存中,如何优化存储,减少内存空间占用对。。。
16、持久化方式:RDB方式与AOF方式
RDB方式
AOF方式
每执行一条会更改Redis中的数据的命令,Redis就将该命令写入硬盘的aof文件。redis在该文件中实现了冗余数据的清楚。
redis提供了复制功能,避免单点故障导致的数据丢失:简单设置,就可以实现
默认情况下,从数据库是只读的,主数据库中的任何数据变化都会自动同步到从数据库。
复制的作用很大:
1、实现读写分离,现实中读的频率很大,从数据库可用来只读。
2、提高服务器的负载能力。
以下源自:http://www.cnblogs.com/shangzekai/p/4705430.html
redis的rdb的配置选项和它的工作原理:
save 900 1 // 表示的是900s内,有1条写入,则产生快照
save 300 1000 // 表示的是300s内,有1000次的写入,则产生快照
save 60 10000 // 表示的是60s内,有10000次的写入,则产生快照
(这3个选项都屏蔽,则rdb被禁用)
stop-writes-on-bgsave-error yes // 后台dump备份进程出错的时候,主进程停止不停写入?
rdbcompression yes // 导出的rdb文件是否需要压缩
rdbchecksum yes //导出的rdb恢复时数据要不要检验rdb的完整性
dbfilename dump.rdb //导出来的rdb文件名
dir ./ //rdb的放置路径
上面的就是rdb的常用配置,那它的备份原理是啥?
非常的简单,只要满足上面的save的3个条件中的任何一条,都会直接从内存中dump出一份镜像到磁盘上,速度非常的快
那我们考虑,如果我们在某一个时刻set存入一条数据,那这时突然redis宕机,那这个时候我们set的数据就会丢失,这是它的一个弊端,就是在发生一些异常的情况的时候,我们可能会丢失1-n分钟内的数据
那我们接下来看一下aof日志的一些配置和原理,它解决了上面rdb不能解决的一些问题:
同样,还是来看一下相关的配置内容:
appendonly no # 是否打开 aof日志功能
appendfsync always # 每1个命令,都立即同步到aof. 安全,速度慢
appendfsync everysec # 折衷方案,每秒写1次
no-appendfsync-on-rewrite yes: # 正在导出rdb快照的过程中,要不要停止同步aof
auto-aof-rewrite-percentage 100 #aof文件大小比起上次重写时的大小,增长率100%时,重写
auto-aof-rewrite-min-size 64mb #aof文件,至少超过64M时,重写
那我们开启了aof的日志的功能的时候,这时候我们每一次进行操作,aof就会将所有的操作记录到aof的日志中,我们可以通过appendfsync和我们具体的业务场景来具体指定多长时间写入文件,当然了推荐是everysec,那这样的话,由于我们记录的是每隔一秒的操作,那如果redis突然宕机的话,我们可以通过aof来恢复数据,这样的话就解决了上述rdb出现的数据丢失的问题,当然了这也会丢失大概1秒的数据吧,损失就会降低很多
我们来看一下相关的问题:
1 注: 在dump rdb过程中,aof如果停止同步,会不会丢失?
2 答: 不会,所有的操作缓存在内存的队列里, dump完成后,统一操作.
3
4 注: aof重写是指什么?
5 答: aof重写是指把内存中的数据,逆化成命令,写入到.aof日志里.
6 以解决 aof日志过大的问题.
7
8 问: 如果rdb文件,和aof文件都存在,优先用谁来恢复数据?
9 答: aof,不会使用rdb来进行恢复数据
10
11 问: 2种是否可以同时用?
12 答: 可以,而且推荐这么做
13
14 问: 恢复时rdb和aof哪个恢复的快
15 答: rdb快,因为其是数据的内存映射,直接载入到内存,而aof是命令,需要逐条执行