说明:使用缓存可以有效的降低用户访问物理设备的频次.快速从内存中获取数据,之后返回给用户,同时需要保证内存中的数据就是数据库数据.
思考:
1.缓存的运行环境应该在内存中.(快)
2.使用C语言开发缓存
3.缓存应该使用什么样的数据结构呢--------K-V结构 一般采用String类型居多 key必须唯一 . v:JSON格式
4.内存环境断电即擦除,所以应该将内存数据持久化(执行写盘操作)
5.如果没有维护内存的大小,则容易导致 内存数据溢出. 采用LRU算法优化!!!

redis介绍

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
原子性说明: Redis的操作是单进程单线程操作,所以没有线程并发性的安全问题. 采用队列的方式一个一个操作.

用法

缓存
数据库
消息中间件(因为支持链表结构,所以可以

安装redis

只需要在redis根目录下依次执行make和make install命令即可

配置

注释ip绑定 #bind 127.0.0.1
关闭保护模式 protected-mode no
开启后台启动 daemonize yes

命令

1.启动命令: redis-server redis.conf
2.检索命令: ps -ef | grep redis
3.进入客户端: redis-cli -p 6379
4.关闭redis: kill -9 PID号 | redis-cli -p 6379 shutdown

基本方法

jedis.setex("key",time,"val"):向redis插入规定超时时间的数据
jedis.setnx("key","val"):jedis里存在key则不变,不存在则修改
jedis.set("key","val",new setParam().ex(time).nx
jedis.multi():开启事务
jedis.exec():提交事务
jedis.discard():回滚事务

分布式锁机制

同步锁只能解决tomcat内部问题,不能解决多态tomcat并发问题.
思想:
1.锁应该使用第三方操作 ,锁应该公用.
2.原则:如果锁被人正在使用时,其他的用户不能操作.
3.策略: 用户向redis中保存一个key,如果redis中有key表示有人正在使用这把锁 其他用户不允许操作.如果redis中没有key ,则表示我可以使用这把锁.
4.风险: 如何解决死锁问题. 设定超时时间.
V[5@K)DG~(~[)}8$LB)C4_U.png

aop

可通过aop来控制哪些方法使用缓存

Redis持久化策略

RDB
特点:
1.RDB模式是redis的默认的持久化策略.
2.RDB模式记录的是Redis 内存数据的快照. 最新的快照会覆盖之前的内容 所有RDB持久化文件占用空间更小 持久化的效率更高.
3.RDB模式由于是定期持久化 所以可能导致数据的丢失.

命令:

  1. save 要求立即马上持久化 同步的操作 其他的redis操作会陷入阻塞的状态.
  2. bgsave 开启后台运行 异步的操作 由于是异步操作,所以无法保证rdb文件一定是最新的需要等待.FC8BJMI)}NVXRXG5YA55}Z3.png
    AOF
    特点:
    1.AOF模式默认条件下是关闭的,需要用户手动的开启
  3. AOF模式是异步的操作 记录的是用户的操作的过程 可以防止用户的数据丢失
  4. 由于AOF模式记录的是程序的运行状态 所以持久化文件相对较大,恢复数据的时间长.需要人为的优化持久化文件

    Redis内存优化策略

    1.LRU 最近最少使用.最常用最好的算法
    2.LFU 最不经常使用.
    3.Random 随机算法
    4.TTL 把设定了超时时间的数据将要移除的提前删除的算法.

Redis分片机制

当海量数据存在redis中时,会严重影响我们的查询效率,所以引入了redis分片机制,实现扩容.
springboot实现reids分片
EUP9@5_[_9JCE70W6O{{)]M.png

一致性hash算法

平衡性平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题.由于会出现节点位置不均的情况,所以引入了虚拟节点的概念,来尽可能的达到均分.
单调性集群在删除或新增节点时,不会影响系统的运行.
分散性数据应该分散的放在集群中的各个节点.

Redis哨兵机制

Redis分片实现了内容扩容,但只要有一台宕机就会导致整个服务出问题,所以引入了Redis哨兵机制,相当于Redis的代理,实现高可用性.
哨兵机制先得实现Redis之间得主从挂载.
命令:slaveof ip 端口
检查主从状态:info replication
原理说明:
1.配置redis主从的结构.
2.哨兵服务启动时,会监控当前的主机. 同时获取主机的详情信息(主从的结构)
3.当哨兵利用心跳检测机制(PING-PONG) 连续3次都没有收到主机的反馈信息则断定主机宕机.
4.当哨兵发现主机宕机之后,则开启选举机制,在当前的从机中挑选一台Redis当做主机.
5.将其他的redis节点设置为新主机的从.
image.png
springboot实现哨兵机制
YQ]YFZ(IIB%~WD2]QRR}89Q.png

Redis集群

由于redis分片机制只实现扩容,不支持高可用,而redis哨兵只能实现高可用.所以引出了redis集群机制

选举机制 脑裂现象

当集群选举时,连续三次出现平票结果则可能出现脑裂现象.
预防:只能通过多设主节点来预防脑裂.

springboot整合redis集群
image.png

Redission 分布式锁
image.png
lock()相当于存储了一个有超时时间的key
unlock()通过方法延时自调来重新设置key失效时间,达到锁续命。底层都是大量lua脚本

jedis.setnx()方法高并发下可能发生业务时间超过锁失效时间,导致删除其他线程设置的key。
可通过增加uuid等标识来优化,但可能出现线程1做完uuid判断之后,(卡顿或gc等情况)锁正好失效,导致又删除其他线程的key。

分布式锁是将并发程序串行化,降低了性能。可考虑将锁粒度缩小(不必要的提出去)、分段锁(200个商品分成10份)等方式优化

缓存数据库双写不一致
9e22164f08e8851de49f8253720e6f2.png

读多写少的场景:可使用redission的读写锁来实现,读写才会互斥
读多写多:一般就不会使用缓存了,但数据库扛不住的话就得使用分布式数据库(tidb)。或者根据业务给缓存设定失效时间


啦啦啦
1 声望0 粉丝