您的位置:首页 > 数据库 > Redis

Redis学习总结

2016-11-22 13:52 162 查看
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      向列表右边增加元素,返回值表示增加元素后列表的长度

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是命令,需要逐条执行
   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  redis