Redis基础

Redis基础(理论)

文章目录

是什么:

Redis是key-value数据库(NoSQL一种),Redis数据操作主要在内存,两者(mysql,redis)并不是相互替换和竞争关系,而是共用和配合使用

能干什么:

1.分布式缓存,挡在mysql数据库之前

2.内存存储和持久化(RDB+AOF)支持支持异步内存同步中的数据写在磁盘中,同时不影响继续服务

3.高可用架构搭配(单机,主从,哨兵,集群)

4.缓存穿透,击穿,雪崩

5.分布式锁

6.队列

优势:

1.性能极高:redis最高的读的速度是110000次/秒,写的速度是81000次/秒

2.redis数据类型丰富,不仅仅支持key-value类型的数据,还支持list,set,zset,hash,hyperloglog,streams等数据结构的存储

3.redis支持数据持久化,可以将内存中的数据存放在磁盘中,重启时重新加载在内存中

4.redis支持数据备份,既master-slave模式的数据备份

redis的10大数据类型

1.string:是redis的基础数据类型,一个key对应一个value,是二进制安全的,就是说可以包含任何数据,比如图片,序列化等,string最大存放512M输出

2.list(列表):是简单的字符串列表,按照插入数据的顺序排序,可以添加一个元素到list的头部(左边)或尾部(右边),redis中的list实际上维护的就是一个双端链表(最多包含2的32次方-1)

3.hash(哈希表):是string类型的field和value的映射表,特别适用于存储对象(最多包含2的32次方-1)

4.set:是string类型的无序列表,具有唯一性,和无序性(也就意味着列表中的元素都是唯一的),redis中的set集合是通过哈希表来实现的,所以查询,添加,删除的复杂度都是O(1),(最多包含2的32次方-1)

5.zset(有序列表):和set类型一样,不同的是在每个元素的前面都会关联着一个double类型的分数,redis也就是通过分数对zset中的元素进行排序,zset的元素是唯一的,但是分数确可以重复的

6.GEO:主要用于存储地理位置信息,并对存储信息进行操作,包括添加地理位置的坐标,获取地理位置的坐标,计算两个位置之间的距离,

7.Hyperloglog:是用来做基数统计的,Hyperloglog的优势就是,在输入数据或者体积非常庞大是,计算基数所需的空间总是固定的且很小,每个Hyperloglog的键只需要12kb的内存,就可以计算2的64次方个不同的元素的基数,和元素越多耗费内存越多的集合形成鲜明对比,但是Hyperloglog只是通过输入元素来计算基数,不会像集合一样存储元素本身,所以Hyperloglog不能像集合一样获取到元素的

8.bitmap(位图):bitmap由很多个小格子组成只能存放0和1,用来判断Y/N状态,也就是说bitmap由0和1状态表现的二进制位的bit数组

9.bitfield(位域):通过bitfield命令可以一次性操作多个比特位域(值连续的几个比特位),他会执行一系列操作并返回一个响应数组,,这个数组中的元素对应参数列表中的相应操作的执行结果

10.streams:主要用于消息队列(MQ,Message Queue),redis本身是有一个redis的订阅与发布(pub/sub)来实现消息队列的功能,但是他的缺点是无法持久化,如果redis出现网络断开,或者是宕机,信息就会丢失,而streams就是pub,sub的补充版streams支持序列化和主备复制功能,可以让任何客户端任何时刻访问数据,并能记住每个客户端的位置,还能保证信息不丢失

redis键(key)

keys *:查看当前库所有的key

exists key:判断某个key是否存在

type key:查看key是什么类型的

del key:删除指定的key的数据

unlink key:非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的删除会在后面异步删除

ttl key:查看还有多少秒过期,-1代表永不过期,-2表示已经过期

expire key 秒数:为指定key指定过期时间

move key dbindex(0-15):将当前的数据库的key移动到指定的数据库中

select dbindex 切换数据库【0-15】 ,默认6

dbsize:查看当前数据库key的数量

flushdb :清空当前数据库

flushall:清空所有库

redis持久化

持久化双雄:RDB和AOF

RDB(Redis DataBase):

1.在指定时间间隔,执行数据集的时间点的快照

2.能做什么:在指定时间间隔将内存中的数据集快照写入磁盘,他恢复是从磁盘快照文件直接读取到内存中

3.redis中的RDB在保存快照是全量快照(把内存中的数据全部快照保存在磁盘中)

4…RDB保存的是dump.rdb文件

RDB优势:

1.适合大规模的数据恢复

2.按照业务定时备份

3.对数据完整性和一致性要求不高

4.RDB文件在内存中的加载速度要比AOF快

RDB缺点:

1.在一定间隔时间做一次备份,如果redis服务器在这个时候宕机,就会丢失从当前至最近一次备份之间的数据会丢失

2.内存数据全量同步,如果数据量非常大的回到是I/O严重影响服务器性能

3.RDB依赖于主进程的fork,在大的数据集中,可能会造成服务请求瞬间延迟,fork在备份的时候数据会在内存中复制一份,大致2倍的膨胀性

AOF(Append Only File):

1.以日志的形式来记录每个写操作,将redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取日志文件重新执行语句

2.默认情况下,AOF是关闭的,在配置文件中appendonly yes(开启AOF功能)

3.AOF保存的是appendonly.aof文件

AOF缓冲区三种写回策略:

1.Always:同步写会,每执行一个增,删,改命令执行完立刻同步到日志文件中

2.everysec:每秒写回,每个写命令执行完,只会先把日志写到AOP文件的内存缓存区,每隔1秒把缓冲区的内容写到磁盘

3.no:操作系统控制的写回,每个写操作命令执行先把日志写到AOF文件的缓冲区中有操作系统决定何时把缓冲区内容写会磁盘

AOF优势:

1.更好的保存数据不丢失,性能更高,可做紧急恢复

AOF劣势:

1.相同的数据集的数据而言AOF远远比RDB文件大,恢复速度慢于RDB(AOF都是以一条条的执行命令写入在aof文件中重启时需要一条条的执行)

同时开启RDB和AOF功能:

1.当redis恢复数据的时候,优先载入AOF文件来恢复原始的数据

2.因为通常AOF文件保存的数据集要比RDB文件保存的完整

3.当RDB数据不实时,同时使用两者是服务器重启时仍然只会找AOF文件(那为什么不直接只开AOF呢?原因是:RDB更适合用于备份数据库,留着RDB作为一个万一的手段)

关闭RDB和AOF功能:

RDB:save “”(关闭RDB)

AOF:appendonly no (禁用AOF)

Redis事务

redis事务是什么:

1.可以一次执行多个命令,本质就是一组命令的集合,一个事务中的所有命令都会序列化的,按照顺序的串行化命令不能让其他的命令插入其中

redis能干什么:

一个队列中,一次性,顺序性,排他性的执行一系列命令

Redis中的事务和Mysql中的事务有很大的不同:

1.单独的隔离操作:

redis事务仅仅是保证事务里的操作会被连续的独占执行,redis命令执行是单线程架构的,在执行事务内所有的指令是不可能在去同时执行其他用户的请求

2.没有隔离级别的概念:

因为事务提交前任何命令都不会被实际执行

3.不保证原子性:

redis中的事务不保证原子性,也就是不保证所有的指令同时执行成功或者失败,只有决定是否执行全部指令的能力,没有执行到一半回滚的能力

4.排他性

redis会保证一个事务内的命令依次执行,而不会被其他命令插入

redis事务的使用

1.正常执行 MULTI EXEC

2.放弃事务:MULTI DISCARD

watch监控:

redis使用watch来提供乐观锁定的

悲观锁:每次拿数据的时候都认为别人会修改,所以每次都会把要修改的元素加上锁,别人要想拿到这个数据就需要获取到这个锁才能修改值

乐观锁:每次拿数据的时候都不会认为别人会修改,所以每次都不会给修改的元素加上锁,但是更新的时候会判断此期间有没有别的人去修改这个元素(策略就是:提交版本必须大于记录当前版本才能执行更新)

要先监控在开启multi,保证key的变动在同一个事物内,当redis事物提交时他会先判断被监控的的key是否有被改动,有被改动在事物中对key修改的命令就会失败

总结redis的事务:

开启:以MULTI开始一个事务

入队:将多个命令入队到事务中,接到这些命令不会立刻被执行,而会放到等待执行的队列当中

执行:由EXEC命令触发事务

redis管道

用于解决:优化频繁命令往返造成的性能瓶颈

redis管道是什么:

批处理命令变种优化措施,类似redis原生命令mget,mset

Pipeline与原生批量命令对比:

1.原生批量命令是原子性的(mset,mget),pipeline是非原子性的

2.原生批量命令一次只能执行一类命令,而pipeline支持批量执行不同的命令

3.原生的批量命令是有redis服务器实现的,而pipeline需要服务器与客户端共同完成

pipeline与实务对比:

1.事务具有原子性,管道不具有原子性

2.管道一次将多条命令发到服务器,事务是一条条发的,事务只有接受到exec命令后才会执行,管道不会,执行事务时会阻塞其他命令的执行,而pipeline不会

pipeline的注意事项

1.pipeline缓冲的指令只是会依次执行,不保证原子性,如果执行到异常也会继续执行后续命令

2.使用pipeline组装的命令个数不能太多,不然数据量过大客户端堵塞的时间可能太久,同时服务器也被迫回复一个队列答复,占用很多的内存

redis的发布与订阅

reids的发布与订阅是什么:

是一种通信模式发送者(PUBLISH)发送消息,订阅者(SUBSCRIBE)接受信息可以实现进程之间的信息传递

redis的发布与订阅能干嘛:

redis客户端可以订阅任意数据的频道,类似我们微信关注多个公众号

总结:

Redis可以实现消息中间件MQ的功能,通过发布订阅实现消息的引导和分流。不推荐使用该功能,

专业的事情交给专业的中间件处理,redis就做好分布式缓存功能

redis复制(replica)

是什么:

就是主从复制,master以写为主(能读能写),slave以读为主(只能读不能写)

当master数据变化的时候,自动将新的数据异步同步到其他slave的数据库中

在这里插入图片描述

能做什么:

1.读写分离

2.容灾恢复

3.数据别分

4.水平扩容支支撑高并发

基本配置和使用:

配置:在master中要配置requirepass(密码)参数,那么slave中就要配置masterauth来设置效验密码,否则master会拒绝slave的请求

基本命令:

info replication: 可以查看复制节点的主从关系和配置信息

master端:replication 主库ip 主库端口:开启主从(一半写入配置文件内)

slave端:slaveof 主库ip 主库端口:每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件,如果该数据库已经是某个主数据库的从数据库,那么会停止和原主数据库的同步关系转而和新的主数据库同步,重新建立主从

slaveof no one :使当前数据库停止与其数据库同步,自己变成主数据库,自立为王

主从复制的工作原理,流程:

1.slave启动,同步初请

slave启动成功连接到master后会发送一个sync命令

slave首次全新连接master,一次完全同步将被自动执行,slave自身原有的数据会被master数据覆盖清除

2.首次连接,全量复制

master节点收到sync命令后会开始在后台保存快照,同时将收集到的用于修改的命令都缓存起来,master节点执行RDB持久化后

master就会把RDB快照文件和缓存的命令发送到slave,以完成第一次的同步

slave端接收到数据库文件后把文件放在缓存中,从而实现复制

3.心跳持续,保持通讯

设置保持通讯心跳包的秒数(repl-ping-replica-period 10)

4.进入平稳,增量复制

master接受到修改命令后会自动依次传给slave,完成同步

5.从机下线,重连续传

master发现slave回来后只会把slave下线之后的数据更新到slave数据库中(并不会重新把全部的数据重新复制给slave)

主从复制缺点

1.复制延时,信号衰减

2.默认情况下master宕机后从机会一直等待master主机的归来,并不会重新选举一个主机

哨兵

是什么:

检查master主机是否还存活中,如果发现master已经不存活就会投票选举新的master

在这里插入图片描述

能干什么:

1.主从监控

监控主从redis是否正常运行

2.消息通知

哨兵可以将故障转移的结果发送给客户端

3.故障转移

如果哨兵发现master异常,则会进行主从切换,将slave中选举出新的master

4.配置中心

客户端通过哨兵连接来获取当前redis服务的主节点地址

基本使用

一半redis的哨兵个数都是3个及以上(单数)因为选举master的时候都是通过各个哨兵的头条来选举

修改自己哨兵的配置文件(

bind 0.0.0.0
daemonize yes
protected-mode no
port 26379
logfile "/myredis/sentinel26379.log"
pidfile /var/run/redis-sentinel26379.pid
dir /myredis
sentinel monitor mymaster 192.168.111.169 6379 2
sentinel auth-pass mymaster 111111

根据自己实际情况修改上面模板)

启动原有的redis主从,启动redis哨兵

把原有的master关掉这个redis服务,哨兵投票选举出新的master之前的slave会直接与新的master建立主从关系

流程和选举原理

流程:

当一个主从配置中的master失效之后,哨兵就会选举出新的master用于取代旧的master工作,之前与旧master建立连接的slave会重新与新的master建立建立(一般建议哨兵的个数采取奇数台,防止一台哨兵与master无法连接时会误操作)

选举原理:

SDown(主观下线):就是单个哨兵发现master主机已经掉线了,判断master主机主观下线的过程(在哨兵上发送ping命令给master主机发现master没有回复,就达到SDown的条件)

ODown(客观下线):需要一定数量的哨兵票数,多个哨兵打成一直意见才能认为一个master客观上已经下线

选举出领导者哨兵(选出兵王):当主节点被判断客观下线以后,各个哨兵节点会进行协商,先选举出一个领导者(兵王),被选出的兵王进行故障转移(通过Raft算法获取兵王)

兵王选举新的master的流程:

一个哨兵发现master下线后达到主观下线的要求后,然后那个哨兵就会通告给其他的哨兵让他们去ping master主机发现都ping不通后打成客观下线的要求,然后其他本来跟着旧master的从服务器就会执行slaveof no one,然后通过哨兵的投票选举选出新的master,然后在从机在重新指定成为新master的从机,当旧的master回归,新的master并不会重新变成slave,而是变成新的master的slave

哨兵使用的建议:

1.哨兵节点的数量应为多个,哨兵本身也是集群,保证高可用

2.一般哨兵的个数都是奇数个

3.各个哨兵的配置都应该一致

4.如果哨兵节点部署在Docker容器里面,要特别注意端口的正确映射

5.哨兵集群+主从复制,确保数据0丢失

集群

是什么

redis集群是一个提供在多个redis节点间共享数据的程序集,redis集群可以支持多个master

在这里插入图片描述

能做什么

一、redis集群支持多个master,每个master又可以挂载多个 slave

1.读写分离

2.支持数据的高可用

3.支持海量的数据的读写操作

二、.由于cluster自带哨兵的故障转移机制,内置高可用的支持,无需再去使用哨兵功能

三、客户端与redis的节点连接,不在需要连接集群中的所有节点,只需要连接任意一个集群上的可用节点即可

四、槽位slot负责分配到各个物理服务器节点,由对应的集群来维护节点,插槽和数据之间的关系

集群算法-分片-插槽slot

1.redis集群的槽位slot

redis集群没有使用一致性hash,而是引入了哈希槽的概念,redis集群有16384个哈希槽,每个key通过crc16算法的效验对16384取模来决定放在哪个槽,集群中的每个节点负责一部分的哈希槽

2.redis集群的分片

使用redis集群时我们会将存储的数据分布在不同的redis服务器上,这就被称为分片,简单来说就是,集群中的每个redis实例都可以被称为整个数据的一个分片

我们如何找到相应的key:我们对key进行crc16算法处理并通过对从分片取模,使用确定性哈希函数,这意味着给定的key将多次始终映射到一个分片,我们就可以读取到特定key的位置

槽位slot和分片这两个的优势

方便扩容和缩容和数据分派查找

slot槽位映射,一般有三种解决方案

1.哈希取余分区

当redis集群发生变化时之前存入的数据就会重新计算hash值在放在对应的redis主机上

2.一致性哈希算法分区

能做什么:当redis集群的服务器台数发生变动时,尽力减少对客户端到服务器的映射的关系

三个步骤

1.构建一致性哈希环

一致性哈希算法必然有个hash函数并按照算法产生hash值,这个算法的所有可能哈希值会构成一个全量集,这个集合可以成为一个hash空间(0,2的32次方-1),这是一个线性空间,在算法中逻辑的把这个线性空间收尾相连,在逻辑上形成一个哈希环,整个空间按顺时针方向组织
在这里插入图片描述

2.redis服务器ip节点映射

将集群中各个ip节点映射到环上的某个位置,经过ip地址的哈希函数计算(hash(ip)),使用ip地址哈希后在环空间的位置

在这里插入图片描述

3.key落到服务器的落键规则

当我们需要存储一个kv键值对时,首先计算key的hash值,然后通过hash算法算出key在环上对应的位置,然后从此位置沿环顺时针行走,遇到的第一台redis服务器它就把这个键值对存储到该节点上

在这里插入图片描述

为什么redis集群的最大槽位数是16384个?(crc16算法其实可以产生2的16次方65535个哈希槽但是为什么只用16384个呢)

一、如果槽位为65535,发送心跳信息的消息头就达到了8k,发送的心跳包就过于庞大

在消息头中最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为65536时,这块的大小是: 65536÷8÷1024=8kb

当槽位为16384时,这块的大小是:16384÷8÷1024=2kb

二、redis的集群主节点数量基本不可能超过1000个

集群的节点越多,发送心跳包的个数就越多,就会导致网络拥堵(所以作者不建议redis集群的服务器个数超过1000台,redis集群服务器台数做多16384台)

三、槽位越小,节点少的情况下,压缩比高,容易传输

redis主节点的配置信息中它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输的过程中都会对bitmap进行压缩,bitmap的填充率=slots/N(N表示节点数),如果redis服务器的节点很少,hash槽位比较多的时候他的压缩率就比较低

redis集群不保证强一致性,这意味着在特定的条件下,redis集群可能会丢掉一些被系统收到的写入请求命令!!!

redis集群部署

这里只讲redis集群的理论部分,具体配置请参考别的文章!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值