如何建设公众平台网站万网域名怎么绑定网站
- 作者: 五速梦信息网
- 时间: 2026年03月21日 09:52
当前位置: 首页 > news >正文
如何建设公众平台网站,万网域名怎么绑定网站,网站建设明细表,广州网络推广外包平台当前代码为8.0版接上一步
当前文档源码#xff0c;接上一篇博客 Redis7实战加面试题-高阶篇#xff08;手写Redis分布式锁#xff09; 逐步深入#xff0c;引入Redlock
自研一把分布式锁,面试中回答的主要考点
1.按照UC里面java.util.concurrent.locks.Lock接口规范编写…当前代码为8.0版接上一步
当前文档源码接上一篇博客 Redis7实战加面试题-高阶篇手写Redis分布式锁 逐步深入引入Redlock
自研一把分布式锁,面试中回答的主要考点
1.按照UC里面java.util.concurrent.locks.Lock接口规范编写 2.lock()加锁关键逻辑 加锁加锁实际上就是在redis中给Key键设置一个值为避免死锁并给定一个过期时间 自旋 续期 3.unlock解锁关键逻辑将Key键删除。但也不能乱删不能说客户端1的请求将客户端2的锁给删除掉只能自己删除自己的锁 上面自研的redis锁对于一般中小公司不是特别高并发场景足够用了单机redis小业务也撑得住
Redis分布式锁-Redlock红锁算法Distributed locks with Redis
官网https://redis.io/docs/manual/patterns/distributed-locks/ 为什么学习这个?怎么产生的? 线程 1 首先获取锁成功将键值对写入 redis 的 master 节点在 redis 将该键值对同步到 slave 节点之前master 发生了故障redis 触发故障转移其中一个 slave 升级为新的 master此时新上位的master并不包含线程1写入的键值对因此线程 2 尝试获取锁也可以成功拿到锁此时相当于有两个线程获取到了锁可能会导致各种预期之外的情况发生例如最常见的脏数据。 我们加的是排它独占锁同一时间只能有一个建redis锁成功并持有锁严禁出现2个以上的请求线程拿到锁。危险的 Redlock算法设计理念 redis之父提出了Redlock算法解决这个问题 Redis也提供了Redlock算法用来实现基于多个实例的分布式锁。锁变量由多个实例维护即使有实例发生了故障锁变量仍然是存在的客户端还是可以完成锁操作。Redlock算法是实现高可靠分布式锁的一种有效解决方案可以在实际开发中使用。 设计理念 该方案也是基于set 加锁、Lua 脚本解锁进行改良的所以redis之父antirez 只描述了差异的地方大致方案如下。 假设我们有N个Redis主节点例如 N 5这些节点是完全独立的我们不使用复制或任何其他隐式协调系统为了取到锁客户端执行以下操作 该方案为了解决数据不一致的问题直接舍弃了异步复制只使用 master 节点同时由于舍弃了 slave为了保证可用性引入了 N 个节点官方建议是 5。演示用3台实例来做说明。客户端只有在满足下面的这两个条件时才能认为是加锁成功。条件1客户端从超过半数大于等于N/21的Redis实例上成功获取到了锁条件2客户端获取锁的总耗时没有超过锁的有效时间。 解决方案 为什么是奇数 N 2X 1 (N是最终部署机器数X是容错机器数) 1 先知道什么是容错 失败了多少个机器实例后我还是可以容忍的所谓的容忍就是数据一致性还是可以Ok的CP数据一致性还是可以满足 加入在集群环境中redis失败1台可接受。2X1 2 * 11 3部署3台死了1个剩下2个可以正常工作那就部署3台。 加入在集群环境中redis失败2台可接受。2X1 2 * 21 5部署5台死了2个剩下3个可以正常工作那就部署5台。 2 为什么是奇数 最少的机器最多的产出效果 加入在集群环境中redis失败1台可接受。2N2 2 * 12 4部署4台 加入在集群环境中redis失败2台可接受。2N2 2 * 22 6部署6台
天上飞的理念(RedLock)必然有落地的实现(Redisson) Redisson是java的redis客户端之一提供了一些api方便操作redis。 redisson之官网https://redisson.org/ redisson之Githubhttps://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95 redisson之解决分布式锁https://github.com/redisson/redisson/wiki/8.-Distributed-locks-and-synchronizers
使用Redisson进行编码改造V9.0
你怎么知道该这样使用? v9.0版本修改 POM
!–redisson–
dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.13.4/version
/dependencyRedisConfig
package com.atguigu.redislock.config;import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/** auther zzyy* create 2022-10-22 15:14/
Configuration
public class RedisConfig
{Beanpublic RedisTemplateString, Object redisTemplate(LettuceConnectionFactory lettuceConnectionFactory){RedisTemplateString,Object redisTemplate new RedisTemplate();redisTemplate.setConnectionFactory(lettuceConnectionFactory);//设置key序列化方式stringredisTemplate.setKeySerializer(new StringRedisSerializer());//设置value的序列化方式jsonredisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.afterPropertiesSet();return redisTemplate;}//单Redis节点模式Beanpublic Redisson redisson(){Config config new Config();config.useSingleServer().setAddress(redis://192.168.111.175:6379).setDatabase(0).setPassword(111111);return (Redisson) Redisson.create(config);}
}InventoryController
package com.atguigu.redislock.controller;import com.atguigu.redislock.service.InventoryService;
import com.atguigu.redislock.service.InventoryService2;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/** auther zzyy* create 2022-10-22 15:23/
RestController
Api(tags redis分布式锁测试)
public class InventoryController
{Autowiredprivate InventoryService inventoryService;ApiOperation(扣减库存一次卖一个)GetMapping(value /inventory/sale)public String sale(){return inventoryService.sale();}ApiOperation(扣减库存saleByRedisson一次卖一个)GetMapping(value /inventory/saleByRedisson)public String saleByRedisson(){return inventoryService.saleByRedisson();}
}从现在开始不再用我们自己手写的锁了 InventoryService
package com.atguigu.redislock.service;import cn.hutool.core.util.IdUtil;
import com.atguigu.redislock.mylock.DistributedLockFactory;
import com.atguigu.redislock.mylock.RedisDistributedLock;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;/** auther zzyy* create 2022-10-25 16:07/
Service
Slf4j
public class InventoryService2
{Autowiredprivate StringRedisTemplate stringRedisTemplate;Value(${server.port})private String port;Autowiredprivate DistributedLockFactory distributedLockFactory;Autowiredprivate Redisson redisson;public String saleByRedisson(){String retMessage ;String key zzyyRedisLock;RLock redissonLock redisson.getLock(key);redissonLock.lock();try{//1 查询库存信息String result stringRedisTemplate.opsForValue().get(inventory001);//2 判断库存是否足够Integer inventoryNumber result null ? 0 : Integer.parseInt(result);//3 扣减库存if(inventoryNumber 0) {stringRedisTemplate.opsForValue().set(inventory001,String.valueOf(–inventoryNumber));retMessage 成功卖出一个商品库存剩余: inventoryNumber;System.out.println(retMessage);}else{retMessage 商品卖完了o(╥﹏╥)o;}}finally {redissonLock.unlock();}return retMessage\t服务端口号port;}
}测试单机OK JMeterbug 业务代码修改为V9.1版
package com.atguigu.redislock.service;import cn.hutool.core.util.IdUtil;
import com.atguigu.redislock.mylock.DistributedLockFactory;
import com.atguigu.redislock.mylock.RedisDistributedLock;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;/** auther zzyy* create 2022-10-25 16:07/
Service
Slf4j
public class InventoryService
{Autowiredprivate StringRedisTemplate stringRedisTemplate;Value(${server.port})private String port;Autowiredprivate DistributedLockFactory distributedLockFactory;Autowiredprivate Redisson redisson;public String saleByRedisson(){String retMessage ;String key zzyyRedisLock;RLock redissonLock redisson.getLock(key);redissonLock.lock();try{//1 查询库存信息String result stringRedisTemplate.opsForValue().get(inventory001);//2 判断库存是否足够Integer inventoryNumber result null ? 0 : Integer.parseInt(result);//3 扣减库存if(inventoryNumber 0) {stringRedisTemplate.opsForValue().set(inventory001,String.valueOf(–inventoryNumber));retMessage 成功卖出一个商品库存剩余: inventoryNumber;System.out.println(retMessage);}else{retMessage 商品卖完了o(╥﹏╥)o;}}finally {if(redissonLock.isLocked() redissonLock.isHeldByCurrentThread()){redissonLock.unlock();}}return retMessage\t服务端口号port;}
}Redisson源码解析
加锁可重入续命解锁 分析步骤 1.Redis 分布式锁过期了但是业务逻辑还没处理完怎么办缓存续命 2.守护线程“续命” 额外起一个线程定期检查线程是否还持有锁如果有则延长过期时间。Redisson 里面就实现了这个方案使用“看门狗”定期检查每1/3的锁时间检查1次如果线程还持有锁则刷新过期时间 3.在获取锁成功后给锁加一个watchdog, watchdog会起一个定时任务在锁没有被释放且快要过期的时候会续期 4.上述源码分析1 通过redisson新建出来的锁key默认是30秒 5.上述源码分析2 RedissonLock.java lock()—tryAcquire()—tryAcquireAsync()— 6.上述源码分析3 流程解释 通过exists判断如果锁不存在则设置值和过期时间加锁成功 通过hexists判断如果锁已存在并且锁的是当前线程则证明是重入锁加锁成功 如果锁已存在但锁的不是当前线程则证明有其他线程持有锁。返回当前锁的过期时间(代表了锁key的剩余生存时间)加锁失败
7.上述源码分析4 这里面初始化了一个定时器dely 的时间是 internalLockLeaseTime/3。在 Redisson 中internalLockLeaseTime 是 30s也就是每隔 10s 续期一次每次 30s。 watch dog自动延期机制: 客户端A加锁成功就会启动一个watch dog看门狗他是一个后台线程会每隔10秒检查一下如果客户端A还持有锁key那么就会不断的延长锁key的生存时间默认每次续命又从30秒新开始 自动续期lua脚本分析 8.解锁
多机案例
理论参考来源 redis之父提出了Redlock算法解决这个问题 官网 具体 小总结 这个锁的算法实现了多redis实例的情况相对于单redis节点来说优点在于 防止了 单节点故障造成整个服务停止运行的情况且在多节点中锁的设计及多节点同时崩溃等各种意外情况有自己独特的设计方法。 Redisson 分布式锁支持 MultiLock 机制可以将多个锁合并为一个大锁对一个大锁进行统一的申请加锁以及释放锁。 最低保证分布式锁的有效性及安全性的要求如下 1.互斥任何时刻只能有一个client获取锁 2.释放死锁即使锁定资源的服务崩溃或者分区仍然能释放锁 3.容错性只要多数redis节点一半以上在使用client就可以获取和释放锁 网上讲的基于故障转移实现的redis主从无法真正实现Redlock: 因为redis在进行主从复制时是异步完成的比如在clientA获取锁后主redis复制数据到从redis过程中崩溃了导致没有复制到从redis中然后从redis选举出一个升级为主redis,造成新的主redis没有clientA 设置的锁这是clientB尝试获取锁并且能够成功获取锁导致互斥失效
代码参考来源 https://github.com/redisson/redisson/wiki/8.-Distributed-locks-and-synchronizers MultiLock多重锁
案例
1.docker走起3台redis的master机器本次设置3台master各自独立无从属关系 docker run -p 6381:6379 –name redis-master-1 -d redis docker run -p 6382:6379 –name redis-master-2 -d redis docker run -p 6383:6379 –name redis-master-3 -d redis 执行成功 进入上一步刚启动的redis容器实例 docker exec -it redis-master-1 /bin/bash 或者 docker exec -it redis-master-1 redis-cli docker exec -it redis-master-2 /bin/bash 或者 docker exec -it redis-master-2 redis-cli docker exec -it redis-master-3 /bin/bash 或者 docker exec -it redis-master-3 redis-cli
建Moduleredis _redlock 改POM
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.3.10.RELEASE/versionrelativePath/ !– lookup parent from repository –/parentgroupIdcom.atguigu.redis.redlock/groupIdartifactIdredis_redlock/artifactIdversion0.0.1-SNAPSHOT/versionpropertiesjava.version1.8/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.19.1/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.8/version/dependency!–swagger–dependencygroupIdio.springfox/groupIdartifactIdspringfox-swagger2/artifactIdversion2.9.2/version/dependency!–swagger-ui–dependencygroupIdio.springfox/groupIdartifactIdspringfox-swagger-ui/artifactIdversion2.9.2/version/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion3.4/versionscopecompile/scope/dependencydependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.11/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-configuration-processor/artifactIdoptionaltrue/optional/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationexcludesexcludegroupIdorg.springframework.boot/groupIdartifactIdspring-boot-configuration-processor/artifactId/exclude/excludes/configuration/plugin/plugins/build/project写YML
server.port9090
spring.application.nameredlockspring.swagger2.enabledtruespring.redis.database0
spring.redis.password
spring.redis.timeout3000
spring.redis.modesinglespring.redis.pool.conn-timeout3000
spring.redis.pool.so-timeout3000
spring.redis.pool.size10spring.redis.single.address1192.168.111.185:6381
spring.redis.single.address2192.168.111.185:6382
spring.redis.single.address3192.168.111.185:6383主启动
package com.atguigu.redis.redlock;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication
public class RedisRedlockApplication
{public static void main(String[] args){SpringApplication.run(RedisRedlockApplication.class, args);}}
业务类 配置 CacheConfiguration
package com.atguigu.redis.redlock.config;import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;Configuration
EnableConfigurationProperties(RedisProperties.class)
public class CacheConfiguration {AutowiredRedisProperties redisProperties;BeanRedissonClient redissonClient1() {Config config new Config();String node redisProperties.getSingle().getAddress1();node node.startsWith(redis://) ? node : redis:// node;SingleServerConfig serverConfig config.useSingleServer().setAddress(node).setTimeout(redisProperties.getPool().getConnTimeout()).setConnectionPoolSize(redisProperties.getPool().getSize()).setConnectionMinimumIdleSize(redisProperties.getPool().getMinIdle());if (StringUtils.isNotBlank(redisProperties.getPassword())) {serverConfig.setPassword(redisProperties.getPassword());}return Redisson.create(config);}BeanRedissonClient redissonClient2() {Config config new Config();String node redisProperties.getSingle().getAddress2();node node.startsWith(redis://) ? node : redis:// node;SingleServerConfig serverConfig config.useSingleServer().setAddress(node).setTimeout(redisProperties.getPool().getConnTimeout()).setConnectionPoolSize(redisProperties.getPool().getSize()).setConnectionMinimumIdleSize(redisProperties.getPool().getMinIdle());if (StringUtils.isNotBlank(redisProperties.getPassword())) {serverConfig.setPassword(redisProperties.getPassword());}return Redisson.create(config);}BeanRedissonClient redissonClient3() {Config config new Config();String node redisProperties.getSingle().getAddress3();node node.startsWith(redis://) ? node : redis:// node;SingleServerConfig serverConfig config.useSingleServer().setAddress(node).setTimeout(redisProperties.getPool().getConnTimeout()).setConnectionPoolSize(redisProperties.getPool().getSize()).setConnectionMinimumIdleSize(redisProperties.getPool().getMinIdle());if (StringUtils.isNotBlank(redisProperties.getPassword())) {serverConfig.setPassword(redisProperties.getPassword());}return Redisson.create(config);}/*** 单机* return*//Beanpublic Redisson redisson(){Config config new Config();config.useSingleServer().setAddress(redis://192.168.111.147:6379).setDatabase(0);return (Redisson) Redisson.create(config);}/}RedisPoolProperties
package com.atguigu.redis.redlock.config;import lombok.Data;Data
public class RedisPoolProperties {private int maxIdle;private int minIdle;private int maxActive;private int maxWait;private int connTimeout;private int soTimeout;/*** 池大小/private int size;}
RedisProperties
package com.atguigu.redis.redlock.config;import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;ConfigurationProperties(prefix spring.redis, ignoreUnknownFields false)
Data
public class RedisProperties {private int database;/** 等待节点回复命令的时间。该时间从命令发送成功时开始计时/private int timeout;private String password;private String mode;/** 池配置/private RedisPoolProperties pool;/** 单机信息配置*/private RedisSingleProperties single;}
RedissingleProperties
package com.atguigu.redis.redlock.config;import lombok.Data;Data
public class RedisSingleProperties {private String address1;private String address2;private String address3;
}
controller
package com.atguigu.redis.redlock.controller;import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.RedissonMultiLock;
import org.redisson.RedissonRedLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;RestController
Slf4j
public class RedLockController {public static final String CACHE_KEY_REDLOCK ATGUIGU_REDLOCK;AutowiredRedissonClient redissonClient1;AutowiredRedissonClient redissonClient2;AutowiredRedissonClient redissonClient3;boolean isLockBoolean;GetMapping(value /multiLock)public String getMultiLock() throws InterruptedException{String uuid IdUtil.simpleUUID();String uuidValue uuid:Thread.currentThread().getId();RLock lock1 redissonClient1.getLock(CACHE_KEY_REDLOCK);RLock lock2 redissonClient2.getLock(CACHE_KEY_REDLOCK);RLock lock3 redissonClient3.getLock(CACHE_KEY_REDLOCK);RedissonMultiLock redLock new RedissonMultiLock(lock1, lock2, lock3);redLock.lock();try{System.out.println(uuidValue\t—come in biz multiLock);try { TimeUnit.SECONDS.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println(uuidValue\t—task is over multiLock);} catch (Exception e) {e.printStackTrace();log.error(multiLock exception ,e);} finally {redLock.unlock();log.info(释放分布式锁成功key:{}, CACHE_KEY_REDLOCK);}return multiLock task is over uuidValue;}}测试 http://localhost:9090/multilock 命令 ttl ATGUIGU_REDLOCK HGETALL ATGUIGU_REDLOCK shutdown docker start redis-master-1 docker exec -it redis-master-1 redis-cli 结论
Redis的缓存过期淘汰策略
面试题 生产上你们的redis内存设置多少? 如何配置、修改redis的内存大小 如果内存满了你怎么办 redis清理内存的方式?定期删除和惰性删除了解过吗 redis缓存淘汰策略有哪些?分别是什么?你用那个? lru和lfu算法的区别是什么 Redis内存满了怎么办 1.redis默认内存多少?在哪里查看?如何设置修改? 查看Redis最大占用内存 redis默认内存多少可以用? 注意在64bit系统下maxmemory 设置为0表示不限制Redis 内存使用 —般生产上你如何配置? —般推荐Redis设置内存为最大物理内存的四分之三 如何修改redis内存设置 1.通过修改文件配置 2.通过修改文件配置 什么命令查看redis内存使用情况? info memoryconfig get maxmemory
真要打满了会怎么样?如果Redis内存使用超出了设置的最大值会怎样? 改改配置故意把最大值设为1个byte试试 结论 设置了maxmemory的选项假如redis内存使用达到上限 没有加上过期时间就会导致数据写满maxmemory为了避免类似情况引出下一章内存淘汰策略
往redis里写的数据是怎么没了的?它如何删除的?
redis过期键的删除策略 如果一个键是过期的那它到了过期时间之后是不是马上就从内存中被被删除呢 如果回答yes立即删除你自己走还是面试官送你走如果不是那过期后到底什么时候被删除呢是个什么操作
三种不同的删除策略 立即删除 Redis不可能时时刻刻遍历所有被设置了生存时间的key来检测数据是否已经到达过期时间然后对它进行删除。 立即删除能保证内存中数据的最大新鲜度因为它保证过期键值会在过期后马上被删除其所占用的内存也会随之释放。但是立即删除对cpu是最不友好的。因为删除操作会占用cpu的时间如果刚好碰上了cpu很忙的时候比如正在做交集或排序等计算的时候就会给cpu造成额外的压力让CPU心累时时需要删除忙死。。。。。。。 这会产生大量的性能消耗同时也会影响数据的读取操作。 总结:对CPU不友好用处理器性能换取存储空间(拿时间换空间)
惰性删除 数据到达过期时间不做处理。等下次访问该数据时 如果未过期返回数据 发现已过期删除返回不存在。 惰性删除策略的缺点是它对内存是最不友好的。 如果一个键已经过期而这个键又仍然保留在redis中那么只要这个过期键不被删除它所占用的内存就不会释放。 在使用惰性删除策略时如果数据库中有非常多的过期键而这些过期键又恰好没有被访问到的话那么它们也许永远也不会被删除(除非用户手动执行FLUSHDB)我们甚至可以将这种情况看作是一种内存泄漏–无用的垃圾数据占用了大量的内存而服务器却不会自己去释放它们这对于运行状态非常依赖于内存的Redis服务器来说,肯定不是一个好消息 总结:对memory不友好用存储空间换取处理器性能拿空间换时间)。开启惰性淘汰lazyfree-lazy-evictionyes
上面两种方案都走极端 定期删除定期抽样key判断是否过期漏网之鱼 定期删除策略是前两种策略的折中 定期删除策略每隔一段时间执行一次删除过期键操作并通过限制删除操作执行时长和频率来减少删除操作对CPU时间的影响。 周期性轮询redis库中的时效性数据采用随机抽取的策略利用过期数据占比的方式控制删除频度 特点1CPU性能占用设置有峰值检测频度可自定义设置 特点2内存压力不是很大长期占用内存的冷数据会被持续清理 总结周期性抽查存储空间 随机抽查重点抽查 举例 redis默认每隔100ms检查是否有过期的key有过期key则删除。注意redis不是每隔100ms将所有的key检查一次而是随机抽取进行检查(如果每隔100ms,全部key进行检查redis直接进去ICU)。因此如果只采用定期删除策略会导致很多key到时间没有删除。 定期删除策略的难点是确定删除操作执行的时长和频率如果删除操作执行得太频繁或者执行的时间太长定期删除策略就会退化成立即删除策略以至于将CPU时间过多地消耗在删除过期键上面。如果删除操作执行得太少或者执行的时间太短定期删除策略又会和惰性删除束略一样出现浪费内存的情况。因此如果采用定期删除策略的话服务器必须根据情况合理地设置删除操作的执行时长和执行频率。 有漏洞 1 定期删除时从来没有被抽查到 2 惰性删除时也从来没有被点中使用过 上述两个步骤 大量过期的key堆积在内存中导致redis内存空间紧张或者很快耗尽 必须要有一个更好的兜底方案… redis缓存淘汰策略登场 redis缓存淘汰策略 Redis配置文件 lru和Ifu算法的区别是什么 区别 LRU最近最少使用页面置换算法淘汰最长时间未被使用的页面看页面最后一次被使用到发生调度的时间长短首先淘汰最长时间未被使用的页面。 LFU最近最不常用页面置换算法淘汰一定时期内被访问次数最少的页看一定时间段内页面被使用的频率淘汰一定时期内被访问次数最少的页 举个栗子 某次时期Time为10分钟,如果每分钟进行一次调页,主存块为3,若所需页面走向为2 1 2 1 2 3 4 假设到页面4时会发生缺页中断 若按LRU算法,应换页面1(1页面最久未被使用)但按LFU算法应换页面3(十分钟内,页面3只使用了一次) 可见LRU关键是看页面最后一次被使用到发生调度的时间长短,而LFU关键是看一定时间段内页面被使用的频率! 有哪些(redis7版本) 1.noeviction:不会驱逐任何key表示即使内存达到上限也不进行置换所有能引起内存增加的命令都会返回error 2.allkeys-lru:对所有key使用LRU算法进行删除优先删除掉最近最不经常使用的key用以保存新数据 3.volatile-lru:对所有设置了过期时间的key使用LRU算法进行删除 4.allkeys-random:对所有key随机删除 5.volatile-random:对所有设置了过期时间的key随机删除 6. volatile-ttl:删除马上要过期的key 7. allkeys-lfu:对所有key使用LFU算法进行删除 8.volatile-lfu:对所有设置了过期时间的key使用LFU算法进行删除
上边总结 2*4得8 2个维度1.过期键中筛选2.所有键中筛选 4个方面LRULFUrandomttl 8个选项
你平时用哪种 如何配置、修改直接用config命令直接redis.conf配置文件
redis缓存淘汰策略配置性能建议避免存储bigkey开启惰性淘汰lazyfree-lazy-evictionyes
下一篇
Redis7实战加面试题-高阶篇Redis为什么快?高性能设计之epoll和IO多路复用深度解析
- 上一篇: 如何建设公司的网站首页wordpress 预约时间
- 下一篇: 如何建设机器人教育网站网站布局设计理由
相关文章
-
如何建设公司的网站首页wordpress 预约时间
如何建设公司的网站首页wordpress 预约时间
- 技术栈
- 2026年03月21日
-
如何建设电子商务网站有关电子商务网站建设的 论文
如何建设电子商务网站有关电子商务网站建设的 论文
- 技术栈
- 2026年03月21日
-
如何建设班级网站首页WordPress主题 luo
如何建设班级网站首页WordPress主题 luo
- 技术栈
- 2026年03月21日
-
如何建设机器人教育网站网站布局设计理由
如何建设机器人教育网站网站布局设计理由
- 技术栈
- 2026年03月21日
-
如何建设企业微网站少儿免费学编程的网站
如何建设企业微网站少儿免费学编程的网站
- 技术栈
- 2026年03月21日
-
如何建设黔货出山电子商务网站网络营销师证
如何建设黔货出山电子商务网站网络营销师证
- 技术栈
- 2026年03月21日






