Redis初探-事务、持久化、哨兵

Redis的介绍、事务、持久化、哨兵

介绍

Redis源码可以查看源码目录里面有各种语言,c#看这里。
是一个nosql的内存数据库,如果做缓存,优先选择redis。
Redis ,直接支持lua脚本(类似存储过程),lua脚本用标准C语言遍写并以源代码形式开放,lua脚本的代码,本身就具有原子性。
lua是c语言编写的,redis也是c语言编写,不存在编译过程。

事务

ACID

  • A,原子性,保证执行多个指令的时候,要么都执行,要么都不执行,要么都成功,要么都没有成功。
  • C,一致性。数据库中的数据应满足完整性约束。
  • I,隔离性。事务之间互不影响。
  • D,持久性。已提交的食物永久保存在数据库中。
    注意:如果要使用redis的事务,最好使用Watch监听所有key。

持久化

策略机制

  • 快照的方式(RDB)可以在指定的时间间隔内生成数据集的时间点快照。
    每次都全量备份--
  • 文件追加方式(AOF)持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。
  • 同时使用AOF 持久化和 RDB 持久化。

RDB

save

一个同步保存操作,将当前 Redis 实例的所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘。
Redis默认配置文件中提供了三种方式:

  • save 900 1 表示 900秒(15分钟内又1个更改)
  • save 300 10 表示 300秒(5分钟)内又10个更改
  • save 60 10000 表示 60秒内有10000个更改
    使用save命令,当数据量大的时候,会造成线程长时间阻塞,因为redis是一个单线程程序,耗时原因是因为fork操作,则当有其他客户端发送指令的时候,会卡主。
bgsave

单独的线程,后台异步一个线程去实现备份,根据我们的配置文件里策略然后去备份数据文件。

底层原理

一个定时器事件,计算数据阈值,每一次bgsave,触发dump操作,再把计数器dirty清0。

优势

备份缓慢,但是重启加载数据性能比较快。

AOF

手动触发

使用bgrewriteAOF指令,调用fork子线程船坚辛的AOF文件。

自动触发

通过修改配置文件redis.conf,持久化需要修改节点 appendonly yes 开启
日志追加:基本都是顺序读写,本身要比我们操作关系型数据库要快。
优点是:文件可读行高,每次都是追加修改的东西,备份比较快,但是当服务重启的时候,加载数据的时候比较慢

RDB、AOF优缺点
类型 备份 启动
RDB
AOF

RDB、AOF混合

如果RDB和AOF都开启了,则默认首先加载AOF文件,为了保证数据的尽可能完整性。默认的情况下,只要开启了AOF,混合默认自动打开。
AOF重写问题:当数据文件到达一个阈值的时候,会继续重写。
Redis.4X 版本之后支持混合模式。

混合模式的好处

备份,启动快,因为这样的备份,可以通过AOF备份,通过RDB还原,可以设计为异步,进行AOF文件转化成RDB文件。

持久化选择

  • 如果希望Redis的性能非常高,尽量不要用持久化
  • 如果希望保证数据的完整性,可根据业务选择不同的持久化策略,一般情况使用混合模式

Redis主从同步

主从是实现读写分离,主节点可以把数据同步到从节点里面,一般情况下,使用主从的时候,防止数据不一致,从节点只能读,默认从节点不会进行写操作。 所以当主节点宕机了,我们需要改代码,收到去修改redis的配置。
为了实现高可用。主节点宕机了,从节点可以替换主节点。由于不是自动替换,需要程序员修改代码,改ip地址和端口,或者使用keeplive实现VIP高可用。主从是不会自动切换,如果要自动切换需要使用哨兵。
Redis 6.X 对多线程进行了优化,优化主要有两个方向:

  • 提高网络 IO 性能,典型的实现像使用 DPDK 来替代内核网络栈的方式
  • 使用多线程充分利用多核,典型的实现像 Memcached

哨兵(Sentinel)

至少三个节点,而且必须是奇数,否则容易选举不出来新的master。

什么是宕机

  • 1.主观宕机:单独哨兵认为你宕机了,发现了故障。。
  • 2.客观宕机:半数哨兵认为主节点宕机,发现了故障。

选举主节点的原则

1.哨兵定期通过ping确认master的响应时间。
2.从节点备份的完整性、数据备份偏移量。
3.从节点的启动时间周期,心跳检测
4.如果上面三个条件都相等,则根据节点启动时分配的run id来,如果runid越小,则最有可能选择为新的master。
选举成功后,原master宕机,新master替换原master,之后原master重新启动,原master变成从节点。

哨兵或者主从里面的数据问题

脑裂问题

master和slave之间因为网络原因,不能连接,虽然master还在运行,但有多数以上的slave认为master宕机,slave开启选举,并产生新的master。这时集群中会出现两个master。client可能还在连接旧的master,当旧master连接恢复时,会被作为一个slave,自己的数据会被清空并从新master复制数据。

异步复制数据丢失问题

由于master和slave是异步复制数据,如果主节点和从节点直接数据复制太慢,主节点宕机这个时候从节点替换主节点,会产生丢失数据。

由于没有办法保证数据百分之白不丢失,只能尽可能少量丢数据。

解决方案

修改配置文件:
1.min-slaves-to-write=0,最少能连接到几个从节点,意思是,当主节点和从节点之间互通的时候,发现从节点小于1的时候,则从节点不会再继续给客户端提供服务。 解决脑裂问题。
2.min-slaves-max-lag=10,主节点和从节点的ack时间差|响应,意思是,数据复制和同步延迟不能超过10秒,一旦所有slave的延迟偏移量超过了10秒,则master不在接收请求。

集群模式(Cluster)

由于哨兵模式写入操作都是在主节点,成为了性能瓶颈,Redis在3.0后加入了Cluster 模式,即多个节点提供服务,去中心节点方式。
根据官方推荐,集群部署至少要 3 台以上的master节点,最好使用 3 主 3 从六个节点的模式。
由于多节点都可以读写,所以产生了哈希槽,实现每一个节点只负责一部分的数据写的分片模式。

集群解决的问题

1.数据是否分配均匀
2.数据节点增删对数据分布影响不能太大

简单的hash

会导致增加机器或减少机器的时候,mod数变更,余数也变更,引起大量的缓存穿透,造成雪崩。

hash环

一致性哈希,通过哈希环的方式,来解决分布式缓存的问题。
先哈希,假设结果=1,则把数据存放在哈希环上面1-2直接的虚拟节点上面,假设1挂了影响的是1-2,并且数据会逐渐转移到2-3之间,依然可用。
一致性哈希算法对于容错性和扩展性有非常好的支持。但一致性哈希算法也有一个严重的问题,就是数据倾斜。即分片集群中,节点太少,分布不均。

hash槽

为了解决hash环的问题,Redis采用了哈希槽(slot)。
Redis一共有2^14(16384)个槽。根据CRC-16(key)%16384来判断属于哪个槽。
注意:槽位转移分配,需要人工配置,非自动。

上一篇:字节跳动算法工程师总结:java接口实验报告总结


下一篇:Redis持久化锦囊在手,再也不会担心数据丢失了