# Redis

# Nosql 特点

1、方便扩展(数据之间没有关系)

2、大数据量高性能(Redis 一秒写入 8 万,读区 11 万,Nosql 的缓存记录级,是一种细粒度 的缓存)

3、数据类型多样(不需要提前设计)

# Nosql 分类

键值类型:Key 指向 value 的键值对,通常用 hash table 来实现

列存储数据库:以列簇存储,将同一列数据存在一起

文档型数据库:Key-Value 对应的键值对,Value 为结构化数据

图形数据库:图结构

# redis 基本知识

redis 默认有 16 个数据库,默认使用第一个数据库,可以使用 select [编号] 来切换数据库

# 五种基本数据结构

1. String

2. List

3. Set

4. Hash

5. Zset

# 三种特殊数据类型

1. Geospatial

存储城市地理位置经纬度;

计算两个位置之间直线距离;

查找我(自己经纬度位置)附近的指定半径之内的附近的人;

2. Hyperloglog

3. Bitmap

# redis 实现乐观锁

使用 watch 监视实现乐观锁

  1. multi,开启 redis 的事物
  2. exec,提交事务执行从 multi 到此命令前到命令队列
  3. discard,取消事务,置客户端为非事物态
  4. watch,监视键值对,作用时,如果事务提交 exec 时发现监视的监视对发生变化,事务将被取消

# Redis 事务

Redis 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端送来的命令请求打断。

Redis 事务的作用就是 串联多个命令 防止别的命令插队。

事务的三个命令:

1. multi

2. exec

3. discard

组队当中的某一个命令失败,整个队列命令都会取消

组队没有失败,但是执行时候失败了,只有失败命令取消

redis 事务三大特性

  • 单独的隔离操作
  • 没有隔离级别的概念
  • 不保证原子性操作

redis 并发情况下连接超时可通过连接池解决

# 悲观锁和乐观锁

** 悲观锁:** 认为很悲观,每次去拿数据的时候都认为别人回修改,所以每次都会在拿数据的时候上锁,这样别人想拿数据的时候就会阻塞,直到她拿到锁。

在关系型数据库当中就用到了这种锁机制,如行锁,表锁等,读锁,写锁等,都是在操作之前先上锁

** 乐观锁:** 乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果冲突,则返回给用户异常信息,让用户决定如何去做。乐观锁适用于读多写少的场景,这样可以提高程序的吞吐量。

# redis 持久化

# 1.RDB

** 概念:** 在指定的时间间隔内将内存中的数据集快照写入磁盘

** 原理:**redis 会单独创建一个子线程进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结速了,再用这个临时文件替换上次持久化好的文件,整个过程中,主线程不用进行任何的 IO 操作,这就确保了极高的性能,如果需要大规模数据恢复,且对于数据的完整性不是很敏感,那么 RDB 方式要比 AOF 方式高效

** 缺点:** 最后一次持久化的数据可能会丢失

优点:

  • 适合大规模的数据恢复
  • 对完整性和一致性要求不高的
  • 节省磁盘空间
  • 恢复速度快

劣势:

  • fork 时候,内存中数据被克隆了一份,所以需要二倍的内存空间需求
  • 虽容 redis 采用了写时拷贝技术,但是数据量大时候还是很费性能
  • 在备份周期的一定时间间隔内做一次备份,如果在这个时间间隔内 redis 退出,数据将会丢失

# 2.AOF

概念:

以日志的形式来记录每个写操作,不记录读操作,将 redis 执行过的所有指令记录下来,只许追加文件,不许改写文件,redis 启动之初会读取文件重新构建数据

如果 RDB 和 AOF 同时开启,默认使用 AOF 恢复数据,因为 AOF 不会存在数据丢失

异常恢复

1. 如果遇到 AOF 文件损坏,可以先停止 redis

2. 然后通过 Redis-check-aof --fix appendonly.aof 命令进行修复

3. 然后重新启动即可

AOF 同步频率设置

appendfsync always

始终进行同步,每次 redis 写入都会立刻计入日志,但是性能较差,完整性好

appendfsync everysec

每秒同步,每秒计入日志一次,如果宕机,本秒数据可能丢失

appendfsync no

redis 不主动进行同步,把同步时机交给操作系统

重写追加操作

AOF 采用文件追加方式,文件会越来越大,为了避免出现此操作,新增了重写机制,当 AOF 文件的大小超过所设定的阀值,redis 就会启动 AOF 文件内容压缩,只保留可以恢复数据的最小指令集,

例如

set test 1
set test2 2

只记录最终结果 set test 1 test2 2

优点

  • 备份机制更稳定,丢失数据概率更低
  • 可读的日志文件,通过操作 AOF 文件,可以处理误操作

劣势

  • 比起 RDB 占用更多对磁盘空间

  • 恢复备份速度慢

  • 每次读写都同步,需要一定压力

# 主从复制

** 概念:** 主机数据更新后根据配置和策略,自动同步到备机的 master/slaver 机制,master 以写为主,slave 以读为主

作用

  • 读写分离,性能扩展
  • 容灾快速恢复

配置:

1. 以一主二从为例,创建一个文件夹 myredis,复制 redis.conf 到该文件夹

2. 再创建主从服务配置文件,redis6379.conf,redis6380,redis6381.conf

3. 里面内容为

#引入公共部分
include ./redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb

另外两个类似,只需更改文件名以及端口即可

4. 分别运行命令 redis-server [redis6379.conf路径]

5. 在从机上分别运行 slaveof <主机ip> <主机端口> 即可

主从复制原理:

从服务器启动之后会主动向主服务器发送一个同步到命令

主服务器接到命令之后,启动后台存盘进程,同时收集所有接收到用于修改数据集命令,在后台进程执行完毕之后,master 将整个数据文件一次性同步给从服务器

从服务器收到后,将数据库文件加载到内存当中

主服务器继续将新的收集到的修改命令依次传给从服务器

# 哨兵模式

当在主从服务器运行当中,会出现主机挂掉情况发生,但是又不能马上执行切换主机,可以利用哨兵模式进行监视主机运行情况,如果主机挂掉将会马上重新选择新的从机作为主机

创建配置文件: sentinel.conf

内容

sentinel monitor my master 127.0.0.1 6379 1

结尾 1 表示,只要有一个哨兵认为主机挂掉,那么就换新的主机

** 执行命令:**Redis-sentinel sentinel.conf

选取主机规则:

  • 优先级靠前的优先设置,在配置文件 redis.conf 中默认 slave-priority 100,值越小,优先级越高
  • 选取偏移量大的,偏移量是指获得原主机数据最全的
  • 选择 runid 最小的从服务器,每个 redis 启动后会随机生成一个 40 位的 runid

# 集群

集群的作用:

  • 分散单台服务器的访问压力,实现负载均衡
  • 分散单台服务器的存储压力,实现可扩展性
  • 降低单台服务器宕机带来的业务灾难

数据存储设计

什么是 slots

一个 redis 集群当中包含 16384 个插槽,数据库中的每个键都属于这 16384 个插槽的其中一个

  • 将所有的存储空间切割成 16384 份,每台主机保存一部分,每份代表的是一个存储空间,不是一个 key 的保存空间
  • 按照对 key 进行哈希计算的结果对 16384 进行取模得到的结果就是存储空间的位置,公式:CRC16(key)%16384

# redis 应用问题

# 缓存穿透

1. 应用服务器压力变大

2.redis 命中率降低,一直查不到缓存

3. 那么服务器就会一直向数据库发起查询请求,造成数据库崩溃

出现原因:

1.redis 查询不到数据库

2. 出现很多非正常 url 访问

解决方案:

  • 对空值做缓存:如果一个查询为空的值(不管数据是否存在),我们仍然将这个空结果进行缓存,设置空结果过期时间会很短
  • 设置可访问名单
  • 布隆过虑器

# 缓存击穿

1. 数据库访问压力瞬间增加

2.redis 中没有出现大量 key 过期

3.redis 正常运行

原因:

redis 当中某个 key 过期了。正好这个 key 正在被大量访问

解决方案:

  • 预先设置热门数据,提高生命周期

  • 实时监控,发现哪些热门数据频繁访问,调整该数据生命周期

  • 使用锁:

    1. 从缓存中读数据

    2. 缓存中不存在数据

    3. 获取锁。获取成功,去数据库取数据

    4. 更新缓存数据

    5. 释放锁

# 缓存雪崩

数据库压力变大,导致服务器崩溃

原因:

在极短时间内,查询大量 key,并且 key 集中过期的情况

解决方案:

  • 构建多级缓存架构
  • 使用锁或者队列限制读写
  • 设置过期标志更新缓存:当某个 key 快过期时候,通知另一个线程去后台更新缓存
  • 将缓存失效时间分散开,不要设置统一失效时间

# 分布式锁

随着业务发展,原本单机部署的系统被演化成分布式集群系统后,由于分布式系统多线程,多进程分布在不同的机器上,这使得原本单机部署的并发控制锁策略失效,为了解决这一问题就是分布式锁需要解决的

上锁: setnx

删除锁: del

为了防止上锁一直不释放,可以设置过期时间

expire test 10

为了防止过期时间无法设置情况,可以使用原子操作进行上锁

set test 10 nx ex 10	//nx表示上锁,ex表示过期时间
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Charmber 微信支付

微信支付

Charmber 支付宝

支付宝

Charmber 贝宝

贝宝