你懂redis吗

 

1、redis简介node

  Redis是当前比较热门的NOSQL系统之一,它是一个开源的使用ANSI c语言编写的key-value存储系统(区别于MySQL的二维表格的形式存储。)。和Memcache相似,但很大程度补偿了Memcache的不足。和Memcache同样,Redis数据都是缓存在计算机内存中,不一样的是,Memcache只能将数据缓存到内存中,没法自动按期写入硬盘,这就表示,一断电或重启,内存清空,数据丢失。因此Memcache的应用场景适用于缓存无需持久化的数据。而Redis不一样的是它会周期性的把更新的数据写入磁盘或者把修改操做写入追加的记录文件,实现数据的持久化。redis

 

2、redismeamache区别数据库

一、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其余东西,例如图片、视频等等。缓存

二、Redis不只仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。安全

三、虚拟内存--Redis当物理内存用完时,能够将一些好久没用到的value 交换到磁盘服务器

四、存储数据安全--memcache挂掉后,数据没了;redis能够按期保存到磁盘(持久化)网络

五、灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后能够经过aof恢复session

六、Redis支持数据的备份,即master-slave模式的数据备份。数据结构

 

3、redis为何这么快架构

一、纯内存操做;

二、单线程操做,避免了频繁的上下文切换;

三、采用C语言编写,而C语言因为更加接近计算机的底层,因此速度更快;

四、采用了非阻塞I/O多路复用机制: 咱们的redis-client在操做的时候,会产生具备不一样事件类型的socket。在服务端,有一段I/0多路复用程序,将其置入队列之中。而后,文件事件分派器,依次去队列中取,转发到不一样的事件处理器中。

 

4、redis的应用场景

一、缓存

二、任务队列

三、网站访问统计

四、数据过时处理

五、应用排行榜

六、分布式集群架构中的session分离

 

5、redis的数据类型

Redis一共支持五种数据类:string(字符串),hash(哈希),list(列表),set(集合)和zset(sorted set有序集合)。

一、String:

经常使用命令:set(赋值)/get(查询)/decr (自减)/incr(自增)/mget(查询多个key)

这个其实没啥好说的, value能够是String也能够是数字。通常作一些复杂的计数功能的缓存。

 

二、hash

命令:hset(添加赋值)/hget(查询)/hgetall(查询全部字段和值)等。

这里value存放的是结构化的对象,比较方便的就是操做其中的某个字段。

 

三、list

经常使用命令:lpush(列表头部添加元素)/rpush(列表尾部添加元素)/lpop(头部删除元素)/rpop(尾部删除元素)/lrange(查询元素)等.

Redis列表是字符串列表,不支持嵌套其余数据类型,是redis中有序可重复结构。能够向列表的头部或者尾部进行添加和删除操做;应用的场景很是多,好比存储文章评论列表,存储用户的粉丝列表,黑名单列表等,也能够做为重要的消息队列来使用。

 

四、set

经常使用命令有sadd(添加元素)/spop(删除)/smembers(查询)/sunion(添加多个集合)等,基本示例以下所示。

使用:Redis集合是字符串集合,不支持嵌套其余数据类型,不重复无序结构。与list的功能类似,可是提供了自动去重功能,而且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。另外,就是利用交集、并集、差集等操做,能够计算共同喜爱,所有的喜爱,本身独有的喜爱等功能。

 

五、sorted set

使用:Redis有序集合是在集合的基础上增长了排序功能,规则是按照该元素对应的Score进行排序。实际应用来说主要是涉及到排序的功能场景均可以使用,例如实现文章按点击量排序,微博热搜榜,论坛热帖等。sorted set多了一个权重参数score,集合中的元素可以按score进行排列。能够作排行榜应用,取TOP N操做。sorted set在set基础上为每一个元素都关联了一个分数score,经过score来实现排序功能。经常使用命令:zadd/zrange/zrem/zcard,

 

6、redis的缺点

实际上是缓存都有下面四个问题,通常的企业,说实话,缓存雪崩、缓存击穿很能遇到。

一、缓存和数据库双写一致性问题

二、缓存雪崩问题: 缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而致使数据库链接异常。

解决方案:

a、给缓存的失效时间,加上一个随机值,避免集体失效。

b、使用互斥锁,可是该方案吞吐量明显降低了。

c、双缓存。咱们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。本身作缓存预热操做。而后细分如下几个小点

I 从缓存A读数据库,有则直接返回

II A没有数据,直接从B读数据,直接返回,而且异步启动一个更新线程。

III 更新线程同时更新缓存A和缓存B。

三、缓存击穿问题: 请求缓存中不存在的数据,致使全部的请求都怼到数据库上,从而数据库链接异常。

解决方案:

a、利用互斥锁,缓存失效的时候,先去得到锁,获得锁了,再去请求数据库。没获得锁,则休眠一段时间重试

b、采用异步更新策略,不管key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存若是过时,异步起一个线程去读数据库,更新缓存。须要作缓存预热(项目启动前,先加载缓存)操做。

c、提供一个能迅速判断请求是否有效的拦截机制,好比,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。若是不合法,则直接返回。

四、缓存的并发竞争问题

 

7、redis的持久化

  redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。其实RDB和AOF两种方式也能够同时使用,在这种状况下,若是redis重启的话,则会优先采用AOF方式来进行数据恢复,这是由于AOF方式的数据恢复完整度更高。若是你没有数据持久化的需求,也彻底能够关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache同样。

一、RDB

  RDB方式,是将redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方法。redis在进行数据持久化的过程当中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是这种特性,让咱们能够随时来进行备份,由于快照文件老是完整可用的。对于RDB方式,redis会单首创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操做的,这样就确保了redis极高的性能。若是须要进行大规模数据的恢复,且对于数据恢复的完整性不是很是敏感,那RDB方式要比AOF方式更加的高效。

  虽然RDB有很多优势,但它的缺点也是不容忽视的。若是你对数据的完整性很是敏感,那么RDB方式就不太适合你,由于即便你每5分钟都持久化一次,当redis故障时,仍然会有近5分钟的数据丢失。因此,redis还提供了另外一种持久化方式,那就是AOF。

 

二、AOF

  AOF,英文是Append Only File,即只容许追加不容许改写的文件。如前面介绍的,AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍,就这么简单。咱们经过配置redis.conf中的appendonly yes就能够打开AOF功能。若是有写操做(如SET等),redis就会被追加到AOF文件的末尾。默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),由于在这种状况下,redis仍然能够保持很好的处理性能,即便redis故障,也只会丢失最近1秒钟的数据。若是在追加日志时,刚好遇到磁盘空间满、inode满或断电等状况致使日志写入不完整,也没有关系,redis提供了redis-check-aof工具,能够用来进行日志修复。由于采用了追加方式,若是不作任何处理的话,AOF文件会变得愈来愈大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留能够恢复数据的最小指令集。举个例子或许更形象,假如咱们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,彻底能够把这100条指令合并成一条SET指令,这就是重写机制的原理。在进行AOF重写时,仍然是采用先写临时文件,所有完成后再替换的流程,因此断电、磁盘满等问题都不会影响AOF文件的可用性,这点你们能够放心。

   AOF方式的另外一个好处,咱们经过一个“场景再现”来讲明。某同窗在操做redis时,不当心执行了FLUSHALL,致使redis内存中的数据所有被清空了,这是很悲剧的事情。不过这也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件尚未被重写(rewrite),咱们就能够用最快的速度暂停redis并编辑AOF文件,将最后一行的FLUSHALL命令删除,而后重启redis,就能够恢复redis的全部数据到FLUSHALL以前的状态了。是否是很神奇,这就是AOF持久化方式的好处之一。可是若是AOF文件已经被重写了,那就没法经过这种方法来恢复数据了。

  虽然优势多多,但AOF方式也一样存在缺陷,好比在一样数据规模的状况下,AOF文件要比RDB文件的体积大。并且,AOF方式的恢复速度也要慢于RDB方式。若是你直接执行BGREWRITEAOF命令,那么redis会生成一个全新的AOF文件,其中便包括了能够恢复现有数据的最少的命令集。若是运气比较差,AOF文件出现了被写坏的状况,也没必要过度担心,redis并不会贸然加载这个有问题的AOF文件,而是报错退出。这时能够经过如下步骤来修复出错的文件:

1).备份被写坏的AOF文件

2).运行redis-check-aof –fix进行修复

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

4).重启redis,加载修复后的AOF文件

 

8、redis的主从复制

  像MySQL同样,redis是支持主从同步的,并且也支持一主多从以及多级从结构。主从结构,一是为了纯粹的冗余备份,二是为了提高读性能,好比很消耗性能的SORT就能够由从服务器来承担。redis的主从同步是异步进行的,这意味着主从同步不会影响主逻辑,也不会下降redis的处理性能。主从架构中,能够考虑关闭主服务器的数据持久化功能,只让从服务器进行持久化,这样能够提升主服务器的处理性能。在主从架构中,从服务器一般被设置为只读模式,这样能够避免从服务器的数据被误修改。可是从服务器仍然能够接受CONFIG等指令,因此仍是不该该将从服务器直接暴露到不安全的网络环境中。若是必须如此,那能够考虑给重要指令进行重命名,来避免命令被外人误执行。

  主从复制的原理:从服务器会向主服务器发出SYNC指令,当主服务器接到此命令后,就会调用BGSAVE指令来建立一个子进程专门进行数据持久化工做,也就是将主服务器的数据写入RDB文件中。在数据持久化期间,主服务器将执行的写指令都缓存在内存中。在BGSAVE指令执行完成后,主服务器会将持久化好的RDB文件发送给从服务器,从服务器接到此文件后会将其存储到磁盘上,而后再将其读取到内存中。这个动做完成后,主服务器会将这段时间缓存的写指令再以redis协议的格式发送给从服务器。另外,要说的一点是,即便有多个从服务器同时发来SYNC指令,主服务器也只会执行一次BGSAVE,而后把持久化好的RDB文件发给多个下游。在redis2.8版本以前,若是从服务器与主服务器因某些缘由断开链接的话,都会进行一次主从之间的全量的数据同步;而在2.8版本以后,redis支持了效率更高的增量同步策略,这大大下降了链接断开的恢复成本。

  主服务器会在内存中维护一个缓冲区,缓冲区中存储着将要发给从服务器的内容。从服务器在与主服务器出现网络瞬断以后,从服务器会尝试再次与主服务器链接,一旦链接成功,从服务器就会把“但愿同步的主服务器ID”和“但愿请求的数据的偏移位置(replication offset)”发送出去。主服务器接收到这样的同步请求后,首先会验证主服务器ID是否和本身的ID匹配,其次会检查“请求的偏移位置”是否存在于本身的缓冲区中,若是二者都知足的话,主服务器就会向从服务器发送增量内容。增量同步功能,须要服务器端支持全新的PSYNC指令。这个指令,只有在redis-2.8以后才具备。

相关文章
相关标签/搜索