Redis字符串常用命令以及应用场景

一、Redis字符串类型常用命令

(1)设置一个值:

命令格式:set key value [ex seconds] [px milliseconds] [nx | xx]

中括号内的表示可选项

可选项 ex seconds 表示 设置这个值的同时设置一个失效时间单位为秒

可选项 px milliseconds 表示设置这个值的同时设置一个失效时间单位为毫秒

可选项 nx 表示 你set的这个键值对的key值原来不存在,才可以设置成功,否则就失败,因为如果set一个key值已经存在的,redis默认是覆盖原来的。所以添加的时候可以用到 nx 这一可选项

可选项 xx与 nx作用相反,键必须存在才能设置成功,可以理解成更新操作

(2)获取值:

命令格式 : get  key

这个没什么好说的就是获取对应key的value值,如果这个key不存在则返回nil

(3、4)批量设置值  &&   批量获取值:

命令格式 :  mset key value [key value…]    &&     mget key [key…]

(5、6、7、8)自增  &&  自减  &&  指定数字自增  &&   指定数字自减:

命令格式 : incr key   && decr key   &&  incrby key increment  &&  decrby key decrement

返回结果有四种:

1.如果这个key的value值不为整数,则返回错误

2.如果key对应的value是整数,则返回自增或自减后的结果

3.如果key不存在,设置这个key的value值为0并自增或自减1(指定了increment或decrement除外),返回自增后的结果

4.若key对应的value自增后超过了integer 的最大值也就是2的64次方,返回错误

(9)获取字符串长度

命令格式 :strlen  key

(10)设置并返回原值

命令格式 : getset key value

ps:这里补充一句Redis的字符串类型实现了三种内部编码,当key对应的value值是int类型则使用”int”这一编码,当key对应的value小于等于39个字节的字符串时使用”embstr”这一内部编码,当大于39个字节时使用raw这一内部编码。

 

二、真实应用场景

1.用redis当缓存层来加速读写性能降低后端的压力

String userIdForRedis = "dmpuser:info:"+id;
//从缓存中查询数据,若是前后端分离项目用JSON作数据交互,直接存json串
User user = (User) SerializeUtil.unserialize(redisClei.get(userIdForRedis.getBytes()));
if(user != null)
{
//缓存中有直接取缓存数据
    return user;
}
else
{
//没有则从数据库中查询
    return userDao.selectUserById(id);
}

2.用作计数器,数据分两类冷数据与热数据,热数据表示经常使用的时常发生变化的数据如一个视频的点击量,某文件的浏览次数,某商品的日月销量,系统消息以及用户消息这些热数据都可以用Redis来做,下面是一个思路



redis> HSET user:<userId>:message system 1//1条未读系统消息
(integer) 1
redis> HINCRBY user:<userId>:message system 1 //未读系统消息+1
(integer) 2
redis> HINCRBY user:<userId>:message comment 1 //未读评论消息+1
(integer) 1
redis> HSET user:<userId>:message system 0//设为系统消息已读
(integer) 1
redis> HGETALL user:<userId>:message //获取这key hashkey 和value
1) "system"
2) "0"
3) "comment"
4) "1"

3.限制某段时间内的访问次数,就比如我们登录的功能可以用手机获取验证码登录,但是我们发送验证码使用的第三方,是多少钱多少条的,肯定不能让他一直点,一直发短信,就算前端js做了校验,若有些人用fiddler拦截绕过前台就麻烦了,这时候可以用redis的incr命令和expire结合起来做一个解决方案

以下是伪代码

 
用户请求了我们的发送短信验证码服务
先从换从里取出这个用户对应的key(可以是电话号码拼接点东西)
 mKey = redisCli.get(key);
 if(mKey != null)
{
    如果缓存中存在了,就是已经请求过验证码了,比如我系统参数设置的至少60秒发送一次短信
    那就代表60之内再次请求了,返回false阻止
    return false;
}
else
{
    否则就是第一次请求短信验证码或者等了60再次请求的验证码
    发送验证码
    sendMsg()
    放入redis缓存并设置失效时间60秒
    redisCli.set(key,value,expire)
}

具体参考

 try {
            //先判断Redis中是否有该key值
            if (RedisHelper.exists(key)) {
                //取出访问次数
                int times = Integer.parseInt(RedisHelper.get(key));
                //判断访问是否大于最大次数
                if (times >= maxTimes) {
                    return true;
                }
                //若不大于则将访问次数加1
                RedisHelper.incr(key, 1L);
            } else {  //若没有则创建并设置失效时间
                RedisHelper.set(key, "1", days, TimeUnit.DAYS);
            }
        } catch (Exception e) {

            throw new Exception
        }
        return false;
    }        

4.分布式的共享session

当我们的系统做成分布式的时候,我们分布式的服务器将用户的session信息保存在各自的服务器中,那么在做Nginx负载均衡的时候,各个用户的请求都会被负载到各个服务器上,这样就造成这么一个问题,比如我们某些服务是需要用户登录才能使用的,一般我们会在用户进行操作的时候用一个拦截器去拦截用户的请求,然后再查看服务器中的Session中有没有用户的信息,如果有就放行。没有就跳转到登录界面提示登录,也就是一个简单的横向越权的问题。在分布式的系统中就比较头疼了,比如我们系统中有三台服务器做负载均衡,服务器A,服务器B,服务器C。

第一次请求被Nginx转发到了服务器A,用户登录之后,操作请求又被分发到了服务器B,这时B服务器没有用户的Session数据,又提示用户需要登录就造成了非常不友好的用户体验,我想到的是两种解决方案,一种是按用户的ip来进行计算,对应的ip经过算法的处理,固定请求某一固定的服务器。还有一种就是用Redis将用户的Session信息进行集中的管理,每次用户登录信息都从Redis中集中获取,也就很好的解决了这一问题


版权声明:本文为nuomizhende45原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。