Redis中String数据类型的编码方式 & String的应用场景

String数据类型的编码方式:

字符串类型的内部编码有 3 种:

  • int:8 个字节的长整型。
  • embstr:小于等于 39 个字节的字符串。
  • raw:大于 39 个字节的字符串。

Resis会根据当前值的类型和长度动态决定使用哪种内部编码实现。关于这里的39等数字一般是可以根据实际的应用场景在配置文件中去修改的,甚至有些公司会对redis源码直接进行魔改。

Redis中整数直接用int来存,相当于C++中的long long 、java中的long。对于小数是将其视作字符串来存储的,者即意味着小数运算,需要将字符串转化为小数,计算完成之后再将结果转化为字符串。

String的应用场景:

作为缓存:

收到用户请求,系统会现在redis缓存中去查找数据,如果hit也就是找到了数据,直接去使用就好了,如果miss也就是没有找到数据,那么就需要进一步在数据库中查询数据了,同时可能会将这个数据存入到redis缓存中,方便下一次查找(这里是因为,当磁盘上的数据被访问是,可能未来不久该数据及其周围为的数据很可能也会被访问到,所以可以提前将这些数据加载到缓存中,随着时间的推移,这种策略可能会导致redis内存不足,我们可以给这些从数据库加载到缓存的数据设置过期时间,以及redis的内存淘汰机制关键的作用)

计数功能:

比如统计视频播放量:

用户请求数据资源,在返回数据的时候,执行incr video:5253命令来统计播放次数。

incr video:5253 //“video:5253”是某键值对的key,video是某实体的名字,5253是实体的id。

上图只是一个简易版的统计视频播放量的流程,实际情况要更复杂一些,比如要考虑完播率,防止用户刷播放量等等。

存储session会话信息:

Cookie(浏览器存储数据的机制);Session(服务器存储数据的机制)

如果不是使用redis缓存session的话,在分布式系统中就会出现下面这种比较尴尬的况,多次请求如果被发送到不同的web服务上,因为session没有共享可能导致用户需要多次登录进行身份验证:

如果使用Redis缓存session,在分布式系统中所有web服务器可以共享这个session:

就好比,一个病人周一去医院找医生看病,医生要病人周五复查,如果周五是另外一个医生值班,新医生无法对病情做先后对比,还好医院的系统存储了病人周一时的病情,每个值班的医生都可以查看得到,就可以给病人复诊了。

存储手机验证码:

手机验证码一般都具有时效性,可能是五分钟或者十分钟等等。可以通过给数据设置过期时间来完成这个功能。

String 发送验证码(String phoneNumber) {
    String key = "shortMsg:limit:" + phoneNumber;
    
    // 设置过期时间为 1 分钟(60 秒)
    // 使用 NX,只在不存在 key 时才能设置成功
    boolean r = Redis.执行命令:set(key, "1", "ex", 60, "nx");
    
    if (r == false) {
        // 说明之前设置过该手机的验证码了
        long c = Redis.执行命令:incr(key);
        
        if (c > 5) {
            // 说明超过了一分钟 5 次的限制了
            // 限制发送
            return null;
        }
    }
    
    // 说明要么之前没有设置过手机的验证码;要么次数没有超过 5 次
    String validationCode = 生成随机的6位数的验证码();
    
    String validationKey = "validation:" + phoneNumber;
    // 验证码 5 分钟(300 秒)内有效
    Redis.执行命令:set(validationKey, validationCode, "ex", 300);
    
    // 返回验证码,随后通过手机短信发送给用户
    return validationCode;
}

// 验证用户输入的验证码是否正确
boolean 验证验证码(String phoneNumber, String validationCode) {
    String validationKey = "validation:" + phoneNumber;
    
    String value = Redis.执行命令:get(validationKey);
    
    if (value == null) {
        // 说明没有这个手机的验证码记录,验证失败
        return false;
    }
    
    if (value.equals(validationCode)) {
        return true;
    } else {
        return false;
    }
}

题外话:

业务决定计数,有些时候计数解决不了的问题,可以优化业务来实现。

比如12306购票软件:如果每早八点放出所有的高铁票,这个时候所有人都来抢票就会导致服务器压力直接拉满,使用一些常规技术手段去优化,效果也不明显;此时可以从业务上去优化进行分时段放票,将票分几个时间去放出,此时就不会导致这么多人抢票,大大减轻了服务器的压力。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值