范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

分布式缓存的实践原理

  技术选型
  分布式缓存方案默认采用的是主流的缓存框架:Redis,即将缓存数据存储在另一台Redis服务器上。 系统在使用缓存时,依赖的是缓存的接口,而非具体的实现;
  分布式缓存在更新时不允许并发更新,防止缓存击穿,因此我们在Redis的基础上,采用了基于Redisson的分布式锁,在更新分布式缓存前必须先获得锁。缓存生命周期
  更新机制被动刷新:基于Redis的数据驱逐策略,包括LRU和TTL等;主动刷新:业务数据驱动的数据更新。当业务侧有数据变更时,将会主动刷新分布式缓存。比如当秒杀品下线时,会发出相应的领域事件,而在领域事件的处理中就会刷新缓存。
  分布式缓存在刷新的过程中,并不会主动刷新所有服务器上的本地缓存,本地缓存将遵循单机的刷新策略。这意味着,本地缓存可能会有秒级或毫秒级的滞后,对于数据一致性非绝对敏感的场景,这种短时间的延迟下的脏数据是可以接受的,它只是会对用户侧的展示有所影响,而不会影响到服务端的数据状态。分布式锁基于Redis实现分布式锁利用set nx ex获取锁,并设置过期时间,保存线程标识释放锁时先判断线程标识是否与自己一致,一致则删除锁/**  * 基于redis的分布式锁  */ public class SimpleRedisLock implements ILock {      private String name;     private StringRedisTemplate stringRedisTemplate;      public SimpleRedisLock(String name, StringRedisTemplate stringRedisTemplate) {         this.name = name;         this.stringRedisTemplate = stringRedisTemplate;     }      private static final String KEY_PREFIX = "lock:";      private static final String ID_PREFIX = UUID.randomUUID().toString() + "-";      /**      * 锁      *      * @param time 锁的过期时间      * @return      */     @Override     public boolean tryLock(long time) {         long id = Thread.currentThread().getId();         // 值用 uuid + 线程id拼接         String value = ID_PREFIX + id;         // 自动拆箱有空指针问题         Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent(KEY_PREFIX + name, value, time, TimeUnit.SECONDS);         return Boolean.TRUE.equals(aBoolean);     }      /**      * 解锁      */     @Override     public void unLock() {         String valueInRedis = stringRedisTemplate.opsForValue().get(KEY_PREFIX + name);         long id = Thread.currentThread().getId();         // 值用 uuid + 线程id拼接         String value = ID_PREFIX + id;         // 两者相同才释放锁,要先做判断再进行释放         if (value.equals(valueInRedis)) {             stringRedisTemplate.delete(KEY_PREFIX + name);         }     } }基于Redison实现分布式锁
  导包             org.redisson             redisson             3.16.3 
  配置文件@Configuration     public class RedissonConfig {          @Bean         public RedissonClient redissonClient() {             Config config = new Config();             config.useSingleServer()                 .setAddress("redis://localhost:6379")                 .setPassword("ezreal")                 .setDatabase(0);              return Redisson.create(config);         }     }
  代码实现@Component public class RedissonLockService implements DistributedLockFactoryService {     private final Logger logger = LoggerFactory.getLogger(RedissonLockService.class);      @Resource     private RedissonClient redissonClient;          @Override     public DistributedLock getDistributedLock(String key) {         RLock rLock = redissonClient.getLock(key);          return new DistributedLock() {              @Override             public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {                 boolean isLockSuccess = rLock.tryLock(waitTime, leaseTime, unit);                 logger.info("{} get lock result:{}", key, isLockSuccess);                 return isLockSuccess;             }              @Override             public void lock(long leaseTime, TimeUnit unit) {                 rLock.lock(leaseTime, unit);             }              @Override             public void unlock() {                 if (isLocked() && isHeldByCurrentThread()) {                     rLock.unlock();                 }             }              @Override             public boolean isLocked() {                 return rLock.isLocked();             }              @Override             public boolean isHeldByThread(long threadId) {                 return rLock.isHeldByThread(threadId);             }              @Override             public boolean isHeldByCurrentThread() {                 return rLock.isHeldByCurrentThread();             }         };     } }
  实现原理可重入:利用hash结构记录线程id和重入次数可重试:利用信号量和PubSub功能实现等待、唤醒,获取锁失败的重试机制超时续约::利用watchDog,每隔一段时间 (releaseTime/3),重置超时时间
  分布式缓存基本逻辑
  每次获取缓存的时候,先从本地缓存中获取,再从分布式缓存中获取。
  若分布式缓存中不存在对应的值,则需要获取分布式锁,然后对分布式缓存数据进行更新若获取锁成功,则查询数据库,获取最新的数据放入缓存;
  若数据库中的数据也为空,则也要存储入数据库,防止缓存穿透若获取锁失败,则直接返回,不要等待重新获取锁,客户端对这次请求进行静默处理;实现代码
  缓存的接口
  实现部分Redis数据结构的存储接口public interface DistributedCacheService {     void put(String key, String value);      void put(String key, Object value);      void put(String key, Object value, long timeout, TimeUnit unit);      void put(String key, Object value, long expireTime);       T getObject(String key, Class targetClass);      String getString(String key);       List getList(String key, Class targetClass);      Boolean delete(String key);      Boolean hasKey(String key); }
  基本逻辑代码private SeckillGoodCache updateDistributedSeckillGood(Long itemId) {         logger.info("更新远程缓存|{}", itemId);          DistributedLock distributedLock = distributedLockFactoryService.getDistributedLock(UPDATE_ITEMS_CACHE_LOCK_KEY + itemId);         try {             boolean tryLock = distributedLock.tryLock(1, 5, TimeUnit.SECONDS);              // 如果没有获得到锁,就返回重试             if (!tryLock) {                 return new SeckillGoodCache().tryLater();             }              // 再次检查             SeckillGoodCache distributedSeckillCache = distributedCacheService.getObject(buildItemCacheKey(itemId), SeckillGoodCache.class);             if (distributedSeckillCache != null) {                 return distributedSeckillCache;             }              // 查询数据库             SeckillGood seckillGood = seckillGoodMapper.selectById(itemId);             SeckillGoodCache seckillGoodCache = new SeckillGoodCache();             if (seckillGood == null) {                 // 数据不存在 也要返回 也要存缓存 防止缓存穿透                 seckillGoodCache.notExist();             } else {                 seckillGoodCache.with(seckillGood).setVersion(System.currentTimeMillis());             }             logger.info("itemCache|远程缓存已更新|{}", itemId);             distributedCacheService.put(buildItemCacheKey(itemId), JSON.toJSONString(seckillGoodCache));             return seckillGoodCache;         } catch (InterruptedException e) {              logger.error("itemCache|远程缓存更新失败|{}", itemId);             return new SeckillGoodCache().tryLater();         } finally {              distributedLock.unlock();         }     }

到底能不能借考啊?怎么操作?首先第一点,考研时间确定了就是12月24日至26日,担心会延期的同学可以安心备考了,好好准备。详细链接httpwww。moe。gov。cnjybxwfbgzdtgzdts59872风范股份变道控股晶樱光电背后的疑问欲通过收购苏州晶樱光电科技股份有限公司(以下简称晶樱光电)跨界光伏产业,风范股份(601700)的这一重组计划已经筹备了5个月。如今对于这起并购,风范股份似乎有些等不及了,调整了收产前查出感染艾滋病病毒,宝宝还能留吗?产前才查出感染艾滋,她难以置信崩溃大哭小芳(化名)永远忘不了2017年的那个冬天,她住进医院等待临产的那一天。当全家人都在热切期盼着宝宝降临的时候,管床医生却着急地来找她谈话,告诉干货主打移动应用的ThinkPadX132022款,谁是更好选择?ThinkPad是国内乃至国际市场的主流办公商用机型,出货量极大且分类齐全。其中,X13是定位于移动办公移动商务的经典轻便机型,1。3kg左右的重量,13。3英寸屏,与此同时保留了线长位多,售价不到50元值不值得买?绿联八位总控延长线插座拆解前言绿联推出了一款8插位总控的插线板,这款插线板长度为2米,额定电流为10A,并配有安全门,高品质阻燃外壳以及加粗线芯。插线板内部采用一体式铜条,具备更强的安全性,使用寿命更长,也德州扒鸡IPO原第一大股东转让股权存蹊跷有着300多年历史的中华老字号山东德州扒鸡股份有限公司(以下简称德州扒鸡)日前披露招股书,拟在上交所主板上市。此次IPO,德州扒鸡计划募资7。58亿元用于扩充产能和进行品牌升级等项日志一一沉默和内向的人是两种感觉一每日一首诗词归嵩山作唐王维清川带长薄,车马去闲闲流水如有意,暮禽相与还荒城临古渡,落日满秋山迢递嵩山下,归来且闭关终于归隐山林,不复牵挂红尘,是看破世事后的无奈,还是千帆阅尽后的阳光保险上市在即近四年累计被罚4145万财产险保费两年仅增2。6在盈亏边缘徘徊长江商报消息长江商报记者蔡嘉港交所将迎来全国第十家上市保险公司。日前,阳光保险(06963。HK)发布全球发售公告,公司拟在11月30日至12月5日招股,将以5。836。45港元股西虹市首富讽刺男足,足球小将激励日本在卡塔尔世界杯的舞台上,日本赢德国赢西班牙,着实让我们见识到了亚洲男人的潜力。虽然他们最终倒在了跟上届亚军克罗地亚的点球大战上。止步于16强。但带给国人的震撼却是巨大的。原来,亚洲将帅内讧,老鹰队惨遭雷霆逆转北京时间12月06日雷霆对阵老鹰。而老鹰在上场比赛中在特雷杨缺阵的情况下战胜了掘金。据NBA名记Shams和SamAmick联合报道,亚特兰大老鹰在训练中爆发内讧球队核心特雷杨与主笑死人!韩国门将挑衅内马尔,下一秒反被戏耍,直接被晃跪倒在地2022世界杯巴西与韩国的比赛如期开踢!本场比赛,可是吸引了很多球迷的目光,一来是大家想看看这一支亚洲球队能不能带着亚洲球迷的希望继续往前走。之前亚足联旗下的三支球队晋级到了16强
让爱情变得简单,让交往变得真诚题记一个国家一个民族,只要有勤劳勇敢善良的优秀儿女坚定地为幸福生活努力奋斗,就会不断进步发展。这是绝大多数人们想看到的,这就是希望!微信读书可阅读三岛由纪夫用散文化的文字记述了一段华谊老总女儿疑新恋情曝光!躺男方怀中亲密紧搂,郎才女貌太般配近日,知名富二代王文也分享了一则动态,引起了网友们对她恋情的猜测。王文也是何许人也?她的爸爸就是华谊的老总王中磊,而她的朋友们则都非富即贵,其中比较有名的有娱乐圈艺人欧阳娜娜范丞丞真要集齐7位NBA男友?詹娜与布克分手了他的下一任会是谁?北京时间11月22日,根据八卦媒体TMT报道,布克已经与詹娜分手了,双方分手的理由是各自忙各自的事业,没有时间相处。很显然,对于布克与詹娜分手的原因,相信大部分人都没有太多兴趣了。清朝一穷苦船员,闹肚子下船方便,谁曾想这是个飞黄腾达的机遇我们都知道中华民族有非常多的传统美德值得我们学习,比如说勤俭节约拾金不昧等等。但是在现在这个科技十分发达的社会上,很少有人能够拾金不昧了,不是人们不遵守这种传统美德了,而是因为现在夺嫡之争第一篇秦二世胡亥矫诏杀兄篡夺嫡位夺嫡主角秦二世胡亥秦二世胡亥影视剧形象支持者赵高李斯李斯赵高影视剧形象对手扶苏蒙氏家族等扶苏雕像夺嫡继位过程公元前230年,胡亥出生,是秦始皇最小的儿子。这一年,秦国灭韩。开始正式古人夏天穿什么衣服?别以为古人很保守,其实穿衣比现代人还开放夏天是一年温度最高的时候,天气炎热,酷暑难耐。我们需要穿上最薄的衣服,短袖,短裤出门,在家的时候吹风扇,吹空调,吃冰镇的爽口西瓜,喝着冷饮!那么我们想一想,在封建的古代,人们在夏天1853年太平天国北伐军归德府(商丘)大败清军记实大清咸丰三年(1853年)三月中旬,太平军占领南京后,于五月初,命大将林凤祥李开芳吉文元等率军北伐。北伐军于六月十日攻占亳州后,遂于十二日抵达河南归德宋家集(即今商丘宋集镇)。归德细思极恐五大诡异证明商鞅之死是孝公父子精细策划的一场阴谋资治通鉴这样读(11)三十一年(癸未,公元前338年)秦孝公薨,子惠文王立。公子虔之徒告商君欲反,发吏捕之。商君亡之魏魏人不受,复内之秦。商君乃与其徒之商於,发兵北击郑。秦人攻商君天下长河黄河从此安定了150多年,在历史上堪称奇迹黄河是中国的母亲河,黄河从上游带来的大量泥沙形成了华北平原,滋养了中华文明。但是,黄河也是一条容易泛滥的河流,大量的泥沙淤积会导致河道不畅,最终引发灾难。因此,历朝历代都会将治理黄菲律宾前总统巨额财产来历不明,妻子一句话道出隐情要说菲律宾人谁最有钱,施氏兄弟说第一没人敢说第二,如果要说谁最贪,在中国恐怕是和珅吧,但在菲律宾却有这样一位总统能够比和珅更能贪污,他就是马科斯。阅读前,希望您能点一下下方呢点赞,岚图汽车A轮融资50亿,粮草充足,该打胜仗了11月18日,岚图汽车宣布完成A轮引战融资协议签署和交割,本轮融资近50亿元,创造了中国新能源汽车行业首轮融资的最大金额,融资后市场估值近300亿元。对于低迷的新能源资本市场,无疑