NoSQL:(not only SQL)不仅仅是SQL语句,泛指非关系型的数据库,区别于关系数据库。随着互联网 web2.0 网站的兴起,传统的关系数据库在处理 web2.0网站,特别是超大规模和高并发动态网站已经显得力不从心,出现了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。
易扩展,数据之间无关系,这样就非常容易扩展,无形之间也在架构的层面上带来了可扩展的能力。
高性能,NoSQL 数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。
灵活的数据模型 NoSQL 无须事先为要存储的数据建立字段,随时可以存储自定义的数据格式。
Redis(远程字典服务),是NoSQL的一种,是利用C语言编写的开源的,以Key—value数据结构存储系统。可以作为数据库、缓存和消息中间件。
它支持多种数据类型,如:字符串(String)、散列值(hash)、列表(list)、集合(set)、有序集合(sorted set),Key—value中key是string类型的数据。
key—value是利用dict结构体进行存储的。
dict :hash字典
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K1Ghp2R2-1691936074904)(C:\Users\wdy_1\AppData\Roaming\Typora\typora-user-images\1691844349338.png)]
dict中维护了一个dictht ht[2] 两个hash表,ht[1]主要用于发生冲突后进行rehash的时候使用,ht[0]是常用的hash表。
redis的rehash并非像我们传统的那样:一次性做完所有的数据迁移工作。Redis将扩容后的rehash操作分散到了它的CRUD操作中,并非一步到位,而且每次rehash遵循少量多次原则,在它的查找、添加、删除都有rehash的体现,称之为渐进式rehash。当ht[0]中的数据完全迁移完成之后,先让ht[0]hash数组清空,然后让ht[0]的指针指向ht[1],这样下次rehash的时候又可以重复操作。
采用关系模型来组织数据的数据库,关系模型就是二维表模型,二维表的名字就是关系,二维表中的一行数据就是一条记录,二维表中的一列就是一个字段。
优点:
缺点:
非关系型,一般不保证ACID原则的数据存储系统。键值对存储。
优点:
缺点:
常用的五种数据类型:字符串(String)、散列值(hash)、列表(list)、集合(set)、有序集合(sorted set)。
底层共有六种数据结构:简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组。
是由有序链表优化而来,链表的查询效率不高。可以把每两个元素的第一个元素提上一层,建立一些冗余索引。进而可以支持快速的插入、删除、查找操作。
查找32,类似这般查找。
类似数组,由一系列特殊编码的连续内存块组成的顺序型数据结构。
string是Redis最基本的类型,一个key对应一个value。底层使用简单动态字符串(sds)实现。最大能存储512MB
是二进制安全的,即string可以包含任何数据类型,比如序列化的对象或者图片。
44字节一下:OBJ.ENCLUDING.EMBSTR(地层是连续的),44字节以上:OBJ.ENCLUDING.RAW(地层是不连续的),数值型:OBJ.ENCLUDING。INT
使用场景:
底层使用压缩表和哈希表
Hash和String都可以存储对象,但是String是将对象转换称为json对象,适合用于不经常修改的字符串,如果是那种需要经常修改的,建议使用Hash存储。
哈希冲突较多时
使用场景:
是一个简单的列表,可以重复,保证添加顺序。
用于消息队列,评论中按照时间先后的评论记录
使用场景:
元素不重复,不保证添加顺序。
快速定位需要查找的元素,可以用来实现点赞收藏等功能,共同好友推荐,
使用场景:
有序集合,值是Map
使用场景:
Redis6之前是单线程,为什么呢?
简单来说,就是Redis官方认为没有必要,单线程的Redis的瓶颈通常在CPU的IO,而在使用Redis时几乎不存在CPU成为瓶颈的情况。使用Redis主要的瓶颈在于内存和网络,并且使用单线程也存在一些优点,比如避免了并发读写带来的一些列问题。
单线程的瓶颈在内存和网咯,Redis6.0引入多线程主要是为了解决网络IO读写这个瓶颈,执行命令还是单线程执行的,所以不存在线程安全问题。
没有,需要修改配置redis.conf: io-threads-do-redis no,中的no改为yes
Redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化很快,也容易丢失。Redis还为我们提供了持久化的机制,分别是RDB(Redis DataBase)和AOF(Append Only File)。
RDB持久化是指在指定的时间间隔内将内存数据中数据集快照写入磁盘。也就是默认的持久化方式,这种方式就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。恢复时是将快照读取到内存中。
触发快照的时机:
save的规则满足的情况下,会触发RDB规则。
save 20 10 就是在20秒之内对10个键值进行操作,会触发持久化;
也可以在关闭Redis的时候使用shutdown save命令持久化到RDB中。
优点:
缺点:
AOF持久化以日志的形式记录服务器所处理的每一个写,删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
优点:
缺点:
Redis事务本质是一组指令的集合,一个事务中的所有指令都会被序列化,在事务执行过程中,会按照顺序执行。Redis事务的主要作用就是串联多个指令防止别的指令插队。
所有的指令在事务中,并没有直接被执行。只有发起执行exec指令的时候才执行。
事务在执行的过程中,不会被其他客户端发送来的指令请求打断。
redis单条指令保证是原子性的。但是事务不保证同一事物多条指令执行的原子性,即使指令有错误也会添加到队列中,执行报错也不会影响其他指令的执行。
Redis的事务操作:
开启事务(multi),
执行命令、命令入队,
执行事务(exec),
放弃事务(discard)。
在事务开启前还可以通过watch指令观测监听某个键的变化,如果在其他客户端将监听值修改,在事务中对某个键操作时,事务会失效。
Redis单机版有以下缺点:
Redis集群就是为了解决Redis单机版的这些问题。
单机版通过RDB或者AOF持久化机制将数据持久化到磁盘上,但数据都存储在一台服务器上,并且读写都在同一台服务器(读写不分离),如果磁盘出现问题,则会导致数据不可用,为了避免这种问题,Redis提供了复制功能,即主从复制。
主从复制是指将一台Redis服务器的数据,复制到其他Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能有主节点到从节点。
使用一个Redis实例作为主机,其余的作为备份机。主机和备份机的数据完全一致,主机支持数据的写入和读取等各项操作,而从机只能支持与主机数据同步和读取。也就是说,客户端可以将数据写入到主机,由主机自动将数据的写入操作同步到从机。主从模式很好地解决了数据备份问题,并且由于主从服务数据几乎是一致的,因而可以将写入数据的指令发送给主机执行,读取数据的指令发送给不同的从机执行,达到读写分离。
主从复制的作用主要包括:
优点:
缺点:
为了解决主从模式的Redis集群不具备自动容错和恢复能力的问题,Redis2.6之后提供了哨兵模式。
哨兵模式的核心还是主从复制,是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
单哨兵
哨兵集群
监听所有服务器是否正常运行:通过发送命令返回服务器的运行状态,除了监控主服务器、从服务器外,哨兵之间也相互监控。
故障切换:当哨兵检测到master宕机,会自动将slave切换称为master,然后通过发布订阅模式通知其他服务器修改配置文件,让它们切换master。同时那台有问题的旧主机也会变为新主机的从。
优点:
是基于主从模式的,解决主从模式中master故障不可以自动切换故障的问题。
缺点:
在Redis缓存中,前台请求后,后台先从缓存中读取数据,取到就直接返回结果,取不到才会去数据库中查询,查询之后将结果更新到缓存中并且返回。
穿透缓存和数据库。
key对应的数据在数据库中就不存在,缓存中肯定也没有,每次请求缓存中找不到,请求都会到数据库中,从而肯能压垮数据库。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有。
解决办法:
击穿缓存
某key在缓存中,但是如果这个key刚好过期了,此时又刚好大量请求访问这个key,这些请求发现这个key已经过期了,都会去数据库中查询,数据库的压力就上升了。
解决办法:
大量的击穿
缓存雪崩是指,在高并发下,大量的缓冲失效,或者缓存层出现故障。于是所有的请求都会访问数据库,数据库的调用就会暴增,造成数据库挂掉。
解决办法: