首页
归档
朋友
关于我
留言
Search
1
虚拟机无法ping不通百度,并无法访问浏览器
4,847 阅读
2
mysql使用or条件使索引失效
4,061 阅读
3
mysql如何在一对多查询时选取时间最近的一条记录
3,475 阅读
4
根据MySQL获取当天,昨天,本周,本月,上周,上月,本月的起始时间
2,927 阅读
5
熟悉mysql的共享锁、排它锁、悲观锁、乐观锁以及使用场景
1,766 阅读
PHP
面向对象
设计模式
知识汇总
常用函数
PHP框架知识
数据库
MySQL
服务器
Docker
虚拟机
Nginx
缓存相关
Redis
前端
中间件
RabbitMQ
网络编程
HTTP相关
Swoole
Workerman
工具软件
Git
Typecho
杂乱无章
面试指南
PHP相关
MySQL面试汇总
中间件相关
开发技巧 | 优化
登录
Search
标签搜索
php
mysql
代码片段
linux
Thinkphp
Redis
nginx
mysql优化
docker
面试指南
面向对象
git
Laravel框架
http协议
RabbitMQ
Redis性能优化
设计模式
linux命令
编译安装
PhpSpreadsheet
黎明强
累计撰写
70
篇文章
累计收到
59
条评论
首页
栏目
PHP
面向对象
设计模式
知识汇总
常用函数
PHP框架知识
数据库
MySQL
服务器
Docker
虚拟机
Nginx
缓存相关
Redis
前端
中间件
RabbitMQ
网络编程
HTTP相关
Swoole
Workerman
工具软件
Git
Typecho
杂乱无章
面试指南
PHP相关
MySQL面试汇总
中间件相关
开发技巧 | 优化
页面
归档
朋友
关于我
留言
搜索到
1
篇与
缓存
的结果
2022-06-18
Redis缓存的概念以及缓存异常处理
缓存的概念缓存是介入应用程序和物理数据之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高应用的运行性能。缓存内的数据对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻会同步缓存数据和物理数据源的数据。比如我们通常是直接查询MySQL数据库,那么在高并发情况下,大量查询MySQL数据库会导致数据库性能变慢。因此我们在应用层与MySQL之间搭建一个Cache层,让请求先访问Cache,这样能大大的降低数据库的压力,提高性能。分布式缓存简单来说,缓存系统能跨进程我们就称为分布式缓存在分布式系统开发中,系统与系统之间都是属于进程级别,缓存系统也能跨进程叫分布式缓存,市面上分布式技术有Memcached 和Redis 这两种,二者区别大致如下:性能Redis是单核的Memcahed是多核的内存空间和数据大小Memcached : 可以修改最大内存大小,进行LRU算法进行淘汰Redis : 不仅可以修改最大内存,因为redis的缓存是存储内存上的,一些数据可以通过VM的特性突破物理空间的限制。(可以理解:外挂一个磁盘当做数据存储源使用)操作比较Memcacehd : 操作比较单一,只有一种数据类型String,用来缓存。Redis : 支持比较丰富的数据类型,(String、哈希、集合、有序集合等),比如做一些签到、附近的人都可以(用bitmap、geo实现),减少服务端的操作,减少IO读写。可靠性Memcacehd :不支持持久化 ,断电重启数据就丢失,只能做缓存使用(需要重新从关系型数据库获取)Redis : 支持持久化 (RDB、AOF的2种机制) ,从持久化的数据磁盘加载并保存到缓存上,能处理单点故障、设置主从、集群、哨兵等机制。应用场景Memcacehd : 减轻数据库的压力,做缓存 (适合写少读多,或者纯读做缓存用的应用场景)Redis:也可以减少数据库的压力,做缓存,(对读多写多场景高 都适合),也可以实现比较复杂的业务实现(积分、签到、附近的人)谨慎考虑的部分Memcacehd :单个key-value的存储,value最大的上限是1M。只是内存缓存,对可靠性没太高要求。Reids :单String类型的key-value的存储,最大的上限是512M (42亿的字节)。Redis的可靠性强,可以理解内存性数据库。还有多个数据类型,一些高阶的数据类型,可以应付一些特殊的业务场景(签单存储bitMap , 附近的人Geo 、好友列表用Set)存储方式使用Redis做缓存的话,数据的存储结构有两种,一种采用String存储,另外使用Hashes 存储。那使用哪种更好呢?得具体情况具体分析:String 存储比较简单,固定的数据,比如存储一个简单的用户信息(用户名、昵称、头像、年龄等)。 存储时需要将数据进行序列化,获取时需要反序列化 , 在数据比较小的情况下还是可以忽略这种开销的。但如果存储的数据可能某些属性会有些变化,比如餐厅数据中,他有likeVotes(喜欢) 、 dislikeVotes(不喜欢)的数量,这类型的数据,那么我们采用Hashes 会更好,而且存储的时候没有序列化开销。官方推荐使用Hashes缓存异常解决如果缓存(异常)清空了,或者时间失效设计的不合理导致缓存删除,一下子突然千万用户访问进来导致数据库崩溃(应用宕机)缓存常见的三大经典问题:缓存击穿、缓存穿透、缓存雪崩缓存击穿原因存中的某个热点数据过期了,此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易就被高并发的请求冲垮,这就是缓存击穿的问题。解决方法:永不过期逻辑过期服务降级缓存穿透原因当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据,没办法构建缓存数据,来服务后续的请求。那么当有大量这样的请求到来时,数据库的压力骤增,这就是缓存穿透的问题。就是明知道这个Key不在缓存,也不在数据库里,请求大量的这种导致数据库压力剧增。解决布隆过滤器空值存储 (上面有说)互斥锁 (不推荐 , 拿到锁请求数据库,没拿到锁就等待阻塞,只要用到锁 用不好锁必然会降低性能损耗)异步更新服务降级缓存雪崩原因:当大量缓存数据在同一时间过期(失效) 或者 Redis 故障宕机 时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩的问题。解决随机失效时间双缓存 (用的不多,备份缓存,主数据失效了,那么去加载副的)互斥锁 (不推荐)服务降级其实最致命的是Redis节点故障,如果那个节点出问题访问不了缓存,那么数据的请求全怼在数据库里,造成数据库崩溃。解决方法:配置主从,集群、开启哨兵机制(防止某个节点宕机,如果某个节点宕机,就自动切换其他节点)缓存淘汰最大内存参数我们的redis数据库最大缓存、主键失效、淘汰机制等参数都是可以通过配置文件来配置的。这个文件是我们的redis.conf 文件。maxmemory <bytes> : 设置最大内存 #比如 maxmemory 500mb超过最大的内存,就会采用内存淘汰策略,执行淘汰,如下。内存淘汰策略截止目前redis一共为我们提供了八个不同的内存置换策略,很早之前提供了6种。# volatile-lru -> Evict using approximated LRU, only keys with an expire set. # allkeys-lru -> Evict any key using approximated LRU. # volatile-lfu -> Evict using approximated LFU, only keys with an expire set. # allkeys-lfu -> Evict any key using approximated LFU. # volatile-random -> Remove a random key having an expire set. # allkeys-random -> Remove a random key, any key. # volatile-ttl -> Remove the key with the nearest expire time (minor TTL) # noeviction -> Don't evict anything, just return an error on write operations. # # LRU means Least Recently Used # LFU means Least Frequently Used # # Both LRU, LFU and volatile-ttl are implemented using approximated # randomized algorithms. # # Note: with any of the above policies, Redis will return an error on write # operations, when there are no suitable keys for eviction. # # At the date of writing these commands are: set setnx setex append # incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd # sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby # zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby # getset mset msetnx exec sort # # The default is: # # maxmemory-policy noeviction默认不淘汰 , 开发中经常使用的是volatile-lruvolatile-lru:从已经设置过期时间的数据集中,挑选最近最少使用的数据淘汰。volatile-ttl:从已经设置过期时间的数据集中,挑选即将要过期的数据淘汰。volatile-random:从已经设置过期时间的数据集中,随机挑选数据淘汰。volatile-lfu:从已经设置过期时间的数据集中,会使用LFU算法选择设置了过期时间的键值对。allkeys-lru:从所有的数据集中,挑选最近最少使用的数据淘汰。allkeys-random:从所有的数据集中,随机挑选数据淘汰。no-enviction:禁止淘汰数据,如果redis写满了将不提供写请求,直接返回错误。注意这里的6种机制,volatile和allkeys规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的lru、ttl以及random是三种不同的淘汰策略,再加上一种no-enviction永不回收的策略使用策略规则:如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用 allkeys-lru如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用 allkeys-random淘汰机制的实现既然是淘汰,那就需要把这些数据给删除,然后保存新的Redis删除策略主要有以下几种:惰性删除内存没满,则使用了这个,不额外开启一个线程去删除,就是保证高性能,在重新获取key的时候就知道这个key是否过期存在。定时删除每隔一段时间获取过期的key进行删除主动删除(内存满了,就主动删除多余的Key)
2022年06月18日
264 阅读
0 评论
0 点赞