Redis深度剖析

目录

1,Redis与Memcached的选择

2,使用redis有哪些好处?

3,Redis有哪些数据淘汰机制?

4,Redis的并发竞争问题如何解决?

5,Redis缓存穿透

6,Redis缓存雪崩

7,Redis 分区的优势、不足以及分区类型

8,Redis持久化数据和缓存怎么做扩容?

9,Redis与消息队列

10,Redis 6.0.1

11,Springboot整合Redis


redis

https://tomasonl.lanzous.com/icq55zi       -------------Redis系统学习教材Kuang。

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。

它通常被称为数据结构服务器,数据类型:字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等。

NoSql not only sql 不仅仅是数据库,非关系型数据库。高并发,高负载,高扩展。

Redis是C语言开发的一个 官方50并发执行10万个请求,读11万次/s写8万次/s

 

NoSql not only sql 不仅仅是数据库,非关系型数据库。高并发,高负载,高扩展。

1〉速度快 :内存  单线程  多路复用2〉键值对的数据结构服务器 3〉丰富的功能:

4〉简单稳定5〉持久化6〉主从复制8〉高可用和分布式转移9〉客户端语言多

使用场景:

1,缓存数据库: 2,排行榜 3,计数器应用 4,社交网络 5,消息队列 6,  其它场景等等
key 永远是字符串  value才是各种类型

一般redis插入数据会有个ex 失效时间,雪崩就是 查不到数据 不断反复查询 系统挂了等等

redis高并发会影响到redis速度。但是持久化机制可以改善,redis是一个支持持久化的内存数据库,也就是说redis需要经常将
内存中的数据同步到磁盘来保证持久化,持久化可以避免因进程退出而造成数据丢失

Redis是C语言开发的一个 官方50并发执行10万个请求,读11万次/s写8万次/s

键对存储数据,value5种类型: 字符串string、列表list、集合set、有序集合sort sets、哈希表hash

缓存,在线好友列表,任务队列,数据过期处理

service redis status

redis-cli 打开数据库 redis-cli --raw解决显示乱码

Jedis jedis = new Jedis(host,port);

JedisPool pool = new JedisPool(JedisConfig,host,port)

1.String                常用命令:  set,get,decr,incr,mget 等。

2.Hash                 常用命令: hget,hset,hgetall 等。

3.List                    常用命令:  lpush,rpush,lpop,rpop,lrange等

4.Set                    常用命令: sadd,spop,smembers,sunion 等

5.Sorted Set        常用命令: zadd,zrange,zrem,zcard等

keys                     通用操作            keys pattern          del key1,key2

1,Redis与Memcached的选择

终极策略: 使用Redis的String类型做的事,都可以用Memcached替换,以此换取更好的性能提升; 除此以外,优先考虑Redis; redis单线程 mencached多线程。

2,使用redis有哪些好处?

(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

(2)支持丰富数据类型,支持string,list,set,sorted set,hash

(3) 支持事务,操作原子性,就是对数据的更改要么全部执行,要么全部不执行

(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

3,MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据(redis有哪些数据淘汰策略???)

redis 内存数据集大小上升到一定大小时,执行数据淘汰策略(回收策略)。有6种方式让他体面

1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)把最近最少使用的数据淘汰

2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)把将要过期的数据淘汰

3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)把任意选择数据淘汰

4. allkeys-lru:从数据集(server.db[i].dict)中把最近最少使用的数据淘汰

5. allkeys-random:从数据集(server.db[i].dict)中把任意选择数据淘汰

6. no-enviction(驱逐):禁止驱逐数据

4,Redis的并发竞争问题如何解决?

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法:

 1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。

  2.服务器角度,利用setnx实现锁。

 注:对于第一种,需要应用程序自己处理资源的同步,可以使用的方法比较通俗,可以使用synchronized也可以使用lock;第二种需要用到Redis的setnx命令,但是需要注意一些问题。

Redis回收进程如何工作的? Redis回收使用的是什么算法?

Redis内存回收:LRU算法(写的很不错,推荐):

https://www.cnblogs.com/WJ5888/p/4371647.html

5,Redis缓存穿透

简单来说就是大量请求的Key不在缓存中,请求直接到了数据库而没有经过缓存。

  • 缓存无效的Key。当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个Key 将会从缓存中获取,保护了后端数据源。------但是出现一致性相关问题还有占用内存不能从根本解决。
  • 布隆过滤器判断给定数据是否在海量数据中。把所有可能存在的请求的值都存放在布隆过滤器中。判断没有直接错误信息。

引出-布隆过滤器(确定某个数字在亿级的数据集中)本质是位数组,每个数据只占一位,空间小效率高。但是布隆过滤器查询出某个数据存在,小概率会误判。但是查询某个数据不存在,那么就是一定不存在。

6,Redis缓存雪崩

缓存雪崩是指,缓存层出现了错误,不能正常工作了。所有的请求都会达到存储层,其调用量暴增以致于存储层挂掉。

  • Redis高可用:就是搭建集群。

  • 限流降级:缓存失效后,通过加锁或者队列控制数据库写入缓存线程数量。

  • 数据预热:对多有可能的数据进行预先访问,使部分可能大量访问的数据加载到缓存中。

 

7,Redis 分区的优势、不足以及分区类型

官方文档提供的讲解:

http://www.redis.net.cn/tutorial/3524.html

8,Redis持久化数据和缓存怎么做扩容?

扩容的话可以通过redis集群实现,做项目的时候用过自己搭的redis集群

https://juejin.im/post/5ad54d76f265da23970759d3

Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件

如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

尽量避免在压力很大的主库上增加从库

 

9,Redis与消息队列

不要使用redis去做消息队列,这不是redis的设计目标。但实在太多人使用redis去做去消息队列,redis的作者看不下去,另外基于redis的核心代码,另外实现了一个消息队列disque: antirez/disque:https://github.com/antirez/disque部署、协议等方面都跟redis非常类似,并且支持集群,延迟消息等等。

我在做网站过程接触比较多的还是使用redis做缓存,比如秒杀系统,首页缓存等等。

10,Redis 6.0.1

于----2020 年 5 月 2 日正式发布
 Redis 作者 antirez:这是迄今为止最“企业”化的版本,也是有史以来改动最大的一个 Redis 版本

  • 提供了众多的新模块(modules)API
  • 提供了客户端缓存功能
  • 多线程 I/O 能力
  • 提升了 RDB 日志的加载速度
  • 修改了若干 bug 和一些优化

io性能翻倍:(注:图片来源于 iTushou.com-HULK)

image.png

11,Springboot整合Redis

https://blog.csdn.net/aisu_yan/article/details/84787214
https://blog.csdn.net/c295477887/article/details/52487621 详细参考!

三个方式

Standalone (独立运行模式)

sentinel模式(哨兵模式)

cluster模式(集群模式)

主从模式:是三种集群方式里最简单的。它主要是基于Redis的主从复制特性架构的。通常我们会设置一个主节点,N个从节点;默认情况下,主节点负责处理使用者的IO操作,而从节点则会对主节点的数据进行备份,并且也会对外提供读操作的处理。主要的特点如下:

主从模式下,当某一节点损坏时,因为其会将数据备份到其它Redis实例上,这样做在很大程度上可以恢复丢失的数据。

主从模式下,可以保证负载均衡,这里不再叙说了

主从模式下,主节点和从节点是读写分离的。使用者不仅可以从主节点上读取数据,还可以很方便的从从节点上读取到数据,这在一定程度上缓解了主机的压力。

从节点也是能够支持写入数据的,只不过从从节点写入的数据不会同步到主节点以及其它的从节点下。

从以上,我们不难看出Redis在主从模式下,必须保证主节点不会宕机——一旦主节点宕机,其它节点不会竞争称为主节点,此时,Redis将丧失写的能力。这点在生产环境中,是致命的。

哨兵模式:是基于主从模式做的一定变化,它能够为Redis提供了高可用性。在实际生产中,服务器难免不会遇到一些突发状况:服务器宕机,停电,硬件损坏等。这些情况一旦发生,其后果往往是不可估量的。而哨兵模式在一定程度上能够帮我们规避掉这些意外导致的灾难性后果。其实,哨兵模式的核心还是主从复制。只不过相对于主从模式在主节点宕机导致不可写的情况下,多了一个竞选机制——从所有的从节点竞选出新的主节点。竞选机制的实现,是依赖于在系统中启动一个sentinel进程。

sentinel特点:

监控:它会监听主服务器和从服务器之间是否在正常工作。

通知:它能够通过API告诉系统管理员或者程序,集群中某个实例出了问题。

故障转移:它在主节点出了问题的情况下,会在所有的从节点中竞选出一个节点,并将其作为新的主节点。

提供主服务器地址:它还能够向使用者提供当前主节点的地址。这在故障转移后,使用者不用做任何修改就可以知道当前主节点地址。

sentinel,也可以集群,部署多个哨兵,sentinel可以通过发布与订阅来自动发现Redis集群上的其它sentinel。sentinel在发现其它sentinel进程后,会将其放入一个列表中,这个列表存储了所有已被发现的sentinel。

集群中的所有sentinel不会并发着去对同一个主节点进行故障转移。故障转移只会从第一个sentinel开始,当第一个故障转移失败后,才会尝试下一个。当选择一个从节点作为新的主节点后,故障转移即成功了(而不会等到所有的从节点配置了新的主节点后)。这过程中,如果重启了旧的主节点,那么就会出现无主节点的情况,这种情况下,只能重启集群。

当竞选出新的主节点后,被选为新的主节点的从节点的配置信息会被sentinel改写为旧的主节点的配置信息。完成改写后,再将新主节点的配置广播给所有的从节点。

Redis集群(cluster) Redis 集群是一个提供在多个Redis间节点间共享数据的程序集。

Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误.

Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令. Redis 集群的优势:

自动分割数据到不同的节点上。

整个集群的部分节点失败或者不可达的情况下能够继续处理命令。

Redis 集群的数据分片 Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.

Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:

节点 A 包含 0 到 5500号哈希槽.

节点 B 包含5501 到 11000 号哈希槽.

节点 C 包含11001 到 16384号哈希槽.

这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.

Redis 集群的主从复制模型 为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品.

在我们例子中具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用.

然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了

不过当B和B1 都失败后,集群是不可用的.

Redis 一致性保证 Redis 并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操作.

第一个原因是因为集群是用了异步复制. 写操作过程:

客户端向主节点B写入一条命令.

主节点B向客户端回复命令状态.

主节点将写操作复制给他得从节点 B1, B2 和 B3.

主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。 注意:Redis 集群可能会在将来提供同步写的方法。 Redis 集群另外一种可能会丢失命令的情况是集群出现了网络分区, 并且一个客户端与至少包括一个主节点在内的少数实例被孤立。

举个例子 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, A1 、B1 、C1 为A,B,C的从节点, 还有一个客户端 Z1 假设集群中发生网络分区,那么集群可能会分为两方,大部分的一方包含节点 A 、C 、A1 、B1 和 C1 ,小部分的一方则包含节点 B 和客户端 Z1 .

Z1仍然能够向主节点B中写入, 如果网络分区发生时间较短,那么集群将会继续正常运作,如果分区的时间足够让大部分的一方将B1选举为新的master,那么Z1写入B中得数据便丢失了.

注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项:

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Thompson

相互学习,欢迎指正。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值