redis基础,优缺点、适合场景、数据淘汰/删除策略、持久化三种方案、并发处理

什么是Redis?简述它的优缺点?

Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。
优点:纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。
缺点:Redis的数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

为什么使用redis?而不是mysql或者memcached

与mysql对比:直接将数据存储在内存,避免了磁盘IO,存取值很迅速
与memcatched对比:

  • 支持的数据类型更丰富,string,list,hash,set,sortedset
  • 存取值更迅速,底层数据结构不同
  • 有虚拟内存,内存不够时,将不常用数据持久化到磁盘中
  • 数据更安全,因为会定期持久化
  • 支持数据恢复,提供了aof技术,即将所有的操作记录都会存入到一个文件中,可以根据该文件进行数据恢复

Redis适用场景?

1缓存热数据
数据经常被使用,而且不会修改不频繁。典型的就是查询前先从redies中查询,有的话使用redis数据,放弃select数据库,没有的话,select 数据库,然后将数据插入redis。注意如果更新的话,需要先更新库中,再操作redies。因为高并发的情况请注意下面场景:
为了update先删掉了redis中的该数据,这时候另一个线程执行查询,发现redis中没有,瞬间执行了查询SQL,并且插入到redis中一条数据,回到刚才那个update语句,这个悲催的线程压根不知道刚才那个该死的select线程犯了一个弥天大错!于是这个redis中的错误数据就永远的存在了下去,直到下一个update或者delete
2计数器
诸如统计点击数等应用。由于单线程,可以避免并发问题,保证不会出错,而且100%毫秒级性能!
命令:INCRBY
3队列
相当于消息系统,ActiveMQ,RocketMQ等工具类似,但是个人觉得简单用一下还行,如果对于数据一致性要求高的话还是用RocketMQ等专业系统。
4最新列表
例如新闻列表页面最新的新闻列表,如果总数量很大的情况下,尽量不要使用select a from A limit 10这种low货,尝试redis的 LPUSH命令构建List,一个个顺序都塞进去就可以啦。不过万一内存清掉了咋办?也简单,查询不到存储key的话,用mysql查询并且初始化一个List到redis中就好了。
5排行榜
谁得分高谁排名往上。命令:ZADD(有续集,sorted set)

redis移除数据的逻辑是什么?

这个问题有三种可能的答案,它们分别代表了三种不同的删除策略:
定时删除:在设置键的过期时间的同时,创建一个定时器( timer )让定时器在键的过期时间来临时,立即执行对键的删除操作。
惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
定期删除: 每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库, 则由算法决定。

怎么理解Redis事务?事务相关的命令有哪几个?

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
事务相关的命令:MULTI、EXEC、DISCARD、WATCH

Redis有哪几种数据淘汰策略?

MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?
redis内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。

  • noeviction:返回错误,当内存限制达到最大内存限制时, 如果需要更多内存, 直接返回错误信息。
  • allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
  • allkeys-random: 回收随机的键使得新添加的数据有空间存放。
  • volatile-random:在设置了过期时间的键中,随机回收数据。
  • volatile-ttl: 在设置了过期时间的键中,优先回收存活时间(TTL)较短的键。
  • volatile-lru: 在设置了过期时间的键中,尝试回收最少使用的键(LRU)。

笔试题:
某缓存系统采用LRU淘汰算法,假定缓存容量为4,并且初始为空,那么在顺序访问一下数据项的时候:1,5,1,3,5,2,4,1,2出现缓存直接命中的次数是?,最后缓存中即将准备淘汰的数据项是?
答案:3, 5
解答:
1调入内存 1
5调入内存 1 5
1调入内存 5 1(命中 1,更新次序)
3调入内存 5 1 3
5调入内存 1 3 5 (命中5)
2调入内存 1 3 5 2
4调入内存(1最久未使用,淘汰1) 3 5 2 4
1调入内存(3最久未使用,淘汰3) 5 2 4 1
2调入内存 5 4 1 2(命中2)

Redis哈希槽的概念?

Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽,所以集群最多16384个,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。假设有两台机器,那么第一台机器负责0-8192,第二台负责8193-16384

Redis中的管道有什么用?

一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应。这样就可以将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复。这就是管道(pipelining),是一种几十年来广泛使用的技术。例如许多POP3协议已经实现支持这个功能,大大加快了从服务器下载新邮件的过程。

Redis如何做内存优化?

尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面。

Redis回收进程如何工作的?

一个客户端运行了新的命令,添加了新的数据。Redi检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收。一个新的命令被执行,等等。所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越

redis持久化的几种方式

1、快照(snapshots)
  缺省情况情况下,Redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb。你可以配置Redis的持久化策略,例如数据集中每N秒钟有超过M次更新,就将数据写入磁盘;或者你可以手工调用命令SAVE或BGSAVE。
  工作原理
  . Redis forks.
  . 子进程开始将数据写到临时RDB文件中。
  . 当子进程完成写RDB文件,用新文件替换老文件。
  . 这种方式可以使Redis使用copy-on-write技术。
2、AOF
  快照模式并不十分健壮,当系统停止,或者无意中Redis被kill掉,最后写入Redis的数据就会丢失。这对某些应用也许不是大问题,但对于要求高可靠性的应用来说,Redis就不是一个合适的选择。Append-only文件模式是另一种选择。你可以在配置文件中打开AOF模式
3、虚拟内存方式
  当你的key很小而value很大时,使用VM的效果会比较好.因为这样节约的内存比较大.

redis常见性能问题和解决方案:   
   1).Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。
   2).Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
   3).Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。
   4). Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内
Aof和快照选择:
Aof保证数据完整性,但是效率略低;快照效率稍高,但是可能会丢失部分数据。


Redis是单进程单线程的:
   redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销

redis的并发竞争问题如何解决?

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法:
   1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。
   2.服务器角度,利用setnx实现锁。
   注:对于第一种,需要应用程序自己处理资源的同步,可以使用的方法比较通俗,可以使用synchronized也可以使用lock;第二种需要用到Redis的setnx命令,但是需要注意一些问题。
 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值