zoukankan      html  css  js  c++  java
  • 实现redis缓存,缓存穿透简单原理

    String get(String key) {  
       String value = redis.get(key);  
       if (value  == null) {  
        if (redis.setnx(key_mutex, "1")) {  //设置分布式锁,同一时刻只能有一个线程能进行此操作
            // 3 min timeout to avoid mutex holder crash  
            redis.expire(key_mutex, 3 * 60)  
            value = db.get(key);  //为锁设置过期时间,防止持有锁的线程down了 锁没法释放,导致死锁
            redis.set(key, value);  //将过期的缓存重新放入redis
            redis.delete(key_mutex);  //操作完成后释放锁
        } else {  
            //其他线程休息50毫秒后重试  
            Thread.sleep(50);  //其他线程等待之后又重新去获取,这时候redis里面过期的数据已经被重新加载了
            get(key);  
        }  
      }  
    }

    func GetTopicDetail(c *gin.Context)  {
        tid:=c.Param("topic_id")
        topics:=Topics{}
        // DBHelper.Find(&topics,tid)
        //c.JSON(200,topics)
        conn:=RedisDefaultPool.Get()
        redisKey:="topic_"+tid
        defer conn.Close()
        ret,err:=redis.Bytes(conn.Do("get",redisKey))
        if err!=nil{ //缓存里没有
            DBHelper.Find(&topics,tid)
            retData,_:=ffjson.Marshal(topics)
            if topics.TopicID==0{ //代表从数据库没有匹配到
                conn.Do("setex",redisKey,20,retData) //设置20s过期时间
            }else{//正常数据 50秒缓存
                conn.Do("setex",redisKey,50,retData)
            }
            c.JSON(200,topics)
            log.Println("从数据库读取")
        }else{//代表有值
            log.Println("从 redis读取")
            ffjson.Unmarshal(ret,&topics)
            c.JSON(200,topics)
        }
    
    
    }




  • 相关阅读:
    Codeforces 166E. Tetrahedron
    Codeforce 687A. NP-Hard Problem
    Codeforces 570C. Replacement
    Codeforces 554B. Ohana Cleans Up
    Codeforces 482A. Diverse Permutation
    Codeforces 431C. k-Tree
    Codeforces 750B. Spider Man
    Codeforces 463A. Caisa and Sugar
    Codeforces 701B. Cells Not Under Attack
    Codeforces 445A. DZY Loves Chessboard
  • 原文地址:https://www.cnblogs.com/hualou/p/12071040.html
Copyright © 2011-2022 走看看