美文网首页
2.【Redis系列】Redis基础数据结构

2.【Redis系列】Redis基础数据结构

作者: 773eeb0e0c48 | 来源:发表于2019-03-08 22:20 被阅读0次

    千里之行始于足下,我们先来看看redis的基础知识。

    Redis有5中基本数据类型:字符串(string)、列表(list)、集合(set)、有序集合(zset)、字典(hash)。熟练掌握这5种基本数据结构也是最基本最重要的部分。

    String(字符串)

    字符串是redis中最简单的数据结构,Redis所有的数据结构都是以唯一key作为名称,然后通过唯一的key来获取相应的redis数据。不同类型的数据结构的差异就在于value的结构不一样。

    字符串使用非常广泛,最常用的就是缓存用户信息,通常我们将用户信息使用JSON序列化成字符串,然后将序列化后的字符串塞进redis中,同样,取用户信息的时候再进行一次反序列化的过程。

    Redis的字符串是动态字符串,内部结构类似java的ArrayList。采用与分配空间的方式肩上内存的频繁分配。内部为当前字符串实际分配的空间capacity,当字符串小于1M时,扩容都是加倍现有的空间,当超过1M时,扩容只会多扩1M的空间,需要注意的是字符串的最大空间是512M。

    键值对
    >set name QQsir
    ok
    >get name
    "QQsir"
    >exists name
    (integer) 1
    >del name
    (integer) 1
    >get name
    (nil)
    
    批量键值对
    >mset name1 QQ name2 wx 
    >mget name1 name2
    1)"QQ"
    2)"wx"
    
    过期和set命令扩展
    >set name QQsir
    >get name
    "QQsir"
    >expire name 5 #5秒后过期
    ...wait 5s
    >get name
    (nil)
    
    计数

    如果value是整数,可以对它自增操作

    >set age 30
    ok
    >incr age
    (integer)31
    >incrby age 5
    (integer)36
    >incrby age -5
    (integer)31
    

    list(列表)

    Redis列表相当于java语言里面的linkedlist,注意它是链表而不是数组。意味着list的插入和删除非常的快,时间复杂度O(1) ,但是索引定位很慢,时间复杂度O(n).

    当列表弹出最后一个元素之后,该数据结果自动被删除,内存回收。

    Redis的列表结构可以用来做异步队列,将延后处理的任务结构体序列成字符串放到Redis的列表中。另一个线程从这个列表中轮训获取数据进行处理。

    左边进左边出
    > rpush books python java golang
    (integer) 3
    > llen books
    (integer) 3
    > lpop books
    "python"
    > lpop books
    "java"
    > lpop books
    "golang"
    > lpop books
    (nil)
    
    右边进右边出:栈
    > rpush books python java golang
    (integer) 3
    > rpop books
    "golang"
    > rpop books
    "java"
    > rpop books
    "python"
    > rpop books
    (nil)
    
    快速列表
    ziplist.png

    如果再深入一些,list列表的底层是一个快速列表quicklist的数据结构。
    当存储元素较少的时候,会分配一块连续的内存,这个结构是压缩列表ziplist,当元素过多,就需要使用quicklist,因为普通的链表使用空间太大,增加内存的碎片化,比如存储一个int类型,还需要两个指针,增加内存占用空间。所以使用链表和ziplist结合的方式,使用双箭头将ziplist链接起来,这样即满足快速插入和删除,又能不占用过多的空间。

    hash(字典)

    Redis字典相当于java里面的hashmap,它是无序字典,内部结构上同hashmap一样,使用数组加链表的方式,第一维hash的数组发生碰撞,就会将碰撞的元素使用链表串联起来。


    hash.png

    不同的是redis存储的只能是字符串,另外他们的rehash的方式不一样,java的hashmap是一次性全部rehash,在元素很多时,是很耗时的操作,redis为了不堵塞服务,提高性能,采用的是渐进式rehash策略。

    redis在rehash时会保留新旧两个hash结构,在查询时会从两个结构中查询,后续一点点的将旧hash的内容迁移到新hash上,当最后一个元素迁移完成,替代旧hash,内存被回收。

    hash 结构也可以用来存储用户信息,不同于字符串一次性需要全部序列化整个对象,hash 可以对用户结构中的每个字段单独存储。这样当我们需要获取用户信息时可以进行部分获取。而以整个字符串的形式去保存用户信息的话就只能一次性全部读取,这样就会比较浪费网络流量。

    set(集合)

    Redis的集合相当于java语言中的hashSet,内部的键值对是无序的唯一的,它的内部实现相当于一个特殊的字典,字典中的所有value都是null。

    set集合可以用来存储中将用户,这样就确保不会重复。

    zset(有序集合)

    有序集合是最有特色的数据结构,类似于java的sortedSet和hashmap的结合体。一方面是一个set保证内部value的唯一性,另一方面对每个值赋予一个score,代表这个值的权重排序。内部使用的是一种叫做跳跃列表的数据结构。

    zset的最后一个元素被移除后,数据结构自动删除,内存被回收。

    以上是Redis的基本数据结构类型,后面给大家分享一下redis的高级用法。

    相关文章

      网友评论

          本文标题:2.【Redis系列】Redis基础数据结构

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