redis基础

1、redis的数据结构

  redis支持5种数据结构:

  1、string(字符串)

  2、list(字符串列表)

  3、sets(字符串集合)

  4、sorted sets(有序字符串集合)

  5、hashes(哈希)

  

1.1、string

  string是任何存储系统必备的数据类型,下面是一个简单例子:

  

  字符串操作就是这么简单,而且因为是二进制安全,所以也可以存储图片,而且可以通过字符串类型进行数值操作

  

  在遇到数值操作时,redis会自动将字符串转换为数值

  由于incr等指令具有原子性操作的特性。所以我们可以使用incr、INCRBY、DECR、DECRBY等命令来进行原子计数的效果

1.2、lists

  首先明确一点,lists在底层实现并不是数组,而是链表,也就是说对于一个具有上百万元素的lists在头部和尾部插入数据的时间复杂度是常数级别的,所以在将元素插入一个上百万元素的lists与插入一个只有10个元素的lists中的速度是一样的。

  虽然lists有这样的优势,但也有其弊端,链表型lists比数组型lists定位要慢得多。

  lists的基础操作有:lpush、rpush、lange等操作

  

 

 1.3、集合

  redis的集合是一种无序集合,集合中的元素是没有先后顺序的

  集合的操作也相当丰富,如添加,删除已有元素,取交集,并集,差集

  

//向集合myset中加入一个新元素"one"
127.0.0.1:6379> sadd myset "one" 
(integer) 1
127.0.0.1:6379> sadd myset "two"
(integer) 1
//列出集合myset中的所有元素
127.0.0.1:6379> smembers myset 
1) "one"
2) "two"
//判断元素1是否在集合myset中,返回1表示存在
127.0.0.1:6379> sismember myset "one" 
(integer) 1
//判断元素3是否在集合myset中,返回0表示不存在
127.0.0.1:6379> sismember myset "three" 
(integer) 0
//新建一个新的集合yourset
127.0.0.1:6379> sadd yourset "1" 
(integer) 1
127.0.0.1:6379> sadd yourset "2"
(integer) 1
127.0.0.1:6379> smembers yourset
1) "1"
2) "2"
//对两个集合求并集
127.0.0.1:6379> sunion myset yourset 
1) "1"
2) "one"
3) "2"
4) "two"

 

 

1.4、有序集合  

  有序集合每个元素都关联一个序号(score),这是排序的标志

  我们将有序集合叫做zset,因为有序集合中的操作都是以z开头的,比如zrange、zadd、zrevrange、zrangebyscore等等 

  

127.0.0.1:6379> zadd myzset 1 baidu.com 
(integer) 1
//向myzset中新增一个元素360.com,赋予它的序号是3
127.0.0.1:6379> zadd myzset 3 360.com 
(integer) 1
//向myzset中新增一个元素google.com,赋予它的序号是2
127.0.0.1:6379> zadd myzset 2 google.com 
(integer) 1
//列出myzset的所有元素,同时列出其序号,可以看出myzset已经是有序的了。
127.0.0.1:6379> zrange myzset 0 -1 with scores 
1) "baidu.com"
2) "1"
3) "google.com"
4) "2"
5) "360.com"
6) "3"
//只列出myzset的元素
127.0.0.1:6379> zrange myzset 0 -1 
1) "baidu.com"
2) "google.com"
3) "360.com"

 

1.5、哈希

  hashes存的是字符串与字符串值之间的映射

  

//建立哈希,并赋值
127.0.0.1:6379> HMSET user:001 username antirez password P1pp0 age 34 
OK
//列出哈希的内容
127.0.0.1:6379> HGETALL user:001 
1) "username"
2) "antirez"
3) "password"
4) "P1pp0"
5) "age"
6) "34"
//更改哈希中的某一个值
127.0.0.1:6379> HSET user:001 password 12345 
(integer) 0
//再次列出哈希的内容
127.0.0.1:6379> HGETALL user:001 
1) "username"
2) "antirez"
3) "password"
4) "12345"
5) "age"
6) "34"

 

2、redis持久化 - 两种方式

  redis提供了两种持久化方式,分别是RDB(又称快照)(Redis DataNase)与AOF(Append Only File)  

  RDB,简而言之,就是在不同的时间点上,将redis存储的数据生成快照,存储到磁盘等介质上

  AOF,就是讲redis执行过的所有写指令记录下来,在一次redis重新启动时,将这些写指令从头到尾执行一遍,就可以将数据恢复过来。

  RDB与AOF也可以同时使用,在这种情况下,如果redis重启的话,会优先使用AOF来进行数据恢复,应为AOF方式数据恢复度最高。如果没有持久化的需求,也可以关闭RDB与AOF,这样redis就变成了一个纯内存数据库。

2.1、RDB

  RDB方式:是将redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方式

  redis在进行持久化的过程中,会将数据先存入一个临时文件中,当持久化结束后,才会将该临时文件替换上次持久化好的文件。正是因为这种特性,我们可以随时进行备份,因为快照文件总是完整可用的。

  对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程不会进行任何的IO操作,这样就保证了redis极高的性能

  如果要进行大规模的数据恢复,且对数据完整性不是很敏感,那么RDB会很适合你

  虽然RDB有很多优点,但是其缺点也是不可忽视的,如果你对数据完整性非常敏感,那么,RDB不适合你,因为RDB每5分钟进行一次备份,如果出现故障,那么会有将近5分钟的数据丢失。所以redis还提供了另一种数据持久化方式--AOF

2.1、AOF

  AOF(Append Only File):即只允许追加,不允许改写的文件

  如前面介绍的那样,AOF就是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序将指令在执行一遍。

  我们通过配置redis.conf中的appendonly yes就可以开启AOF功能,如果有写操作(set)就会被追加到AOF文件中

  默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的性能,即使redis故障,也只会丢失一秒的数据

  如果在追加日志时,碰到磁盘空间满的情况、inode满或断电的情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志的修复

  因为采用了追加方式,如果不做任何处理的话,AOF文件会越来越大,为此,redis提供了AOF文件重写的机制,即当AOF文件的大小超过指定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。如:我们调用了100次incr指令,但是AOF文件中就是要存储100条指令,这明显是很低效的,完全可以将这100条指令合并成一条SET指令,这就是重写机制的原理。

  在进行AOF重写时,仍然是采用先写临时文件,全部完成后再替换的流程,所以在断电、磁盘满等情况都不会影响AOF文件的可用性。

  AOF的另一个好处是:如果你在操作redis时,不小心执行了FLUSHALL命令,导致redis内存中的数据全部清空了,只要配置了AOF,且AOF文件还没有被重写,我们就可以用最快的方式暂停redis并编辑AOF文件,将AOF文件中最后一行的FLUSHALL命令删除,然后重启redis,就可以将redis数据恢复到FLUSHALL命令执行之前。这就是使用AOF进行持久化的好处之一,但是如果AOF文件被重写了,那么就无法通过这种方式来恢复数据。

  然而,AOF也有缺点,例如,在同等数据规模下,AOF文件比RDB文件规模更大,而且,恢复数据的速度也远远慢与RDB。

  如果运气比较差,出现了AOF文件被写坏的情况,也不必过于担忧,redis不会贸然加载这个有问题的文件而是报错退出,这时可以通过以下步骤来修复出错的文件:

  1、备份被写坏的文件

  2、运行redis-check-aof-fix进行修复

  3、用diff-u来看下两个文件的差异,确认问题点

  4、重启redis,加载修复后的文件

 

未完待续

 

 

  

 

posted @ 2018-02-05 13:59  Alighieri  Views(135)  Comments(0Edit  收藏  举报