Redis String存储结构

作者: 8033b4d1f3ec | 来源:发表于2018-06-19 22:19 被阅读14次

    Redis是一个非常优秀的key-value存储系统,我自己非常喜欢用redis做内存存储。redis本身提供了非常多的数据结构存储,能够满足很多业务的存储场景,今天先从日常使用最多的String结构入手谈谈,记录下我自己平时的使用场景。

    String大概是工作中使用最多的场景了,String的内部存储默认是字符串。我在工作中最常使用的场景莫过于把结果集序列化成json,然后利用string的set命令存储了。这种存储方式最常见,也最省事,是偷懒型程序员的最爱。例如持久化的用户榜单信息,我就喜欢将整个榜单序列化成json,然后存入redis。

          public List<RankInfo> getRankList(){
            String json = redis.string.get(“key”);
            if(!StringUtiils.isEmpty(json)){
                return new Gson().fromjson(json,new     
                                      TypeToken<List<User>>() {});
            } else {
                List<RankInfo> list = db.getData();
                if(!CollectionUtils.isEmpty(list)) {
                    redis.string.set(“key”,new Gson().toJson(list));
                    redis.expire(“key”,5000);
                }
                return list;
            }
          }
    

    上面这段代码可是我最喜欢的代码片段,简单,快速,又可以偷懒。当然用string存储也是有缺点的,那就是会浪费内存,因为string存储的key是散落在各个角落的,每个存储的key的大小不确定,这样可能会造成内存碎片,造成不必要的内存浪费。所以如果存储的内存块非常大,我们是需要考虑存储结构的优化的,这个后期再讲。

    自增(INCRBY)自减(DECRBY)操作也是string结构的常用命令。incrby命令的常用业务场景就是可以用来判断用户的某些行为验证。比如某个业务场景有这样一种规则:每个用户一小时内只能投票两次,这时候incrby命令就非常有用。

        public void vote(int userId){
            String key = “vote”+userId;
            redis.string.incrby(key,1);
            long ttl = redis.ttl;
            if(ttl==-1 | ttl ==-2){
                redis.expire(key,3600);
            }
        }
    
        public  int getUserVoteCount(int userId){
            String key = “vote” + userId;
            String value = redis.string.get(key);
            if(value!=null){
                return Integer.parseInt(value);
            } else {
                return 0;
            }
        }
    

    以上我们通过incrby命令就可以非常简单的完成了用户投票的场景。此外incry还可以用来解决集群情况下分布式锁的业务场景,这个放在后期的mutex设计中来讲。

    String存储结构的过期时间。过期时间其实非常好理解,只是其中有个地方需要特别注意下,这个问题之前可是让我栽了大坑。一个string类型的key,当你第一次设置了过期时间之后,如果第二次重新做了set操作,那么这个key的过期时间已经不存在了,什么意思呢?可以看以下这段代码:

        public void test(){
                redis.string.set(“key”,”1”);
                redis.expire(“key”,2000);
                //这一步将key的value设置为2的时候,key的过期时间已经不存在了
                redis.string.set(“key”,”2”);
        }
    

    如果有业务场景需要保留过期时间的,那么需要重新设置过期时间,可以利用ttl命令计算出key的剩余时间,再将ttl取得的剩余时间重新设置为key的过期时间。此外对key的修改操作,比如:incrby,rename等操作不会使得过期时间失效。hash存储结构的hset命令不会出现string过期时间消失的情况,因为hset命令针对的是field操作,并不是对整个key进行重写操作。具体文档可以看这里

    string作为redis的基础数据结构,我平时用的最多的就是以上几种场景,平时只需要知道string的场景和注意的要点就可以了。

    相关文章

      网友评论

        本文标题:Redis String存储结构

        本文链接:https://www.haomeiwen.com/subject/jrizeftx.html