Redis简介

Redis

缓存

缓存是Redis最常见的用途,一般用来保证系统的高性能与高并发,因为缓存是放在内存的,而数据库的数据需要经过磁盘文件,当然mysql也支持一部分缓存,内存读写的并发量一定是比磁盘读写高的。

简介

Redis与Memcached的区别

  1. Redis支持复杂数据结构。
  2. Redis支持集群模式,当然Memcached也可也实现集群只是比较麻烦。
  3. Redis是单核的,在小数据的处理上Redis比Memcached的性能要高。Memcached是多核的,在大数据的处理上性能较高。

线程模型

主要使用file event handler,一个单线程的文件事件处理器。监听多个socket,根据socket上的事件类型选择对应的处理器来处理。包括四个部分:多个socket,IO多路复用程序,文件事件分派器,事件处理器(连接应答,命令请求,命令回复处理),其中为了防止事件并发引起的问题,文件事件分派器会将产生的事件放入队列中排队。由于是纯内存操作、IO多路复用程序是NIO的、底层使用C语言、没有多线程的竞争问题等优点,Redis的效率很高。在6.0版本后引入了多线程,用来处理网络数据的读写与协议解析。

支持的数据类型

  1. Strings: 简单的key-value缓存
  2. Hashes:类似map的一种结构,适用于结构化的数据,将对象的属性作为key,属性值作为value,来存放整个对象,每次读写缓存就可以操作某个字段。
  3. Lists:有序列表,存储列类型的数据而且分页性能高。
  4. Sets:无序集合,主要用于分布式环境下的全局去重。
  5. Sorted Sets:有序集合。
  6. Bitmaps:位图不常用。
  7. HyperLogLogs:不常用
  8. Streams:不常用

过期策略

定期删除+惰性删除

定期删除: 指的是Redis每隔一定的时间(默认100ms,可重新配置)随机选择一些设置了过期时间的key,检查并决定是否删除。
惰性删除:每次现在获取的时候,都会检查是否过期。
存在一个极端情况,当定期删除没能选中某些数据,而这些数据也未被使用也就是不能惰性删除,那么会导致数据会越来越多,导致内存耗尽。

内存淘汰

主要提供几种

  1. noeviction: 当内存不够写,新写入会报错。
  2. allkeys-lru:内存不够时,针对所有的key,移除最近最少使用的key,和操作系统的LRU淘汰机制类似。
  3. allkeys-random:内存不够时,随机移除某个key.
  4. volatile-lru:当内存不够时,移除最近最少使用的key,但是是针对有过期时间的key。
  5. volatile-random:当内存不够时,随机移除某个key,但是是针对有过期时间的key.
  6. volatile-ttl: 当内存不够时,根据过期时间的顺序,把过期时间早的key移除。

高并发与高可用

高并发

主要依靠主从架构:和其他主从一样,就是一个节点负责写,其他节点负责读。

Redis replication
  1. 数据从主节点被写入,然后采用异步的方式更新到其他从节点,并且从节点会定时确认自己的数据是否正常。
  2. 从节点之间也可也有通信,但从节点不影响主节点的工作。(非阻塞)
  3. 从节点的在写入时,并非阻塞式,而是用新替旧的方式。
  4. 简单通过增加从节点,可以用提高Redis的吞吐量。
核心原理

当从节点第一次启动并连接主节点,会启动一次全量复制。复制的方式是由主节点生成一份RDB文件(类似镜像快照),同时将新的写入命令缓存。从节点收到RDB之后,先将它写入磁盘,再加载到内存。然后主节点将新写入的缓存命令发送给slave,继续同步这些数据。

断点续传

上述题到的主从复制核心原理,会发生网络不佳的情况,那么就会出现部分命令丢失的情况,这时候就需要用到断点续传。主要由主节点维护一个内存中的backlog,主从节点都会保存一个偏移量和id,其中偏移量是保存在backlog中,这样断开重连后还能重新开始传,id的话主要是用来定位主节点的。因为用ip来定位是不可靠的。

无磁盘化复制

主节点在内存中直接创建RDB,在配置文件的repl-diskless-sync配置项设置为yes就可以了。

过期处理

只有主节点才可以处理过期的key,并将淘汰命令同步到从节点。

心跳检测

主从节点会相互发送心跳信息,确认是否活着。

高可用

主要由哨兵来实现,哨兵有集群监控、消息通知、故障转移、配置中心的功能。并不保证数据的零丢失。

核心知识

哨兵至少需要3个实例,不保证数据完全不丢失,其中数据丢失主要发生在两种情况,一种是异步复制导致的数据丢失,另一种是脑裂导致的数据丢失(出现了两个master)。解决方法就是配置min-slaves-max-lag和min-slaves-to-write去尽量避免问题。

sdown和odown的转换机制

sdown是主观宕机的,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机。
odown是客观宕机,如果quorum数量的哨兵都觉得一个master宕机了,那么就是客观宕机。

自动发现机制

主要通过pub/sub实现,去互相交换信息对master的监控配置等。

选举算法(新的主节点如何产生)

首先按照从节点的优先级排序,然后按照从节点的复制偏移量。总而言之就是选择留有尽可能多的数据的从节点。

quorum和majority

每次一个哨兵要做主备切换,首先需要quorum数量的哨兵认为down,然后选举出一个哨兵来切换,同时得到主哨兵的授权。

Redis持久化

主要有两种方式,RDB和AOF

RDB

RDB持久化机制,是对Redis中的数据执行周期性的持久化。
RDB会生成多个数据文件,可以用来做备份。
RDB的性能很高,因为复制操作是由一个线程完成的。
由RDB恢复Redis进程更快。
但是RDB可能会丢失数据在故障情况下。
当RDB足够大的时候,会一定程度导致服务暂停。

AOF

把每条写入命令存入日志,通过回放日志来重新建立。
数据更安全,丢失的数据不会很多。
没有磁盘寻址的开销,性能高。
日志文件过大的时候,后台会重写,但不会影响客户端的重写,因为有压缩。
AOF的可读性较强,即使被删库也可恢复。
缺点是容量过大。

选择

成年人才做选择,可以都开启。

集群

在集群架构下,每个Redis会开启两个端口6379和16379,其中16379是用来节点间通信的,主要用总线的模式来进行,一般使用的是gossip协议,自动将数据进行分片,每个master上放一部分数据,提供内置的高可用支持,部分master不可用时可以继续工作。

内部通信机制
通信原理

分为集中式、Gossip协议两种。
集中式的原理类似与大数据里的storm,主要用zookeeper来实现。
Gossip协议则是一种达到分布式共识的传输协议。

分布式寻址算法
hash算法

对于key先计算hash值,然后对节点数取模。一旦某个master宕机,都会基于最新的剩余master节点去取模,尝试去取数据。导致大部分请求过来,无法拿到新的缓存。

一致性hash算法

将整个hash值空间组织成一个虚拟的圆环,整个空间按顺时针方向组织,下一步将各个master节点(使用ip和主机名)进行hash。从而确定位置。
如果一个节点挂了,受影响的只有一前面的那个节点。但是在节点太少时,容易因为节点分部不均匀而造成缓存热点的问题。所以引入了虚拟节点机制,即对每一个节点计算多个hash,每个计算结果位置都放置一个虚拟节点。

hash slot算法

Redis cluster 有固定的 16384 个 hash slot,对每个 key 计算 CRC16 值,然后对 16384 取模,可以获取 key 对应的 hash slot。
Redis cluster 中每个 master 都会持有部分 slot,比如有 3 个 master,那么可能每个 master 持有 5000 多个 hash slot。hash slot 让 node 的增加和移除很简单,增加一个 master,就将其他 master 的 hash slot 移动部分过去,减少一个 master,就将它的 hash slot 移动到其他 master 上去。移动 hash slot 的成本是非常低的。客户端的 api,可以对指定的数据,让他们走同一个 hash slot,通过 hash tag 来实现。
任何一台机器宕机,另外两个节点,不影响的。因为 key 找的是 hash slot,不是机器。

并发竞争的CAS方案

可以通过zookeeper实现分布式锁,确保同一时间只能有一个实例在操作某个key。
CAS的话是通过时间戳来作为版本号,这样可以有效避免ABA问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值