常用redis,深入了解redis的性能和瓶颈。reference
介绍
redis: 内存中的数据结构存储系统,可以用作数据库、缓存和消息中间件,nosql的一种。
nosql
关系型数据库不够用,出来了nosql。。。
- 一开始单体应用,小用户量能承受。但是当体量变大时:
- 数据量大
- 数据的索引大
- 访问量大
- 读写分离思想(垂直拆分),写一个库,其他库从这个库做同步,但是数据库大部分其实都是读,把刚查到的进行缓存,这样下一个要查且数据没变的话就用缓存中的数据。 添加一层memcache缓存
- 集群(水平拆分):上面的读写分离copy多份。
mysql早些年使用的是MyISAM引擎,特性是表锁(查询某个数据会将整个表锁起来,高并发下性能下滑),现在使用的是Innodb,改为了行锁。
不能用mysql做实时存储和访问、个人信息、地理位置(如微信热门10万+的文章记录等)。
特点
- 易于扩展,数据间没有关系(key value键值对),好比java面向接口,便于解偶。
- 大数据量也高性能(写8万次/秒,读11万次/秒)
- 多样型,不需要事先设计数据库
- 没有固定的查询语言;最终一致性
- 键值对存储,列存储,文档存储,图形存储库(社交)
- 高性能、高可用、高可扩
- CAP、BASE,异地多活
- 多样、实时、并发(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 | start=>start: start |
触发机制
- save的规则
- 执行flushall
- 退出redis
产生备份,会自动生成一个dump.rdb
用rdb恢复
1 | config get dir |
优点:
- 适合大数据
- 对数据完整性要求不高(比如90srdb一次,60s的时候宕机,就会造成数据丢失)
缺点:
- 需要一定的时间间隔进程操作
- fork进程的时候会占用一定的内容空间
AOF
Append Only File, 将我们的所有命令都记录下来,相当于history,恢复的时候再追加。这是另一种恢复的方法。
- 大数据的情况下效率会比较低。
- 默认是不开启的。
开启后会记录操作记录,关闭redis的时候会产生aof文件,如果恶意篡改,redis无法正常启动。
修复aof文件 redis-check-aof --fix
优点:
- 每次修改都同步,文件的完整性更好,默认每秒同步一次,可能会丢失一秒的数据
- 从不同步效率最高
缺点:
- 相对于数据文件,aof远大于rdb,修复的速度比rdb慢
- 默认是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实例。为了防止哨兵挂了,还要配置哨兵集群。(如果一主二从,正常应该启动六个进程,加上哨兵的话)
优点
- 集群
- 主从切换
缺点
- 不方便在线扩容,一旦到达上线。
- 配置麻烦(配置文件的内容很多)。简单的话可以只启动一个哨兵监控主机,会自动检测到从机。
redis异常处理
缓存穿透(一直查询不到)
1 | start=>start: request |
如果请求量非常大,redis相当于空白,都去请求到dao层,redis的作用就没了。
布隆过滤器
它是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,避免了对底层存储系统的查询压力
缓存空对象
缓存击穿(量太大,缓存过期)
活力集中在一个点(一个热评的点,如微博)。
加互斥锁
设置热点数据永不过期
缓存雪崩
在某一个时间段,缓存集中过期失效,可能瞬间把数据库压跨。
redis高可用
限流降级
数据预热
正式部署前先把可能的数据访问一遍(加入缓存),设置不同的过期时间,让缓存失效的时间尽可能平均。