java类似于redis的中间件 类似redis的数据库_redis

Redis是一款开源的基于内存存储的Key-Value模型的No-SQL类型数据库

数据类型:key-String、key-List、key-Set、SortSet、key-Hash、Geo、Bit、Hyper

常用的客户端:1.Jedis 2.Redisson 3.SpringData Redis

Redis底层数据结构:

String类型:SDS(动态字符串,空间预分配、惰性空间释放)

组成:free区域-剩余空间,len区域-长度,buf存放字符数组

ziplist(压缩列表,连锁更新),底层存储键值对的核心技术,节约内存,连续的区域,避免内存碎片

Hash(拉链法),扩容和收缩

Skiplist(跳表),双链式,header:头,tail尾,level层数,length长度,实现快速访问-SortSet

RESP协议:Redis序列化协议,自定义客户端需要使用

现象

击穿:

高并发下,同时访问某个key,可是Key失效了,导致大量的请求落到了数据库上,导致数据库崩溃。

高并发,单Key,失效

解决:1.热点key设置永久有效 2.互斥锁MutexKey 3.同步+双锁检查

穿透:

高并发下,大量访问不存在的Key,导致请求落到了数据库上,从而数据库宕机

解决:1.布隆过滤器(Redisson-封装或者谷歌Gauva(布隆过滤器))Bitmap类型,容错率-哈希函数-误判率

雪崩:

高并发下,大量访问很多key,可是,这些key都失效了,导致请求落到了数据库上

解决:1.设置不同的有效期(有效期+随机时间)2.多重缓存机制 3.锁

倾斜:

集群下,高并发,大量请求某个key,结果都被分配到了固定某台的服务器上,导致这台服务器压力过大

解决:1.采用去中心化

2.从设计的角度去尽可能排除(避免大集合、不适应影响性能的命令:keys、monitor、功能单一,拆解大key)

Redis过期策略

key的生存时间到了,Redis会立即删除吗?不会立即删除。 过期策略:

●定时删除:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除

●定期删除:Redis每隔一段时间就去会去查看Redis设置了过期时间的key,会再100ms的间隔中默认查看3个key。

●惰性删除:

key过期的时候不删除,每次通过key获取值的时候去检查是否过期,若过期,则删除,返回null(用的时候再检查删除)

当去查询一个已经过了生存时间的key时,Redis会先查看当前key的生存时间是否已经到了,是则直接删除当前key,并且给用户返回一个空值。

Redis采用的过期策略:惰性删除+定期删除

惰性删除流程:在进行get或setnx等操作时,先检查key是否过期,若过期,删除key,然后执行相应操作;若没过期,直接执行相应操作

定期删除流程:遍历每个数据库,检查当前库中的指定个数个key(默认是每个库检查20个key,注意相当于该循环执行20次,循环体时下边的描述)

如果当前库中没有一个key设置了过期时间,直接执行下一个库的遍历。

随机获取一个设置了过期时间的key,检查该key是否过期,如果过期,删除key。

判断定期删除操作是否已经达到指定时长,若已经达到,直接退出定期删除。

Redis的淘汰机制

在Redis内存已经满的时候,添加了一个新的数据,执行淘汰机制。

volatile-lru:在内存不足时,Redis会在设置过了生存时间的key中干掉一个最近最少使用的key。

allkeys-lru:在内存不足时,Redis会在全部的key中干掉一个最近最少使用的key。

volatile-lfu:在内存不足时,Redis会在设置过了生存时间的key中干掉一个最近最少频次使用的key。

allkeys-lfu:在内存不足时,Redis会在全部的key中干掉一个最近最少频次使用的key。

volatile-random:在内存不足时,Redis会在设置过了生存时间的key中随机干掉一个。

allkeys-random:在内存不足时,Redis会在全部的key中随机干掉一个。

volatile-ttl:在内存不足时,Redis会在设置过了生存时间的key中干掉一个剩余生存时间最少的key。

noeviction:(默认)在内存不足时,直接报错。

指定淘汰机制的方式:maxmemory-policy 具体策略,设置Redis的最大内存:maxmemory 字节大小

Redis持久化

Redis提供2种方式实现持久化:1.RDB 2.AOF

RDB

RDB是Redis默认的持久化机制

RDB持久化文件,速度比较快,而且存储的是一个二进制的文件,传输起来很方便。

RDB持久化的时机:

save 900 1:在900秒内,有1个key改变了,就执行RDB持久化。

save 300 10:在300秒内,有10个key改变了,就执行RDB持久化。

save 60 10000:在60秒内,有10000个key改变了,就执行RDB持久化。

RDB无法保证数据的绝对安全。

RDB存储的是数据,时间间隔无法实时持久化

AOF

AOF持久化机制默认是关闭的,Redis官方推荐同时开启RDB和AOF持久化,更安全,避免数据丢失。

AOF持久化的速度,相对RDB较慢的,存储的是一个文本文件,到了后期文件会比较大,传输困难。

AOF持久化时机:

appendfsync always:每执行一个写操作,立即持久化到AOF文件中,性能比较低。

appendfsync everysec:每秒执行一次持久化。

appendfsync no:会根据你的操作系统不同,环境的不同,在一定时间内执行一次持久化。

AOF相对RDB更安全,推荐同时开启AOF和RDB。

AOF存储的是命令(更改数据的命令),可以实时持久化

同时开启RDB和AOF的注意事项:

1.如果同时开启了AOF和RDB持久化,那么在Redis宕机重启之后,需要加载一个持久化文件,优先选择AOF文件。

2.如果先开启了RDB,再次开启AOF,如果RDB执行了持久化,那么RDB文件中的内容会被AOF覆盖掉。

Redis事务

Redis的事务:一次性、顺序性、排他性的执行一个队列中的一系列命令。

Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。

可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

集群策略(可以抗更高的并发量,高可用,避免单机故障)

1.Redis主从复制

实现:多台服务器,一主多从

主机负责读写,从机负责读--->读写性能增加,从机和主机保持一致

优点:防止数据的丢失,主机挂了,从机可以立即配置为主机,一定程度上可以解决单点故障。

缺点:1.主机挂了,从机不能自动上位,需要手动配置。

2.主机内存有限

无法解决存储上限的问题

Redis主从同步策略:主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

2.哨兵机制

主机和从机每一个机器都有一个哨兵,哨兵之间会有相应的联系,如果说master (主机)挂掉了,哨兵会自动选举slave来作为主机,保证服务的高可靠。

保证主库存活,监控主库的状态 无法解决存储上限的问题

缺点:主机决定了当前集群的内存容量,决定整个集群的容量

3.Redis-Cluster 多主多从,去中心化 

去中心化模式中一般有三主三从,因为有多个主机,每个主节点只负责读写一部分数据。

去中心化模式中一共有16384个位置 ,多台主机平均分配。

优点:

1.有主从,可以自动切换,保证数据不丢失,服务不停止

2.大大提高了读写性能,集群的内存也成倍增加,完善了哨兵模式下的缺点。

3.提供数据槽,用来存储数据,方便数据的迁移。如果数据迁移,是整个数据操一块迁移。


a.哈希卡槽slot,分片策略(crc16和crc16(key)%16384计算存储的卡槽) 

b.请求随机分配到主节点,错误转向



基于Redis实现分布式锁:Redisson(RLock)红锁

结合项目,谈项目中的使用

你们项目中使用多少台机器?

 

青山不改,绿水常流。谢谢大家!