redis想必大家用的不少,下面为大家详细介绍下:
一、Redis的五种数据类型
- strings(字符串)
a) 如果只使用redis中的字符串类型,且不使用redis的持久化功能,那么,redis就和memcache非常非常的像了;
b) 在遇到数值操作时,会自动转换过为字符串,如写入数字1,读出来将是字符串1;
c) 本身具有原子性的指令:incr、decr和Memecached中increment、decrement类似;
d) 应用场景:常规计数-微博数, 粉丝数;
- lists(列表)
a) lists数据类型的实现不是数组而是通过链表这种数据结构实现;
b) 使用Lists结构,我们可以轻松地实现最新消息排行等功能。Lists的另一个应用就是消息队列,可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行;
c) 每个子元素都是String类型的双向链表,可以通过push和pop操作从列表的头部或者尾部添加或者删除元素,这样List即可以作为栈,也可以作为队列;
- sets(无序集合)
a) 所谓集合就是一堆不重复值的组合,并且是没有顺序的;
b) 在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
- sorted sets(有序集合)
a) 和Sets相比,Sorted Sets增加了一个权重参数score,使得集合中的元素能够按score进行有序排列;
b) 比如一个存储全班同学成绩的Sorted Sets,其集合value可以是同学的学号,而score就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。可以用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。
c) 应用场景:在线游戏的排行榜,根据得分你通常想要:
- 列出前100名高分选手
- 列出某用户当前的全球排名
- hashes(哈希)
a) 在Memcached中,我们经常将一些结构化的信息打包成hashmap,在客户端序列化后存储为一个字符串的值,比如用户的昵称、年龄、性别、积分等,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。
b) 应用场景:存储部分变更数据,如用户信息,session共享;
二、Redis的持久化
- RDB
a) 简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;
b) 对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了redis极高的性能。
c) 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
d) 如果你对数据的完整性非常敏感,那么RDB方式就不太适合你,因为即使你每5分钟都持久化一次,当redis故障时,仍然会有近5分钟的数据丢失。
- AOF
a) 将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
b) 默认的AOF持久化策略是每秒钟fsync一次;
c) AOF在文件中采用追加方式来写入,因此不做任何处理的话,AOF文件会变得越来越大,为此,redis提供了AOF文件重写(rewrite)机制,当AOF文件的大小超过所设定的值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。假如我们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,完全可以把这100条指令合并成一条SET指令,这就是重写机制的原理。
- RDB和AOF的区别:
a) RDB方式存的是数据,AOF方式存的是指令;
b) RDB和AOF可以同时使用,在这种情况下,如果redis重启的话,会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。
c) 同样数据规模的情况下,AOF文件要比RDB文件的体积大。而且,AOF方式的恢复速度也要慢于RDB方式。
- AOF重写原理:
a) 首先,当重写开始时,创建一个重写子进程;
b) 子进程读取现有AOF文件中的指令解析并压缩至一个临时文件中;
c) 同时主进程接收到新的写指令时,一边继续向AOF文件中写入,以保证原有AOF文件的可用性,避免重写过程中发生意外,一边向内存缓冲区中写入;
d) 当子进程完成重写任务后,想主进程发送信号,主进程接收到信号后将内存缓冲区中新的写指令追加到新的AOF文件中;
e) 追加结束后,会用新的AOF文件替换旧的AOF文件,至此,重写结束;
三、Redis的主从:
- 主从结构,一是为了纯粹的冗余备份,二是为了提升读性能,比如很消耗性能的SORT就可以由从服务器来承担。
- redis的主从同步是异步进行的,这意味着主从同步不会影响主逻辑,也不会降低redis的处理性能。
- 主从架构中,可以考虑关闭主服务器的数据持久化功能,只让从服务器进行持久化,这样可以提高主服务器的处理性能。
四、Redis主从同步原理:
- 从服务器向主服务器发送sync指令,主服务器接到后,调用bgsave指令创建子进程将主服务器的数据写入RDB文件中,该过程中,主服务器会将新接收到的写的指令缓存在内存中;
- bgsave指令结束后,主服务器将RDB文件发送至从服务器,从服务器接收到后存在磁盘上,然后读取到内存中。然后主服务器会将该时间段内缓存的写的指令以redis协议格式发送至从服务器;
- 如果有多个从服务发送过来sync指令,主服务器只会执行一次bgsave,然后将持久化好的RDB文件发送给多个从服务器;
- redis2.8版本之前,如果同步过程断开,再次连接后会再进行一次全数据同步,2.8版本之后增减的增量同步机制;
- 缓冲区内容的同步
- 增量同步功能,需要服务器端支持全新的PSYNC指令。这个指令,只有在redis-2.8之后才具有;
五、Redis的事务:
- 事务的指令:MULTI、EXEC、DISCARD、WATCH;
- MULTI 用来组装一个事务,即开启事务;
- EXEC用来执行一个事务;
- DISCARD用来取消一个事务;
- WATCH用来监视一些key,一旦这些key在事务执行之前被改变,则取消事务的执行。
六、事务的相关:
- 如果开启了AOF,事务执行成功后,事务中的命令就会一次性写入磁盘中,如果该过程中刚好断电或者其他导致无法写入的问题时,会出现只有部分命令持久化,AOF文件不完整的情况,这是可以使使用redis-check-aof工具来修复这一问题,这个工具会将AOF文件中不完整的信息移除,确保AOF文件完整可用;
- 调用EXEC之前的报错:可能是由于语法错误,也有可能是内存不足导致;如果出现某个命令无法写入缓冲队列,redis会进行记录,当执行exec是2.6.5版本之前会拒绝执行,2.6.5版本之后会忽略失败的命令来执行;
- 调用EXEC之后的报错:redis不会理睬报错,继续往下执行;
- 关于watch:类似于乐观锁,用来监视,可以同时监视多个key。事务开始之前,一旦监视的某个key被修改了,执行事务时会显示无法执行;