Redis相关分享:

2021-05-20  本文已影响0人  漫行者_

Redis简介

Redis 是一个开源的使用 C 语言编写、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。

问题1. 为什么Redis读取快?

(Redis 在最新的几个版本中加入了一些可以被其他线程异步处理的删除操作,我们知道Redis可以使用del命令删除一个元素,如果这个元素非常大,可能占据了几十兆或者是几百兆,那么在短时间内是不能完成的,这样一来就需要多线程的异步支持。)

问题二:Redis主要用于做缓存:可能面临多种问题。

  1. 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
  2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击。

设置空

jedis.setex("Id + ":info", 60 * 3, JSON.toJSONString("empty"));  

访问的情况

            String json = jedis.get(id);
            if ("empty".equals(json)) {
                return null;
            }
  1. 设置热点数据永远不过期。
  2. 加互斥锁
    当访问不存在的时候开始加互斥锁,存在的问题,极大的影响访问性能。
   /*设置分布式锁 返回值是OK*/
        String token = UUID.randomUUID().toString();
                  /*保证加的锁是加和取消是同一个访问。
                  为了避免当拿到锁的用户在过期时间后依旧没有从数据库中获取到数据,锁已经自动销毁(过期时间已满)
                      这时下一个用户拿到锁,开始访问数据库,但是,上一个拿到锁的用户访问完毕,会回来执行“删除锁”
                      jedis.del(Id + ":lock");命令,这时删除的锁是当前正在访问的用户的锁,造成当前用户访问失败。
                      所以在当前用户拿到锁情况下,上一个用户回来做“删除锁”jedis.del(Id + ":lock");命令时
                      上一个用户应该将此时的newToken和自己拿到锁分配的随机token做比较,相同则是同一个用户,可以删除锁*、*/
          String OK = jedis.set(Id + ":lock", token, "nx", "px", 10 * 1000);
            if (OK != null && !OK.equals("") && OK.equals("OK")) {
                    /*设置成功,有权利在10秒的过期时间内访问数据库*/
              info = getInfoByIdFromDb(skuId);
               if (info != null) {
                        /*4.mysql将想要查询的结果返回给redis*/
                        Random random = new Random();
                        jedis.setex(Id + ":info",(random.nextInt(10)+1)*60, JSON.toJSONString(info));
                } else {
                     
                        jedis.setex(Id + ":info", 60 * 3, JSON.toJSONString("empty"));
                 }                
               String newToken = jedis.get(Id + ":lock");
                 if (newToken != null && !newToken.equals("") && newToken.equals(token)) {
                        /*  并发问题*/
                        jedis.del(Id + ":lock");
                }
}
                
(1)读取时,首先读取缓存,如果没有缓存,则读取数据库,然后取出数据并放入它在缓存中,然后返回Response
(2)更新时,请先删除缓存,然后再更新数据库

.....

上一篇 下一篇

猜你喜欢

热点阅读