精华内容
下载资源
问答
  • 一、集成redis 1、引入redis的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>...

    一、集成redis

    1、引入redis的依赖

     		<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
    

    2、yml中配置redis地址、端口、密码

    redis:
        # redis密码
        password:
        alone:
          #redis地址
          host: 127.0.0.1
          #redis端口
          port: 6379
    
    

    3、在server中使用redis

    首先实体类要实现序列化
    在这里插入图片描述

    简单实现redis缓存和查询功能
    @Service
    public class SysUserService {
    	//自动注入redis
    	@Autowired
        private RedisTemplate<Object,Object> redisTemplate;
    
    	//根据用户id获取用户信息
    	 public SysUser selectSysUserByUserId(Integer userId){
            //修改key的序列化类型 提高可读行 StringRedisSerializer设置key的类型为string
            RedisSerializer redisSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(redisSerializer);
    
            //从redis缓存中查询
            SysUser sysUser = (SysUser) redisTemplate.opsForValue().get("sysUser");
            //如果为空则从数据库查询
            if(sysUser == null){
                //从数据库查询
                 sysUser = sysUserDao.selectSysUserByUserId(userId);
                 //存入redis中
                 redisTemplate.opsForValue().set("sysUser",sysUser);
            }
            return sysUser;
        }
    }
    
    
    解决高并发问题

    第一种:效率最慢。在方法前面加上synchronized ,使用同步锁去锁定请求。当同时有一千条数据请求时,只能一条一条请求的进来。

     public synchronized SysUser selectSysUserByUserId(Integer userId){
            //修改key的序列化类型 提高可读行 StringRedisSerializer设置key的类型为string
            RedisSerializer redisSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(redisSerializer);
    
            //从redis缓存中查询
            SysUser sysUser = (SysUser) redisTemplate.opsForValue().get("sysUser");
            if(sysUser == null){
                //从数据库查询
                 sysUser = sysUserDao.selectSysUserByUserId(userId);
                 redisTemplate.opsForValue().set("sysUser",sysUser);
            }
            return sysUser;
        }
    
    第二种:效率比第一种高点,可以适用请求量不大的场景下。
     public  SysUser selectSysUserByUserId(Integer userId){
            //修改key的序列化类型 提高可读行 StringRedisSerializer设置key的类型为string
            RedisSerializer redisSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(redisSerializer);
    
            //从redis缓存中查询
            SysUser sysUser = (SysUser) redisTemplate.opsForValue().get("sysUser");
    
            //双重监测锁
            if(sysUser == null){
                synchronized (this){
                    if(sysUser == null){
                        //从数据库查询
                        sysUser = sysUserDao.selectSysUserByUserId(userId);
                        redisTemplate.opsForValue().set("sysUser",sysUser);
                    }
                }
            }
    
            return sysUser;
        }
    
    展开全文
  • 平时多积累点高并发啊锁啊缓存啊这些知识点 面试的时候可以和面试官侃侃而谈 面试官喜欢听高并发相关的 当然你能结合实际业务场景来分析 面试肯定加分 传统单点应用的线程安全问题,因为只涉及到单个应用中...

    吐槽

    平时多积累点高并发啊锁啊缓存啊这些知识点

    面试的时候可以和面试官侃侃而谈

    面试官喜欢听高并发相关的

    当然你能结合实际业务场景来分析

    面试肯定加分

     

     

    传统单点应用的线程安全问题,因为只涉及到单个应用中多线程之间的资源共享,往往通过加锁synchronized,ReentrantReadWriteLock等手段就能实现共享资源的安全;

    但是现在很多大型系统,高并发的量往往较大,整个服务架构也都是设计成分布式架构,原本在单机中的共享资源转而分布在了不同的机器上,这个时候锁也应该相应的升级为分布式锁;

    分布式锁有多种方式redis,zookeepper等,因为系统中本就用到了redis,就以redis为例:

    分布式锁需要满足什么条件呢?

    一,互斥:既然是锁,不能每个客户端都有吧,那还锁啥?

    二,不能死锁:让一个客户端抱住锁,永远不释放,别的就获取不到了,那还要分布式系统干啥?

    三,每个客户端的锁自己加,自己解;

    redis为什么能作为分布式锁的选择呢?本身就是单进程单线程的模式,并且提供的命令具有原子性;

    一般用来做分布式锁的方式有1,setnx+getset方式, 2,INCR

    1,setnx+getSet方法加锁:

    setnx:(set if not exists)不存在就设置,设置成功为1,已经存在,返回0;

    getSet: set新key,并返回原来的value;

    伪代码如下图:

    场景解释如下:

    第一个线程读到没有锁存在,使用lock加锁,带上时间戳,超时则释放锁,防止死锁

    第二个线程读到锁存在(setnx==0),进入循环,判断锁是否在超时时间内,并使用setGet方法把最新的超时时间set进去,(防止超时时间到了,多个线程读到锁超时,都去释放的情况),

    第一个线程处理完业务逻辑,并删除锁,则后面的线程可以获得锁。。。

    2,INCR方法加锁

    这个方法会在不存在key的时候,先初始化0,然后加1,返回1;如果key存在,则在执行就会大于1;

    所以使用INCR方法加锁,伪代码如下图:

    1,进行加锁操作;

    2,如果锁不存在,并且加锁成功,设置过期时间;

    3,如果锁已经存在,查看是否已经过了过期时间,如果过了,则重新设置。。

    当然上述的分布式锁只在单机redis中安全,如果存在redis集群,可能会因为宕机,延时等问题,让锁不在唯一。需要redis官方推荐的redlock进行加锁,对此reddssion已经有良好的封装RedissionLock,建议可直接使用。

     

    展开全文
  • redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们用的是数据库(硬盘),提高了访问效率,解决了数据库服务器压力。 为什么redis的地位越来越高,我们为何不选择memcache,这是因为memcache只能存储字符...
  • Redis解决高并发问题 redis真的是一个很好的技术,它可以很好的在一定程度上解决网站一瞬间的并发量,例如商品抢购秒杀等活动。 redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们用的是数据库(硬盘...

    Redis锁解决高并发问题

    redis真的是一个很好的技术,它可以很好的在一定程度上解决网站一瞬间的并发量,例如商品抢购秒杀等活动。
    redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们用的是数据库(硬盘),提高了访问效率,解决了数据库服务器压力。

    为什么redis的地位越来越高,我们为何不选择memcache,这是因为memcache只能存储字符串,而redis存储类型很丰富(例如有字符串、LIST、SET等),memcache每个值最大只能存储1M,存储资源非常有限,十分消耗内存资源。
    而redis可以存储1G,最重要的是memcache它不如redis安全,当服务器发生故障或者意外关机等情况时,redsi会把内存中的数据备份到硬盘中,而memcache所存储的东西全部丢失;这也说明了memcache不适合做数据库来用,可以用来做缓存。

    这里我们主要利用Redis的setnx的命令来处理高并发。
    setnx 有两个参数。第一个参数表示键。第二个参数表示值。如果当前键不存在,那么会插入当前键,将第二个参数做为值。返回 1。如果当前键存在,那么会返回0。

    创建库存表

    CREATE TABLE `storage` (
     `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
     `number` int(11) DEFAULT NULL,
     PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
    

    设置初始库存为10

    创建订单表

    CREATE TABLE `order` (
     `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
     `number` int(11) DEFAULT NULL,
     PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
    

    测试不用锁的时候

    $pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
    $sql="select `number` from storage where id=1 limit 1";
    $res = $pdo->query($sql)->fetch();
    $number = $res['number'];
    if($number>0)
    {
     $sql ="insert into `order` VALUES (null,$number)";
    
     $order_id = $pdo->query($sql);
     if($order_id)
     {
    
     $sql="update storage set `number`=`number`-1 WHERE id=1";
     $pdo->query($sql);
     }
    }
    

    ab测试模拟并发,发现库存是正确的。

    mysql> select * from storage;
    +----+--------+
    | id | number |
    +----+--------+
    | 1 | 0 |
    +----+--------+
    1 row in set (0.00 sec)
    

    在来看订单表

    mysql> select * from `order`;
    +----+--------+
    | id | number |
    +----+--------+
    | 1 | 10 |
    | 2 | 10 |
    | 3 | 9 |
    | 4 | 7 |
    | 5 | 6 |
    | 6 | 5 |
    | 7 | 5 |
    | 8 | 5 |
    | 9 | 4 |
    | 10 | 1 |
    +----+--------+
    10 rows in set (0.00 sec)
    

    发现存在几个订单都是操作的同一个库存数据,这样就可能引起超卖的情况。修改代码加入redis锁进行数据控制

    <?php
    
    class Lock
    {
     private static $_instance ;
     private $_redis;
     private function __construct()
     {
     $this->_redis = new Redis();
     $this->_redis ->connect('127.0.0.1');
     }
     public static function getInstance()
     {
     if(self::$_instance instanceof self)
     {
      return self::$_instance;
     }
     return self::$_instance = new self();
     }
    
     /**
     * @function 加锁
     * @param $key 锁名称
     * @param $expTime 过期时间
     */
     public function set($key,$expTime)
     {
     //初步加锁
     $isLock = $this->_redis->setnx($key,time()+$expTime);
     if($isLock)
     {
      return true;
     }
     else
     {
      //加锁失败的情况下。判断锁是否已经存在,如果锁存在切已经过期,那么删除锁。进行重新加锁
      $val = $this->_redis->get($key);
      if($val&&$val<time())
      {
      $this->del($key);
      }
      return $this->_redis->setnx($key,time()+$expTime);
     }
     }
    
    
     /**
     * @param $key 解锁
     */
     public function del($key)
     {
     $this->_redis->del($key);
     }
    
    }
    
    
    
    $pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
    $lockObj = Lock::getInstance();
    //判断是能加锁成功
    if($lock = $lockObj->set('storage',10))
    {
     $sql="select `number` from storage where id=1 limit 1";
     $res = $pdo->query($sql)->fetch();
     $number = $res['number'];
     if($number>0)
     {
     $sql ="insert into `order` VALUES (null,$number)";
    
     $order_id = $pdo->query($sql);
     if($order_id)
     {
    
      $sql="update storage set `number`=`number`-1 WHERE id=1";
      $pdo->query($sql);
     }
     }
     //解锁
     $lockObj->del('storage');
    
    }
    else
    {
     //加锁不成功执行其他操作。
    }
    

    再次进行ab测试,查看测试结果

    mysql> select * from `order`;
    +----+--------+
    | id | number |
    +----+--------+
    | 1 | 10 |
    | 2 | 9 |
    | 3 | 8 |
    | 4 | 7 |
    | 5 | 6 |
    | 6 | 5 |
    | 7 | 4 |
    | 8 | 3 |
    | 9 | 2 |
    | 10 | 1 |
    +----+--------+
    10 rows in set (0.00 sec)
    

    发现订单表没有操作同一个库存数据的情况。所以利用redis锁是可以有效的处理高并发的。

    这里在加锁的时候其实是可以不需要判断过期时间的,这里我们为了避免造成死锁,所以加一个过期时间的判断。当过期的时候主动删除该锁。

    展开全文
  • Redis进行高并发的处理

    千次阅读 2019-08-01 20:04:42
    解决方案:为了解决这种高并发的情况可以使用Redis进行处理,常见的方式先进行Redis.GetValue(key),如果值不存在的情况下,进行Redis.SetValue(key,10);这种情况如果是同一秒钟进行请求的时候是无法进行拦截的,...

    背景:在集群多台服务器的系统会产生同一秒钟请求多次的情况;

    解决方案:为了解决这种高并发的情况可以使用Redis进行处理,常见的方式先进行Redis.GetValue(key),如果值不存在的情况下,进行Redis.SetValue(key,10);这种情况如果是同一秒钟进行请求的时候是无法进行拦截的,具体的可以使用Jmeter进行性能应用进行请求处理;

    改善的方法:使用Redis.SetNX进行改写

    在 Redis 里,所谓 SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。

    通过测试进行的效果可以看到这个是可以进行同一秒钟多个请求的拦截处理;

    2.如果不是同一秒甚至与是10秒之后的二次回写的问题这个可以使用数据库的原子性操作进行业务的更新、插入操作;

    如果更新的结果是0,说明该操作已经处理,就不能进行二次的处理,该情况适用于一个方法的执行时间较长,并且在请求的时候数据状态是1,当真正进行处理业务的时候该数据的状态0已经无效了,这个时候就不能进行功能的处理,否则会把0值更新为1;导致的业务异常;

     

    展开全文
  • SETNX命令简介 SETNX key value 将key的值设为value,并且仅当key不存在。... 此处放置需要要高并发的代码 */ //代码执行成功则释放锁 redisTemplate.delete( lockKey ); }    
  • 利用redis性能和事务特性来解决线上优惠券被超库存抢购的问题,下面我给出我临时解决这个问题的第一版的伪代码,去掉了一些细节: /** * 抢优惠券(秒杀) * @param int $couponId 商品ID * @param
  • 本篇文章主要介绍了利用redis + lua解决抢红包高并发的问题 ,详细的讲诉了需求分析和方案,有兴趣的可以了解一下。
  • Redis 高并发问题,及解决方案!

    万次阅读 多人点赞 2018-08-04 09:41:11
    redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们用的是数据库(硬盘),提高了访问效率,解决了数据库服务器压力。 为什么redis的地位越来越高,我们为何不选择memcache,这是因为memcache只能存储字符...
  • 利用redis实现分布式事务锁,解决高并发环境下库存扣减 问题描述: 某电商平台,首发一款新品手机,每人限购2台,预计会有10W的并发,在该情况下,如果扣减库存,保证不会超卖 解决方案一 利用数据库锁机制,对记录进行...
  • Redis解决并发的方案

    2020-06-06 18:12:05
    Redis解决并发的思路 Redis中的数据存储策略 企业中的数据存储策略 其核心就是设计Key 这里我们的Key的设计是 数据对象名:数据对象id:对象属性 Key ---- Sku:108:info Redis解决并发的简单代码实现 @Override ...
  • 本篇文章主要介绍了Java利用Redis实现消息队列的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 这个图虽然简单,但能形象的说明大流量高并发的秒杀业务架构,大家要记得这一张图。后面细细解析各个层级怎么优化。   四、各层次优化细节 第一层,客户端怎么优化(浏览器层,APP层) 问大家一个问题...
  • 本文讲述了Redis高并发问题的解决办法。分享给大家供大家参考,具体如下: redis为什么会有高并发问题 redis的出身决定  redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以...
  • 实现方案较为简单,分为两步走: 1、把数据临时写入redis,减轻前台同时并发写入数据库的压力 2、写一个死循环的PHP,可以判断下每秒钟运行一次,然后把redis里的内容给写入到数据库。 为什么这样解决可以呢?因...
  • Redis如何支持高并发的访问

    千次阅读 2020-09-06 13:56:28
    Redis高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快; 2.redis是单线程的,省去了很多上下文切换线程的时间; 3.redis使用多路复用技术,可以处理并发的连接。非阻塞IO 内部实现采用epoll,采用...
  • 秒杀事务高并发所产生的问题及解决方案秒杀业务高并发产生的问题问题一:超卖问题解决方式一:采用乐观锁解决方式二: 采用LUA脚本1.1 LUA脚本介绍1.2 特点问题二:由于有些连接等待时间过长会出现连接超时的问题解决...
  • 但是数据库操作是有时间的,在高并发下这种方式明显是不能限制重复请求提交的,有可能一个用户一天签到好几次,只要这个提交时间在很短的范围内就行(亲测确实是这样的)。  于是就引出了今天要讨论的问题,如何...
  • 如何利用Redis分布式锁处理高并发? 一、添加项目依赖 <!-- redis依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-...
  • 利用Redis解决并发问题

    千次阅读 2018-10-11 20:54:18
    那如果要使用redis来进行高并发问题的解决的话,应注意以下几点: 1、首先我们要先知道,我们在存储时,应使用redis的setnx方法,不应该使用set方法,因为setnx拥有原子操作命令(正确点说法应该是使用setnx,根据...
  • 使用Redis作为缓存数据库高并发处理步骤图: 整合redis到工程中 由于redis作为缓存数据库,要被多个项目使用,所以要制作一个通用的工具类,方便工程中的各个模块使用。 而主要使用redis的模块,都是后台服务的模块...
  • Redis高并发下存在的问题

    万次阅读 2020-05-09 17:44:40
    Redis在高并发下存在的问题:Redis与数据库的双一致性问题、缓存穿透、缓存击穿、缓存雪崩,利用Redis防止表单重复提交
  • Redis 的 sorted set 做排队队列。  主要使用的 Redis 命令有, zadd, zcount, zscore, zrange 等。  测试完毕后,发到线上,发现有大量接口请求返回超时熔断(超时时间为3s)。  Error日志打印的异常堆栈...
  • 可用问题,如何保证redis的持续可用性。 容量问题,单实例redis内存无法无限扩充,达到32G后就进入了64位世界,性能下降。 并发性能问题,redis号称单实例10万并发,但也是有尽头的。 如果只使用一个r...
  • 为什么Redis能支持高并发

    千次阅读 2020-08-07 18:55:31
    一、Redis为什么快 纯内存K-V操作 数据库的工作模式按存储方式分为了磁盘数据库和内存数据库。Redis将数据存储在内存中,并且绝大多数命令都不会受...多路 /O 复用模型是指利用select、poll、epoll 同时监察多个流的
  • 业务场景: ...但是我们的服务器压力就会很大了,从而使服务器宕机,那么我们如何使服务器压力减小还能保证数据不异常呢,我们可以使用队列的思想,下面我们介绍的是使用redis队列解决高并发的问题! redi...
  • zhanghan_java@163.com All Rights Reserved. * 项目名称:Spring Boot实战解决高并发数据入库: Redis 缓存+MySQL 批量入库 * 类名称:RedisConfig.java * 创建人:张晗 * 联系方式:zhanghan_java@163.com * 开源...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 51,948
精华内容 20,779
关键字:

利用redis解决高并发

redis 订阅