- A+
1. Redis缓存
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
它是基于高性能的Key-Value、并提供多种语言的 API的非关系型数据库。不过与传统数据库不同的是 redis 的数据是存在内存中的,所以存写速度非常快。
它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)
2. 为什么需要使用缓存
说明:使用缓存可以有效的降低用户访问物理设备的频次,有效的减少并发的压力。保护后端真实的服务器。
主要从“高性能”和“高并发”两点来看:
2.1高性能
2.2高并发
直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。
3.Redis的架构模式
3.1 主从模式
Redis的复制功能允许用户根据一个Redis服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。
特点:
1、master/slave 角色
2、master/slave 数据相同
3、降低 master 读压力在转交从库
问题:
1、无法保证高可用
2、没有解决 master 写的压力
3.2 哨兵模式
Redis sentinel 是一个分布式系统中监控Redis主从服务器,并在主服务器下线时自动进行故障转移。
它具备三个特征:监控、提醒、自动故障迁移。
特点:
1、保证高可用
2、监控各个节点
3、自动故障迁移
缺点:
1、主从模式,切换需要时间丢数据
2、没有解决 master 写的压力
3.3 分片模式
虽然redis可以扩展内存空间的大小。但是如果需要存储海量的数据一味的扩大内存,其实效率不高。
分片介绍: 准备多台redis,共同为用户提供缓存服务。在保证效率的前提下,实现了内存的扩容。用户在使用分片机制时,将多台redis当做1台使用。
**1.那么数据是依据什么算法存储到Redis分片缓存中的呢?
一致性哈希算法(下文介绍)
**2.关于redis分片总结
1)当redis节点宕机之后,用户访问必然受到影响,该节点中的数据可能丢失
2)redis分片可以实现内存数据的扩容
3)redis分片机制中hash运算发生在业务服务器中,redis只负责存取,不负责计算,所以效率高。
3.4 集群模式
从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
特点:
1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。
2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。
4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本
5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。
缺点:
1、资源隔离性较差,容易出现相互影响的情况。
2、数据通过异步复制,不保证数据的强一致性
4.一致性Hash算法介绍
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 。
4.1 一致性Hash原理
目的:解决数据如何在分布式环境下进行存储
hash取值区间:8位16进制数 共有2^32种可能性
1)数据如何存储
2)当节点发生变化时,节点中的对应的数据可以动态的迁移。
原则:当发生了节点变化时,应该尽可能小的影响其他节点。
4.2 一致性Hash特征
一致性哈希算法是在哈希算法基础上提出的,在动态变化的分布式环境中,哈希算法应该满足的几个条件:
①平衡性(均衡性)是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题。利用虚拟节点实现数据平衡(相对而已的平均)
②单调性是指在新增或者删除节点时,不影响系统正常运行,可以实现动态的数据迁移。
③分散性是指数据应该分散地存放在分布式集群中的各个节点,不必每个节点都存储所有数据。
5.Hash槽算法介绍
RedisCluster采用此分区,所有的键根据哈希函数(CRC16[key]%16384)映射到0 - 16383槽内,工16384个槽位,每个节点维护部分槽及槽所映射的键值数据。根据主节点的个数,均衡划分区间。
哈希函数:Hash()=CRC16[key]%16384
如图所示:
当redis集群中插入数据时,首先将key进行计算,之后将计算结果匹配到具体的某一个槽的区间内,之后再将数据set到管理该槽的节点中。
如图所示:
6.Redis的持久化策略
Redis的数据都保存在内存中,如果断电或者宕机,则内存数据将擦除,导致数据的丢失。为了防止数据丢失,Redis内部有持久化机制。
当第一次Redis服务启动时,根据配置文件中的持久化要求,进行持久化操作。如果不是第一次启动,则在服务启动时会根据持久化文件的配置,读取指定的持久化文件,实现内存数据的恢复。
6.1 RDB模式
特点:
1.rdb模式是redis中默认的持久化策略。
2.rdb模式定期持久化。保存的是Redis中的内存数据快照,持久化文件占用空间较小。
3.rdb模式可能导致内存数据丢失。
前提:需要在redis的客户端中执行.
1.save 命令 立即持久化,会导致其他操作陷入阻塞.
2.bgsave 命令 开启后台运行。 以异步的方式进行持久化,不会造成其他操作的阻塞。
6.2 AOF模式
特点:
1.AOF模式默认条件下是关闭状态.。如果需要开启则需要修改配置文件。
2.AOF模式可以实现数据的实时持久化操作,AOF模式记录的是用户的操作过程。
3.只要开启了AOF模式,则持久化方式以AOF模式为主。
6.3 持久化总结
1.如果用户允许少量的数据丢失,则可以选用RDB模式. 效率更高
2.如果用户不允许数据丢失,则选用AOF模式.
3.可以2种方式都选, 需要搭建组从结构 , 主机选用RDB模式, 从机选用AOF模式,可以保证业务允许.
7.Redis的内存策略
redis服务器运行在内存中,数据也在内存中保存。 如果一直往里存,总有一天内存资源不够用,所以需要研究如何优化内存。
7.1 LRU算法
维度:时间
LRU(Least Recently Used)即最近最少使用,是一种常见的页面(数据)置换算法,选择最近最久未使用的页面(数据)予以淘汰。该算法赋予每个页面(数据)一个访问字段,用来记录一个页面(数据)自上次被访问以来所经历的时间t,当必须淘汰一个页面(数据)时,选择现有页面(数据)中其t值最大的,即最近最少使用的页面(数据)予以淘汰。
7.2 LFU算法
维度:引用次数
LFU(least frequently used (LFU) page-replacement algorithm)。即最不经常使用页置换算法,要求在页置换时置换引用计数最小的页,因为经常使用的页应该有一个较大的引用次数。但是有些页在开始时使用次数很多,但以后就不再使用,这类页将会长时间留在内存中,因此可以将引用计数寄存器定时右移一位,形成指数衰减的平均使用次数。
7.3 随机算法
灭霸响指,随机删除页面(数据)
7.4 TTL算法
将设定了超时时间的数据提前删除
7.5 Redis中内存优化策略
volatile-lru 设定超时时间的数据采用lru算法
allkeys-lru .所有的数据采用lru算法
volatile-lfu设定超时时间的数据采用LFU算法 .
allkeys-lfu 所有的数据才能lfu算法
volatile-random设定了超时时间的数据采用随机算法
allkeys-random 所有数据采用随机算法
volatile-ttl设定超时时间的数据采用TTL算法
noeviction 该配置为模式配置 表示内存满时 只报错,不删除数据.
8.Redis的数据类型及其应用场景
一)String 常用命令: set,get,decr,incr,mget 等。
最常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。
二)hash 常用命令: hget,hset,hgetall 等。
这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。
三)list 常用命令: lpush,rpush,lpop,rpop,lrange等
使用list的数据结构,可以做简单的消息队列的功能。另外一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。
四)set 常用命令: sadd,spop,smembers,sunion 等
set堆放的是一堆不重复值的集合,所以可以做全局去重的功能。
五)sorted set 常用命令: zadd,zrange,zrem,zcard等
多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOPN操作。
9. Redis为什么是单线程的
官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)Redis利用队列技术将并发访问变为串行访问
单线程的redis为什么这么快?
1)绝大部分请求是纯粹的内存操作(非常快速)
2)采用单线程,避免了不必要的上下文切换和竞争条件
3)非阻塞IO优点:
1.速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
2.支持丰富数据类型,支持string,list,set,sorted set,hash
3.支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
4.丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除如何解决redis的并发竞争key问题