Redis 简介 基本操作 秒杀 验证码

Redis

1.简介
1、数据都在内存中,支持持久化,主要支持备份功能。
2、除了简单的key-value模式,还支持数据结构的存储,比如list、set、hash、zset等。
3、一般都是作为缓存数据库辅助持久化的数据库
2.Redis应用场景
1、高频次、热门访问的数据,降低数据库IO
2、分布式架构,做Session共享
3、由于持久化能力,其多样的数据结构存储特定的数据
最新的N个数据 List实现自然世界排序
排行榜,TopN 利用Zset
时效性数据,手机验证码 Exprie过期
计数器 ,秒杀 原子性
构建队列 List集合
3、Redis为什么块
1、完全基于内存,绝大多数请求存粹时内存的操作,非常快速。数据存在内存中,类似HashMap,时间复杂度时O(1)
2、数据结构简单,对数据的操作也简单,Redis中的数据结构是专门设计的。
3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多线程导致的切换而消耗CPU,不用考虑各种锁的问题,不存在加锁释放锁操作,更没有死锁操作
4、采用多路I/O服用模型,非阻塞IO,其底层调用的epool方法
5、使用的底层模型不同,他们之间底层实现方式与客户端之间通信的应用协议不一样,Redis直接构建自己的VM机制,因为一般系统调用系统函数的话,会浪费一定的时间去移动和请求。
4、Redis的五大数据类型
Key相关的
keys* 查询当前库的所有键
exists 判断某个键是否存在
type查看键的类型
del 删除某个键
exprie 为键值设置过期时间,单位秒
ttl 查看还有多少秒过期 -1永不过期
dbsize 查看当前数据库key的数量
Redis 五大数据类型
String
get 查询对应的key值
set 添加键值对
append 追加到原始的末尾
strlen 获取值的长度
setnx 只有在不存在时候设置key值
incr 将key中的存储的数字值增1 只能针对数字
decr 将key中存储的数字减1
incrby/decrby<步长>
mset 同时设置一个或者多个key-value对
mget 同时获取一个或者多个value
setex <过期时间>
getset 以新换旧,设置了新值同时获得旧
List
单键多值
Redis列表是简单的字符串列表,按照插入顺序排队,可以添加一个元素到左面或者右面
底层是一个双向链表,对两端操作性能很高,通过索引下标的操作中间的节点性能会较差
lpush/rpush
从左边/右边插入一个或者多个值
lpush/rpush
从左面/右面插入一个或者多个值
lpop/rpop
从左面/右面吐出一个值
值在键在,值亡键亡
lrange
按照索引下标获取元素
lindex
获取长度
llen
set
场景是无序,但是可以去重
sadd … 将一个或者多个放入集合key当中
smembers 取出所用值
sismember 是否有值,有的话返回1 没有0
scard 返回集合个数
hash
hset 给集合中的 键赋值
hget 从集合 取出 value
zset
有序set
zadd …
zrange [WITHSCORES]
5、Redis例子
第一个 完成手机验证码功能
要求:
1、输入手机号,点击发送后随机生成6位数字码,2分钟有效
2、输入验证码,点击验证,返回成功或失败
3、每个手机号每天只能发送3次验证码

    public static String buildCode() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            sb.append(new Random().nextInt(10));
        }
        return sb.toString();
    }

    public static String buildPhone() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 2; i++) {
            sb.append(new Random().nextInt(10));
        }
        return sb.toString();
    }

    public static void sendCode(String phoneNum) {
        Jedis jedis = null;
        try {
            String phoneCount = phoneNum + " :count";
            String phoneKey = phoneNum + " :key";
            jedis = new Jedis("Master", 6379);
            String cn = jedis.get(phoneCount);
            //今日没有发送过验证码
            if (cn == null) {
                jedis.setex(phoneCount, 60 * 60 * 24, "1");
                String code = buildCode();
                jedis.setex(phoneKey, 60 * 2, code);
                System.out.println("用户 " + phoneNum + " 第一次今日发送 ");
            } else {
                if (Integer.parseInt(cn) < 3) {
                    String code = buildCode();
                    jedis.setex(phoneKey, 60 * 2, code);
                    jedis.incr(phoneCount);
                    System.out.println(phoneNum + "当天" + (Integer.parseInt(cn) + 1) + "次");
                } else {
                    System.out.println("今日已经发送了三次 不能再次发送");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }
    }

    public static void main(String[] args) {
        for(int i=0;i<1000;i++){
           sendCode(buildPhone());
        }
    }

第二个 秒杀功能

 public static void secondKill(){
        Jedis jedis = new Jedis();
        //商品id
        String prodid =  "1001";
        String userid = new Random().nextInt(1000)+"";
        String memberKey = "sk:"+ userid +":user";
        //判断是否用户已经秒杀过d了
        Boolean flag = jedis.sismember(memberKey, userid);
        if(flag){
            //表示已经存在
            System.out.println("该"+userid+"已经参与过秒杀");
        }else{
            String qtKey = "sk:"+prodid+":qt";
            String qt = jedis.get(qtKey);
            if(qt==null){
                System.out.println("不存在该商品的秒杀");
            }else{
                //库存减1
                Transaction multi = jedis.multi();
                multi.decr(qtKey);
                //增加秒杀
                multi.sadd(memberKey,userid);
                jedis.decr(qtKey);
                List<Object> exec = multi.exec();
                if(exec==null||exec.size()==0){
                    System.out.println("秒杀失败");
                }else{
                    System.out.println("秒杀成功");
                }
            }
        }
    }

基于Lua脚本 跟分布式锁的解法,后面会有详细说明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值