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

redis高并发缓存架构与性能优化

Redlock实现原理

超过半数redis节点加锁成功才算成功加锁。
Redlock存在问题
如果主节点挂掉,还没有同步到从节点,重新选举出主节点,那加锁就没有加到这个新的主节点上。
如果增加redis主节点数,那么加锁的性能更差,要给半数节点加锁,如果没有加成功,还要回滚。
Redis的刷盘频率,1s刷盘一次,否则写一条刷盘一条性能就非常差了。如果redis挂了或者重启,可能导致这1s内的数据没有持久化,因此也会造成锁丢失,别的线程也可以加锁成功。
RedLock 依赖 Redis 实例的系统时钟计算锁的剩余有效期。若不同实例的时钟不同步(如时钟跳跃或漂移),可能导致锁被提前释放或无法释放。
Redisson 官方已弃用 RedLock。

高并发扣减库存

分段锁。
ConcurrentHashMap1.7分段锁的原理
分段结构:分为多个segment,继承reentrantLock。
锁粒度:写操作仅锁定当前操作的segment。读操作不用加锁。
哈希定位:第一次hash计算segment位置,第二次hash计算数组下标。

热点缓存重建

Product product = null;
String productCacheKey = RedisKeyPrefixConst.PRODUCT_CACHE + productId;
// 获取缓存
product = getProductFromCache(productCacheKey);
if(product != null) return product;
//加分布式锁解决热点缓存并发重建问题
RLock hotCreatecacheLock = redisson.getLock( LOCK_PRODUCT_HOT_CACHE_CREATE_PREFIX + productId);
hotCreateCacheLock.tryLock();
try {
	// 在锁内再次确认缓存状态,防止在第一次检查缓存为空后
	// 但是在加锁前,其他线程已经重新构建好缓存
	// 并且若多个线程同时通过第一次检查,加锁后保证只有一个线程来执行
	// 剩下的线程拿到锁再进来检查到缓存有值就直接返回了
	product = getProductFromCache(productCacheKey);
	if(product != null)  return product;
	// 读锁共享,写锁互斥
	RReadWriteLock productupdateLock = redisson.getReadWriteLock( name: LOCK_PRODUCT_UPDATE_PREFIX + productId);
	// 读锁
	RLock rLock =productUpdateLock.readLock();
	rLock.lock();
	// 构建缓存,同时也构建本地缓存。
	reBuildCache();
	// 热点key,比如微博,百万用户查同一个key,redis扛不住。
	// 本地缓存,并发百万级别没问题。
	// 多级缓存无法保证绝对一致性。不用过度设计。MQ异步或者redis发布订阅。
	// redis的发布订阅机制,如果更新数据,发送消息到queue,然后监听更新。
	// 热点中的热点商品才会存放到本地缓存,因为本地缓存是非常宝贵的。
	// 并且热点商品的变动是非常快的。
	// 因此,有专门的一个热点缓存计算系统,所有的应用会对热点缓存计算系统做一个监听,维护缓存。
}


// 发布消息
redisTemplate.convertAndSend("cache:update", 
        JSON.toJSONString(new CacheMessage("user:" + user.getId(), "DELETE")));
// 订阅频道
redisTemplate.execute((RedisConnection connection) -> {
     connection.subscribe(new RedisMessageListener() {
            @Override
            public void onMessage(String channel, String message) {
                // 解析消息
                CacheMessage cacheMsg = JSON.parseObject(message, CacheMessage.class);
                // 更新本地缓存
// 重建热点缓存串行转并行
// tryLock允许线程立即尝试获取锁,若锁不可用则立即返回失败,而非阻塞等待。这种机制打破了严格的串行逻辑。
if (cacheLock.tryLock()) {
    try {
        // 重建缓存(串行)
    } finally {
        cacheLock.unlock();
    }
} else {
    // 返回旧缓存或默认值(并行)
}

缓存穿透

查询一个不存在的key,设置为空值给缓存。

private final static String EMPTY_CACHE = "{}";

缓存雪崩

过期时间加一个随机值。

相关文章:

  • 青少年编程与数学 02-016 Python数据结构与算法 04课题、栈与队列
  • UE5学习记录part14
  • Windows11 优雅的停止更新、禁止更新
  • 回归预测 | Matlab实现NRBO-Transformer-GRU多变量回归预测
  • 【Linux操作系统——学习笔记三】Linux环境下多级目录构建与管理的命令行实践报告
  • GTA6大型MOD地图
  • 使用docker搭建redis镜像时云服务器无法访问到国外的docker官网时如何解决
  • 瑞萨RA4M2使用心得-GPIO输出
  • [Deep-ML]Reshape Matrix(重塑矩阵)
  • 【Part 1全景视频拍摄与制作基础】第三节|全景视频后期拼接与处理流程
  • C# Winform 入门(12)之制作简单的倒计时
  • zkmall开源商城日志管理:Logback 最佳实践
  • Visual Decoding and Reconstruction via EEG Embeddings with Guided Diffusion
  • 14-产品经理-维护计划
  • 【数据分享】2000—2020年我国250m精度灌溉农田栅格数据(免费获取)
  • 2025 XYCTF ezsql 详细教程wp
  • Java的Selenium的特殊元素操作与定位之时间日期控件
  • BN 层做预测的时候, 方差均值怎么算
  • c++的map基本知识
  • Hyperlane框架全面详解与应用指南 [特殊字符][特殊字符][特殊字符]
  • 创网站需要什么/天津网站推广
  • 跨境电商怎么注册开店/甘肃新站优化
  • 做网站费用多少钱/友情链接属于免费推广吗
  • 惠州公司做网站/百度托管运营哪家好
  • 天津网站建设服务电话/保温杯软文营销300字
  • wordpress登录及注册/志鸿优化设计