什么是redis?
是一种基于内存的数据库,对数据的读写操作都是在内存中完成的,因此读写速度非常快,常用于缓存,消息队列,分布式锁等场景。
redis的数据类型以及使用场景
1)String 类型:可以是字符串、整数或浮点数,对整个字符串或字符串的一部分进行操作,对整数或浮点数进行自增或自减操作。使用场景:缓存对象,常规计数,分布式锁,共享session信息等。
2)list列表:一个链表,链表上的每个节点都包含一个字符串,对链表的两端进行push和pop操作,读取单个或多个元素;根据值超载或删除元素:使用场景:消息队列
3)hash散列:包含键值对的无序散列表,包含方法有添加,获取,删除单个元素,使用场景:缓存对象、购物车等。
4)set集合:包含字符串的无序集合,字符串的集合,包含基础的方法有:是否存在,添加,获取,删除,还包含计算交集,并集,差集等。使用场景:点赞,共同关注,抽奖活动等。
5)zset类型:排序场景,比如排行榜,电话,姓名排序等。
redis三种持久化方式
1)AOF日志:每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里。
2)RDB快照:将某一时刻的内存数据,以二进制的方式写入磁盘。
4)混合持久化方式:Redis 4.0新增的方式,集成了AOF和RDP的优点
AOF日志是如何实现的
1)Redis 在执行完一条写操作命令后,就会把该命令以追加的方式写到一个文件里,然后redis 重启时,会读取该文件记录的命令,然后逐一执行命令的方式来进行数据恢复。
2)为什么先执行命令,再把数据写入日志呢?
redis时先执行写操作命令后,才将该命令记录到AOF日志里的,这样做有两个好处:
2.1)避免额外的检查开销:因为如果先将写操作命令记录到AOF日志里,再执行该命令的话,如果当前的命令语法有问题,那么如果不进行领料语法检查,该错误的命令记录到AOF日志里后,redis 在使用日志恢复数据时,就可能出错。
2.2)不会阻塞当前写操作命令的执行:因为当写操作命令执行成功后,才会将命令记录到AOF日志。
缺点:
2.3)数据可能会丢失:执行写操作命令和记录日志是两个过程,那当redis还没有来得及将命令写入硬盘时,服务器发生宕机了,这个数据就会有丢失的风险。
2.4)可能阻塞其他操作:由于写操作命令执行成功后才记录到AOF日志,所以不会阻塞当前命令的执行,但因为AOF日志也是在主线程中执行的,所以当redis把日志文件写入磁盘的时候,还是会阻塞后续的操作无法执行。
3)AOF写回策略有几种?
3.1)写回流程:
1)redis执行网写操作命令后,会将命令追加到service.aof_buf缓存区
2)然后通过write()系统调用,将aof_buf缓冲去的数据写入到AOF文件,此时数据并没有写入到硬盘,而是拷贝到内核缓冲区,等待内核将数据写入硬盘。
3)具体内核缓冲区的数据什么时候写入到硬盘,由内核决定。
3.2)always:每次写操作命令执行完后,同步将aof日志数据写回硬盘。
3.3)everysec:每次写操作命令执行完后,先将命令写入到aof文件的内核缓冲区,然后每隔一秒将缓存区里的内容写回到磁盘。
3.4)no:不由redis控制写回硬盘的时机,转交给操作系统控制写回时机,也就是每次写操作命令执行完后,先将命令写入aof文件的内核缓冲区,再由操作系统决定何时将缓冲区内容写回硬盘
4)AOF日志过大,会触发什么机制?
为了避免aof文件越写越大,提供了AOF重写机制,当aof文件的大小超过所设定的阈值后,redis就会启用aof重写机制,来压缩aof文件。AOF重写机制在重写时,读取当前数据库中的所有键值对,然后将每个键值对用一条命令记录到新的AOF文件,等到全部记录完后,就将新的AOF文件替换现有的AOF文件。重写是有由子进程来完成的