当前位置: 首页 > news >正文

东莞 网站 建设 汽车python如何做网页

东莞 网站 建设 汽车,python如何做网页,wordpress小工具 登陆,找人做网站注意什么目录 1.什么是Redis缓存问题#xff1f; 2.缓存穿透 3.缓存击穿 4.缓存雪崩 5.缓存污染#xff08;或满了#xff09; 5.1 最大缓存设置多大 5.2 缓存淘汰策略 6.数据库和缓存一致性 6.1 4种相关模式 6.2 方案#xff1a;队列重试机制 6.3 方案#xff1a;异步更新缓…目录 1.什么是Redis缓存问题 2.缓存穿透 3.缓存击穿 4.缓存雪崩 5.缓存污染或满了 5.1 最大缓存设置多大 5.2 缓存淘汰策略 6.数据库和缓存一致性 6.1 4种相关模式 6.2 方案队列重试机制 6.3 方案异步更新缓存(基于订阅binlog的同步机制) 1.什么是Redis缓存问题 在高并发的业务场景下数据库大多数情况都是用户并发访问最薄弱的环节。所以就需要使用redis做一个缓冲操作让请求先访问到redis而不是直接访问Mysql等数据库。这样可以大大缓解数据库的压力。 当缓存库出现时必须要考虑如下问题 缓存穿透缓存穿击缓存雪崩缓存污染或者满了缓存和数据库一致性 2.缓存穿透 什么是缓存穿透 缓存穿透说简单点就是大量请求的 key 是不合理的根本不存在于缓存中也不存在于数据库中 。这就导致这些请求直接到了数据库上根本没有经过缓存这一层对数据库造成了巨大的压力可能直接就被这么多请求弄宕机了。 举个例子某个黑客故意制造一些非法的 key 发起大量请求导致大量请求落到数据库结果数据库上也没有查到对应的数据。也就是说这些请求最终都落到了数据库上对数据库造成了巨大的压力。 有什么解决办法吗 最基本的就是首先做好参数校验一些不合法的参数请求直接抛出异常信息返回给客户端。比如查询的数据库 id 不能小于 0、传入的邮箱格式不对的时候直接返回错误消息给客户端等等。 1缓存无效 key 如果缓存和数据库都查不到某个 key 的数据就写一个到 Redis 中去并设置过期时间具体命令如下SET key value EX 10086 。这种方式可以解决请求的 key 变化不频繁的情况如果黑客恶意攻击每次构建不同的请求 key会导致 Redis 中缓存大量无效的 key 。很明显这种方案并不能从根本上解决此问题。如果非要用这种方式来解决穿透问题的话尽量将无效的 key 的过期时间设置短一点比如 1 分钟。 如果用 Java 代码展示的话差不多是下面这样的 public Object getObjectInclNullById(Integer id) {// 从缓存中获取数据Object cacheValue cache.get(id);// 缓存为空if (cacheValue null) {// 从数据库中获取Object storageValue storage.get(key);// 缓存空对象cache.set(key, storageValue);// 如果存储数据为空需要设置一个过期时间(300秒)if (storageValue null) {// 必须设置过期时间否则有被攻击的风险cache.expire(key, 60 * 5);}return storageValue;}return cacheValue; }2布隆过滤器 布隆过滤器是一个非常神奇的数据结构通过它我们可以非常方便地判断一个给定数据是否存在于海量数据中。我们需要的就是判断 key 是否合法是不是感觉布隆过滤器就是我们想要找的那个正确答案。 具体是这样做的把所有可能存在的请求的值都存放在布隆过滤器中当用户请求过来先判断用户发来的请求的值是否存在于布隆过滤器中。不存在的话直接返回请求参数错误信息给客户端存在的话才会走下面的流程。 加入布隆过滤器之后的缓存处理流程图如下。 但是需要注意的是布隆过滤器可能会存在误判的情况。总结来说就是布隆过滤器说某个元素存在小概率会误判。布隆过滤器说某个元素不在那么这个元素一定不在。 为什么会出现误判的情况呢? 我们还要从布隆过滤器的原理来说 我们先来看一下当一个元素加入布隆过滤器中的时候会进行哪些操作 使用布隆过滤器中的哈希函数对元素值进行计算得到哈希值有几个哈希函数得到几个哈希值。根据得到的哈希值在位数组中把对应下标的值置为 1。 我们再来看一下当我们需要判断一个元素是否存在于布隆过滤器的时候会进行哪些操作 对给定元素再次进行相同的哈希计算得到值之后判断位数组中的每个元素是否都为 1如果值都为 1那么说明这个值在布隆过滤器中如果存在一个值不为 1说明该元素不在布隆过滤器中。 然后一定会出现这样一种情况不同的字符串可能哈希出来的位置相同。 可以适当增加位数组大小或者调整我们的哈希函数来降低概率 3.缓存击穿 什么是缓存击穿 缓存击穿中请求的 key 对应的是 热点数据 该数据 存在于数据库中但不存在于缓存中通常是因为缓存中的那份数据已经过期 。这就可能会导致瞬时大量的请求直接打到了数据库上对数据库造成了巨大的压力可能直接就被这么多请求弄宕机了。 举个例子秒杀进行过程中缓存中的某个秒杀商品的数据突然过期这就导致瞬时大量对该商品的请求直接落到数据库上对数据库造成了巨大的压力。 有什么解决办法吗 设置热点数据永不过期或者过期时间比较长。针对热点数据提前预热将其存入缓存中并设置合理的过期时间比如秒杀场景下的数据在秒杀结束之前不过期。请求数据库写数据到缓存之前先获取互斥锁保证只有一个请求会落到数据库上减少数据库的压力。 缓存穿透和缓存击穿有什么区别 缓存穿透中请求的 key 既不存在于缓存中也不存在于数据库中。 缓存击穿中请求的 key 对应的是 热点数据 该数据 存在于数据库中但不存在于缓存中通常是因为缓存中的那份数据已经过期 。  4.缓存雪崩 什么是缓存雪崩 实际上缓存雪崩描述的就是这样一个简单的场景缓存在同一时间大面积的失效导致大量的请求都直接落到了数据库上对数据库造成了巨大的压力。 这就好比雪崩一样摧枯拉朽之势数据库的压力可想而知可能直接就被这么多请求弄宕机了。 另外缓存服务宕机也会导致缓存雪崩现象导致所有的请求都落到了数据库上。 举个例子数据库中的大量数据在同一时间过期这个时候突然有大量的请求需要访问这些过期的数据。这就导致大量的请求直接落到数据库上对数据库造成了巨大的压力。 有哪些解决办法 针对 Redis 服务不可用的情况 采用 Redis 集群避免单机出现问题整个缓存服务都没办法使用。限流避免同时处理大量的请求。 针对热点缓存失效的情况 设置不同的失效时间比如随机设置缓存的失效时间。缓存永不失效不太推荐实用性太差。设置二级缓存。 缓存雪崩和缓存击穿有什么区别 缓存雪崩和缓存击穿比较像但缓存雪崩导致的原因是缓存中的大量或者所有数据失效缓存击穿导致的原因主要是某个热点数据不存在与缓存中通常是因为缓存中的那份数据已经过期。  5.缓存污染或满了 缓存污染问题说的是缓存中一些只会被访问一次或者几次的的数据被访问完后再也不会被访问到但这部分数据依然留存在缓存中消耗缓存空间。 缓存污染会随着数据的持续增加而逐渐显露随着服务的不断运行缓存中会存在大量的永远不会再次被访问的数据。缓存空间是有限的如果缓存空间满了再往缓存里写数据时就会有额外开销影响Redis性能。这部分额外开销主要是指写的时候判断淘汰策略根据淘汰策略去选择要淘汰的数据然后进行删除操作。 5.1 最大缓存设置多大 系统的设计选择是一个权衡的过程大容量缓存是能带来性能加速的收益但是成本也会更高而小容量缓存不一定就起不到加速访问的效果。一般来说我会建议把缓存容量设置为总数据量的 15% 到 30%兼顾访问性能和内存空间开销。 对于 Redis 来说一旦确定了缓存最大容量比如 4GB你就可以使用下面这个命令来设定缓存的大小了 不过缓存被写满是不可避免的, 所以需要数据淘汰策略。  5.2 缓存淘汰策略 Redis共支持八种淘汰策略分别是noeviction、volatile-random、volatile-ttl、volatile-lru、volatile-lfu、allkeys-lru、allkeys-random 和 allkeys-lfu 策略。 怎么理解呢主要看分三类看 不淘汰 noeviction v4.0后默认的对设置了过期时间的数据中进行淘汰 随机volatile-randomttlvolatile-ttllruvolatile-lrulfuvolatile-lfu全部数据进行淘汰 随机allkeys-randomlruallkeys-lrulfuallkeys-lfu 具体分析如下 1.noeviction 该策略是Redis的默认策略。在这种策略下一旦缓存被写满了再有写请求来时Redis 不再提供服务而是直接返回错误。这种策略不会淘汰数据所以无法解决缓存污染问题。一般生产环境不建议使用。 其他七种规则都会根据自己相应的规则来选择数据进行删除操作。 2.volatile-random 这个算法比较简单在设置了过期时间的键值对中进行随机删除。因为是随机删除无法把不再访问的数据筛选出来所以可能依然会存在缓存污染现象无法解决缓存污染问题。 3.volatile-ttl 这种算法判断淘汰数据时参考的指标比随机删除时多进行一步过期时间的排序。Redis在筛选需删除的数据时越早过期的数据越优先被选择。 4.volatile-lru LRU算法LRU 算法的全称是 Least Recently Used按照最近最少使用的原则来筛选数据。这种模式下会使用 LRU 算法筛选设置了过期时间的键值对。 详细LRU算法可看此博客LRU缓存淘汰算法详解与实现_北~笙的博客-CSDN博客 Redis优化的LRU算法实现 Redis会记录每个数据的最近一次被访问的时间戳。在Redis在决定淘汰的数据时第一次会随机选出 N 个数据把它们作为一个候选集合。接下来Redis 会比较这 N 个数据的 lru 字段把 lru 字段值最小的数据从缓存中淘汰出去。通过随机读取待删除集合可以让Redis不用维护一个巨大的链表也不用操作链表进而提升性能。 Redis 选出的数据个数 N通过 配置参数 maxmemory-samples 进行配置。个数N越大则候选集合越大选择到的最久未被使用的就更准确N越小选择到最久未被使用的数据的概率也会随之减小。 5.volatile-lfu 会使用 LFU 算法选择设置了过期时间的键值对。 LFU 算法LFU 缓存策略是在 LRU 策略基础上为每个数据增加了一个计数器来统计这个数据的访问次数。当使用 LFU 策略筛选淘汰数据时首先会根据数据的访问次数进行筛选把访问次数最低的数据淘汰出缓存。如果两个数据的访问次数相同LFU 策略再比较这两个数据的访问时效性把距离上一次访问时间更久的数据淘汰出缓存。 Redis的LFU算法实现: 当 LFU 策略筛选数据时Redis 会在候选集合中根据数据 lru 字段的后 8bit 选择访问次数最少的数据进行淘汰。当访问次数相同时再根据 lru 字段的前 16bit 值大小选择访问时间最久远的数据进行淘汰。 Redis 只使用了 8bit 记录数据的访问次数而 8bit 记录的最大值是 255这样在访问快速的情况下如果每次被访问就将访问次数加一很快某条数据就达到最大值255可能很多数据都是255那么退化成LRU算法了。所以Redis为了解决这个问题实现了一个更优的计数规则并可以通过配置项来控制计数器增加的速度。 6.allkeys-lru 使用 LRU 算法在所有数据中进行筛选。具体LFU算法跟上述 volatile-lru 中介绍的一致只是筛选的数据范围是全部缓存这里就不在重复。 7.allkeys-random 从所有键值对中随机选择并删除数据。volatile-random 跟 allkeys-random算法一样随机删除就无法解决缓存污染问题。 8.allkeys-lfu 使用 LFU 算法在所有数据中进行筛选。具体LFU算法跟上述 volatile-lfu 中介绍的一致只是筛选的数据范围是全部缓存这里就不在重复。 allkeys-lfu 策略是 Redis 4.0 后新增。 6.数据库和缓存一致性 问题来源 使用redis做一个缓冲操作让请求先访问到redis而不是直接访问MySQL等数据库 读取缓存步骤一般没有什么问题但是一旦涉及到数据更新数据库和缓存更新就容易出现缓存(Redis)和数据库MySQL间的数据一致性问题。 不管是先写MySQL数据库再删除Redis缓存还是先删除缓存再写库都有可能出现数据不一致的情况。举一个例子 1.如果删除了缓存Redis还没有来得及写库MySQL另一个线程就来读取发现缓存为空则去数据库中读取数据写入缓存此时缓存中为脏数据。 2.如果先写了库在删除缓存前写库的线程宕机了没有删除掉缓存则也会出现数据不一致情况。 因为写和读是并发的没法保证顺序,就会出现缓存和数据库的数据不一致的问题。  6.1 4种相关模式 更新缓存的的Design Pattern有四种Cache aside Pattern, Read through, Write through, Write behind caching;  这里主要来看最常用的Cache Aside Pattern, 总结来说就是 读的时候先读缓存缓存没有的话就读数据库然后取出数据后放入缓存同时返回响应。更新的时候先更新数据库然后再删除缓存。 其具体逻辑如下 失效应用程序先从cache取数据没有得到则从数据库中取数据成功后放到缓存中。命中应用程序从cache中取数据取到后返回。更新先把数据存到数据库中成功后再让缓存失效。 注意我们的更新是先更新数据库成功后让缓存失效。那么这种方式是否可以没有文章前面提到过的那个问题呢我们可以脑补一下。 一个是查询操作一个是更新操作的并发首先没有了删除cache数据的操作了而是先更新了数据库中的数据此时缓存依然有效所以并发的查询操作拿的是没有更新的数据但是更新操作马上让缓存的失效了后续的查询操作再把数据从数据库中拉出来。而不会像文章开头的那个逻辑产生的问题后续的查询操作一直都在取老的数据。 那么是不是Cache Aside这个就不会有并发问题了不是的比如一个是读操作但是没有命中缓存然后就到数据库中取数据此时来了一个写操作写完数据库后让缓存失效然后之前的那个读操作再把老的数据放进去所以会造成脏数据。 但这个case理论上会出现不过实际上出现的概率可能非常低因为这个条件需要发生在读缓存时缓存失效而且并发着有一个写操作。而实际上数据库的写操作会比读操作慢得多而且还要锁表而读操作必需在写操作前进入数据库操作而又要晚于写操作更新缓存所有的这些条件都具备的概率基本并不大。 6.2 方案队列重试机制 流程如下所示 更新数据库数据缓存因为种种问题删除失败将需要删除的key发送至消息队列自己消费消息获得需要删除的key继续重试删除操作直到成功 然而该方案有一个缺点对业务线代码造成大量的侵入。于是有了方案二在方案二中启动一个订阅程序去订阅数据库的binlog获得需要操作的数据。在应用程序中另起一段程序获得这个订阅程序传来的信息进行删除缓存操作。 6.3 方案异步更新缓存(基于订阅binlog的同步机制) 整体思路 MySQL binlog增量订阅消费消息队列增量数据更新到redis 1读Redis热数据基本都在Redis 2写MySQL: 增删改都是操作MySQL 3更新Redis数据MySQ的数据操作binlog来更新到Redis Redis更新 1数据操作主要分为两大块 一个是全量(将全部数据一次写入到redis)一个是增量实时更新 这里说的是增量,指的是mysql的update、insert、delate变更数据。 2读取binlog后分析 利用消息队列,推送更新各台的redis缓存数据。 这样一旦MySQL中产生了新的写入、更新、删除等操作就可以把binlog相关的消息推送至RedisRedis再根据binlog中的记录对Redis进行更新。 其实这种机制很类似MySQL的主从备份机制因为MySQL的主备也是通过binlog来实现的数据一致性。 这里可以结合使用canal(阿里的一款开源框架)通过该框架可以对MySQL的binlog进行订阅而canal正是模仿了mysql的slave数据库的备份请求使得Redis的数据更新达到了相同的效果。 当然这里的消息推送工具你也可以采用别的第三方kafka、rabbitMQ等来实现推送更新Redis。
http://www.w-s-a.com/news/104739/

相关文章:

  • 公司 网站 方案高考写作网站
  • 网站后台如何登陆网站开发需求逻辑图
  • 市级档案网站建设情况分析server2008做DNS与网站
  • 公积金门户网站建设方案网站建设代理平台怎么做
  • 网站建设知识论文抖音开放平台是干什么的
  • 网站建设期末试卷大气简洁网站
  • 电子商务网站建设报告范文单位做网站怎么做
  • 优质的外国网站qq小程序在哪里打开
  • 商务网站建设与推广实训报告免费素材网站无水印
  • 外贸站seoapp开发公司历程概述
  • 沈阳网站推广¥做下拉去118cr陶瓷企业 瓷砖地板公司网站建设
  • 医院网站官方微信精神文明建设我做服装设计师的 求推荐资源网站
  • 微信网站建设需要那些资料昆明cms模板建站
  • 安庆网站建设兼职中企动力是500强吗
  • 网站排名优化技巧基于网站的网络营销方法有哪些
  • 摄影素材网站做知识问答的网站
  • 中小企业网站建设济南兴田德润电话门店管理系统软件排行
  • 昆明工程建设信息网站柳州网站建设公司哪家好
  • 如何分析网站关键词北京门户网站网址
  • 做网站与做游戏那个好网站域名怎么起
  • 有没有做cad单的网站银行网站建设方案视频
  • 和各大网站做视频的工作高校网站群管理系统
  • 中国建设人才服务信息网是正规网站怎么注销自己名下的公司
  • 网站开发新型技术那些网站做任务领q币
  • 海口手机网站建设wordpress微支付宝
  • 做公司网站需要几天深圳自定义网站开发
  • 做网站学多长时间可以学会推广软件公司
  • 网络网站设计培训长沙建站模板大全
  • 站群搭建移动端处理器天梯图
  • 岳池发展建设集团有限公司门户网站湛江seo咨询