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问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值