博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis学习
阅读量:4166 次
发布时间:2019-05-26

本文共 4618 字,大约阅读时间需要 15 分钟。

1、为什么使用redis

(一)性能

     我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。

这样,后面的请求就去缓存中读取,使得请求能够迅速响应。

(二)并发

      在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常

这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。

2、单线程的redis为什么这么快

redis是单线程工作模型:

(一) 纯内存操作
(二) 单线程操作,避免了频繁的上下文切换
(三) 采用了非阻塞I/O多路复用机制

3、redis的数据类型,以及每种数据类型的使用场景

(一) String

这个其实没啥好说的,最常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。

(二) hash

这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果

(三) list

使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。本人还用一个场景,很合适---取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则。

(四) set

因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。
另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。

(五) sorted set

sorted set多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作。

4、redis的过期策略以及内存淘汰机制

redis采用的是 定期删除+惰性删除策略

为什么不用定时删除策略?

定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源

在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.

定期删除,redis默认每隔100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。

于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下这个key是否过期了?如果过期了此时就会删除。

如果定期删除没删除key。然后也没有即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制

在 redis.conf 中有一行配置

# maxmemory-policy volatile-lru

该配置就是配内存淘汰策略的。

1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错

2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key推荐使用

3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key

4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐   // TODO 为什么不用这个???

5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。依然不推荐

6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐

ps:如果没有设置 expire 的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。 

6、redis和数据库双写一致性问题

     数据库和缓存双写,就必然会存在不一致的问题。如果对数据有强一致性要求,不能放缓存我们所做的一切,只能保证最终一致性。另外,我们所做的方案其实从根本上来说,只能说降低不一致发生的概率,无法完全避免。因此,有强一致性要求的数据,不能放缓存。

首先,采取正确更新策略:先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。

Redis中数据存储模式有两种:cache-only以及persistence

cache-only: 只作为"缓存"服务,不提供数据的持久化操作,数据在服务停止后消失,因此在此模式下也不存在数据恢复的问题,该模式的优点是效率高,容易扩展,缺点是安全性较低。

persistence:该模式下将内存中的数据持久化到磁盘文件,服务重启后数据可以恢复,优点是相对安全。

对于persistence持久化存储,Redis提供了两种方式:

Redis Database 简称(RDB)  以及   Append-only file 简称(AOF)

RDB

RDB是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。

优点:使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能

缺点:RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候

执行数据写入到临时文件的时间点是可以通过配置来自己确定的,通过配置redis在n秒内如果超过m个key被修改就执行一次RDB操作。这个操作就类似于在这个时间点来保存一次Redis的所有数据,一次快照数据。所有这个持久化方法也通常叫做 snapshots。

RDB默认开启redis.conf 中的具体配置参数如下 :

# dbfilename:持久化数据存储在本地的文件dbfilename dump.rdb# dir:持久化数据存储在本地的路径,如果是在/redis/redis-3.0.6/src下启动的redis-cli,则数据会存储在当前src目录下dir ./## snapshot触发的时机,save 
## 如下为900秒后,至少有一个变更操作,才会snapshot ## 对于此值的设置,需要谨慎,评估系统的变更操作密集程度 ## 可以通过“save “””来关闭snapshot功能 # save时间: 更改了1个key时间隔900s进行持久化存储;save 900 1# save时间: 更改了10个key300s进行存储;save 300 10# save时间: 更改10000个key60s进行存储。save 60 10000## 当snapshot时出现错误无法继续时,是否阻塞客户端“变更操作”,“错误”可能因为磁盘已满/磁盘故障/OS级别异常等 stop-writes-on-bgsave-error yes ## 是否启用rdb文件压缩,默认为“yes”,压缩往往意味着“额外的cpu消耗”,同时也意味这较小的文件尺寸以及较短的网络传输时间 rdbcompression yes

snapshot 触发的时机,是有“间隔时间”和“变更次数”共同决定,同时符合2个条件才会触发snapshot, 否则“变更次数”会被继续累加到下一个“间隔时间”上。snapshot过程中并不阻塞客户端请求。snapshot首先将数据写入临时文件,当成功结束后,将临时文件重名为dump.rdb。

使用RDB恢复数据:自动的持久化数据存储到dump.rdb后。实际只要重启redis服务即可完成(启动redis的server时会从dump.rdb中先同步数据)

AOF默认关闭,开启方法,修改配置文件 reds.confappendonly yes

##此选项为aof功能的开关,默认为“no”,可以通过“yes”来开启aof功能  ##只有在“yes”下,aof重写/文件同步等特性才会生效  appendonly yes  ##指定aof文件名称  appendfilename appendonly.aof  ##指定aof操作中文件同步策略,有三个合法值:always everysec no,默认为everysec  appendfsync everysec  ##在aof-rewrite期间,appendfsync是否暂缓文件同步,"no"表示“不暂缓”,“yes”表示“暂缓”,默认为“no”  no-appendfsync-on-rewrite no  ##aof文件rewrite触发的最小文件尺寸(mb,gb),只有大于此aof文件大于此尺寸是才会触发rewrite,默认“64mb”,建议“512mb”  auto-aof-rewrite-min-size 64mb  ##相对于“上一次”rewrite,本次rewrite触发时aof文件应该增长的百分比。  ##每一次rewrite之后,redis都会记录下此时“新aof”文件的大小(例如A),那么当aof文件增长到A*(1 + p)之后  ##触发下一次rewrite,每一次aof记录的添加,都会检测当前aof文件的尺寸。  auto-aof-rewrite-percentage 100

AOF和RDB各有优缺点,这是有它们各自的特点所决定:

        1) AOF更加安全,可以将数据更加及时的同步到文件中,但是AOF需要较多的磁盘IO开支,AOF文件尺寸较大,文件内容恢复数度相对较慢。
        2) snapshot安全性较差,它是“正常时期”数据备份以及master-slave数据同步的最佳手段,文件尺寸较小,恢复数度较快。

可以通过配置文件来指定它们中的一种,或者同时使用它们(不建议同时使用),或者全部禁用

        在架构良好的环境中,master 通常使用 AOF,slave 使用 snapshot,主要原因是

master需要首先确保数据完整性,它作为数据备份的第一选择;

slave提供只读服务(目前slave只能提供读取服务),它的主要目的就是快速响应客户端read请求;

        但是如果你的redis运行在网络稳定性差/物理环境糟糕情况下,建议你master和slave均采取AOF,这个在master和slave角色切换时,可以减少“人工数据备份”/“人工引导数据恢复”的时间成本;

        如果你的环境一切非常良好,且服务需要接收密集性的write操作,那么建议master采取snapshot,而slave采用AOF。

 

 

 

 

 

 

 

 

 

转载地址:http://jkgxi.baihongyu.com/

你可能感兴趣的文章
leetcode 97 Interleaving String(python)
查看>>
leetcode 92 Reverse Linked List II
查看>>
leetcode 78 Subsets
查看>>
leetcode 90 Subsets II
查看>>
leetcode 91 Decode Ways
查看>>
leetcode 89 Gray Code
查看>>
leetcode 88 Merge Sorted Array
查看>>
leetcode 87 Scramble String(递归+剪枝)
查看>>
win10系统下“python不是内部或外部命令”的解决方法
查看>>
Python的优缺点
查看>>
python中如何区分常量和变量
查看>>
python导入模块的4种方法
查看>>
linux more命令简单使用
查看>>
vi 编辑器超级简单且实用的命令
查看>>
python多行注释和跨行字符串
查看>>
linux终端输出彩色字体
查看>>
一个程序学会python的流程控制
查看>>
python中sys.exit() os._exit() exit() quit()的简单使用
查看>>
linux rm -f rm -rf 命令:删除文件和文件夹
查看>>
ubuntu-14.04.3下安装VMware Tools(虚拟机与主机之间直接复制粘贴)
查看>>