redis
Sebastian Lv4

常用redis,深入了解redis的性能和瓶颈。reference

介绍

redis: 内存中的数据结构存储系统,可以用作数据库缓存消息中间件,nosql的一种。

nosql

关系型数据库不够用,出来了nosql。。。

  1. 一开始单体应用,小用户量能承受。但是当体量变大时:
    • 数据量大
    • 数据的索引大
    • 访问量大
  2. 读写分离思想(垂直拆分),写一个库,其他库从这个库做同步,但是数据库大部分其实都是读,把刚查到的进行缓存,这样下一个要查且数据没变的话就用缓存中的数据。 添加一层memcache缓存
  3. 集群(水平拆分):上面的读写分离copy多份。

mysql早些年使用的是MyISAM引擎,特性是表锁(查询某个数据会将整个表锁起来,高并发下性能下滑),现在使用的是Innodb,改为了行锁

不能用mysql做实时存储和访问、个人信息、地理位置(如微信热门10万+的文章记录等)。

特点

  1. 易于扩展,数据间没有关系(key value键值对),好比java面向接口,便于解偶。
  2. 大数据量也高性能(写8万次/秒,读11万次/秒)
  3. 多样型,不需要事先设计数据库
  4. 没有固定的查询语言;最终一致性
  5. 键值对存储,列存储,文档存储,图形存储库(社交)
  6. 高性能、高可用、高可扩
  7. CAP、BASE,异地多活
  8. 多样、实时、并发(Volume, Variety, Veiocity)

与关系型一起使用。

商品的描述、评论(文字比较多的):文档型数据库(MongoDB)

商品的基本信息(价格、商家、名称):MySQL

图片:FastDFS, GFS, HDFS, OSS…

商品热门的波段信息:内存数据库(Redis,Tair,Memcache……)

==没有什么不是加以层解决不了的==: 统一服务层。

文档型数据库

MongoDB,介于关系型和非关系型数据库中的中间产品,非关系型数据库中功能最丰富的。

KV键值对

Redis,Tair

列存储数据库

HBase(大数据)

分布式文件系统

类似知识图谱,不是存储图形。主要用于存储社交网络。

Neo4j,InfoGrid。

Redis

Remote Dictionary Server. C语言编写的。免费,开源,提供多种语言的api。

  • 内存存储、持久化,但是内存是断电即失,所以持久化很重要(rdb、aof)
  • 计时器、计数器(浏览量)

测试

安装后自带的测试工具

1
redis-benchmark -h localhost -p 6379 -100 -n 100000

基础

默认16个数据库且使用的是第0个。

GEOSPATIAL

地理位置,不仅仅是GET、SET!根据经纬度获取距离。

springboot集成

版本<2.0 底层使用的jedis,BIO,直连数据库,多线程下不安全,优化方式是jedis pool连接池。

版本>2.0 底层使用的lettuce,NIO,采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况。

rdb

为什么会有这个rdb?

redis的高速查询来源于它的内存存储,由于内存断电即失,可以把rdb作为备份来弥补这个不足。所以rdb即redis databse。但是也不是每次操作都保存,否则性能急速降低,这也带来另一个问题,即最后一个/批操作不会被保存。

1
2
3
4
5
6
7
8
9
start=>start: start
end=>end: end
condition=>condition: 触发rdb
rdbfile=>inputoutput: dump.rdb
operation=>operation: go on dealing with

start->condition
condition(yes)->rdbfile->end
condition(no)->operation->end

触发机制

  1. save的规则
  2. 执行flushall
  3. 退出redis

产生备份,会自动生成一个dump.rdb

用rdb恢复

1
config get dir

优点:

  1. 适合大数据
  2. 对数据完整性要求不高(比如90srdb一次,60s的时候宕机,就会造成数据丢失)

缺点:

  1. 需要一定的时间间隔进程操作
  2. fork进程的时候会占用一定的内容空间

AOF

Append Only File, 将我们的所有命令都记录下来,相当于history,恢复的时候再追加。这是另一种恢复的方法。

  • 大数据的情况下效率会比较低。
  • 默认是不开启的。

开启后会记录操作记录,关闭redis的时候会产生aof文件,如果恶意篡改,redis无法正常启动。

修复aof文件 redis-check-aof --fix

优点:

  1. 每次修改都同步,文件的完整性更好,默认每秒同步一次,可能会丢失一秒的数据
  2. 从不同步效率最高

缺点:

  1. 相对于数据文件,aof远大于rdb,修复的速度比rdb慢
  2. 默认是rdb,效率自然高于aof。

与rdb混合使用

主从复制

将一台redis服务器的数据复制到其他的redis服务器,前者称为主节点,后者称为从结点。

作用:数据冗余、故障恢复、负载均衡(读写分离)、高可用(集群)基石

reids的容量有限,机器的内存不可能全部用来给redis做存储内存,最大不应该超过20G。

默认情况下每台redis都是主节点;一个主节点可以有多个从结点,但是一个从结点只能有一个主节点。

环境配置

1
info replication # 查看当前库的信息

一般情况下只用配置从机即可。

1
SLAVEOF ip:port # ip:port为主机

上面的是命令配置,只是暂时的。实际生产应该修改配置文件,在文件中写主机的地址和密码,主机负责写,从机负责读,主机的所有数据会自动被从机保存。

如果主机宕机了呢?

默认情况下,主机挂了以后,用info replication查看剩余机器,从机运行正常,但是没有写操作了。主机恢复后,仍旧正常主从复制。考虑到主机要人工手动恢复、排查故障,仍旧会影响业务。

更好的情况是,默认从剩余的从机中选择一个作为主机,继续完成写操作。

  • 全量复制 master将整个数据传送到slaver
  • 增量复制

只要重新链接master,一次全量复制将被自动执行

哨兵模式

Sentinel(Redis2.8起)后台监控主机是否故障,如果故障了根据投票数自动将从库转为主库。

哨兵是一个独立的进程。通过发送命令,等待Redis服务器响应,从而监控运行的多个redis实例。为了防止哨兵挂了,还要配置哨兵集群。(如果一主二从,正常应该启动六个进程,加上哨兵的话)

优点

  1. 集群
  2. 主从切换

缺点

  1. 不方便在线扩容,一旦到达上线。
  2. 配置麻烦(配置文件的内容很多)。简单的话可以只启动一个哨兵监控主机,会自动检测到从机。

redis异常处理

缓存穿透(一直查询不到)

1
2
3
4
5
6
7
start=>start: request
end=>end: response
condition=>condition: redis缓存中是否存在
op1=>operation: select in mysql
start->condition
condition(yes)->end
condition(no)->op1->end

如果请求量非常大,redis相当于空白,都去请求到dao层,redis的作用就没了。

布隆过滤器

它是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,避免了对底层存储系统的查询压力

缓存空对象

缓存击穿(量太大,缓存过期)

活力集中在一个点(一个热评的点,如微博)。

加互斥锁

设置热点数据永不过期

缓存雪崩

在某一个时间段,缓存集中过期失效,可能瞬间把数据库压跨。

redis高可用

限流降级

数据预热

正式部署前先把可能的数据访问一遍(加入缓存),设置不同的过期时间,让缓存失效的时间尽可能平均。