美文网首页
Redis API的使用和理解之数据结构和内部编码

Redis API的使用和理解之数据结构和内部编码

作者: Change_6556 | 来源:发表于2019-10-20 10:56 被阅读0次
    image.png

    1.String字符串

    所有的key都是字符串 value有5中类型
    位图也是 json xml 也是 字符串
    本质上 都是二进制key value 一般 在100K以内 字符串value 不能大于512M

    使用场景

    1.缓存

    2.分布式锁

    3.计数器

    4.等等

    get key
    获取 key 对应的value O(1)
    set key value
    设置 key-value O(1)
    del key1 key2
    删除 key1 key2 及其value
    incr
    key 自增1 如果key不存在 自增后get(key) =1
    decr
    key 自增1 如果key不存在 自减后get(key) =1
    incrby key k
    key 自增k 如果key不存在 自增后get(key) = k
    decrby key k
    key 自减k 如果key不存在 自减后get(key) =k

    image.png

    实战 记录网站每个用户个人主页的访问量

    incr userid:pageview (单线程:无竞争)

    实战 缓存视频的基本信息(数据源在Mysql中)伪代码

    视频vid 先在redis中找 找到直接返回,没找到请求mysql 然后写入redis,下次直接使用缓存

        public VideoInfo get (long id){
            String redis Key = redisPrefix + id;
            VideoInfo videoInfo = redis.get(redisKey);
            if(videoInfo == null){
                videoInfo = mysq.get(id);
                if(videoInfo != null){
                    //序列化
                     redis.set(redisKey,serialize(videoInfo));  
                }
            }
            return videoInfo;
        }
    

    实战分布式id生成器

    原理 incr id 生成器

    set setnx setxx的区别

    1. set key value O(1)
      不管key是否存在,都设置
    2. setnx key value
      key不存在 才设置 O(1) 只做新增操作
    3. set key value xx
      key存在 才设置 O(1) 只做更新操作
      set setnx set xx的区别.png

    批量操作

    1. mget O(n)
      多次get 要反复传输命令 返回结果
      n次get = n次网络时间 + n次命令时间
      mget
      1次mget = 1次网络时间 + n次命令时间
    2. mset O(n)

    getset append strlen

    1. getset key newvalue
      set key newvalue 并返回旧的 value
    2. append key value
      将value 追加到旧的value,相当与字符串拼接
    3. strlen key
      返回字符串长度(注意中文) 一个中文字符长度为2 占两个字节


      image.png

    incrbyfloat getrange setrange 浮点数自增操作

    1. incrbyfloat key 3.5 O(1) 目前只有keys 和批量操作 为O(n)
      增加 key对应的值3.5
    2. getrange key start end
      获取字符串指定下标所有的值
    3. setrange key index value
      设置指定下表所有对应的值


      image.png

    2.哈希Hash

    Key field value
    一个key 对应一个value,value 为一个 key value对象

    特点

    Mapmap?
    Small redis
    key 不能相同,field不能相同, value 可以相同

    示例

    个人信息表
    user1 email 1420901244@qq.com
    name 张小涵

    hget hset hdel

    1. hget key field
      获取hash key 对应field 的value
    2. hset key field value
      设置hash key 对应 field 的value
    3. hdel key field
      删除 hash key 对应 field 的value


      image.png
      image.png

      可以直接 del 这个key hash 直接被删除 也可以 同时删除多个field

    hexists hlen

    1.hexists key field
    判断hash key 是否有field
    2.hlen key
    获取hash key field 的数量


    image.png

    所有集合类型的key 操作 相同 区别在于value的操作
    3.hmget hmset 批量操作
    hmget key field1 field2...fieldN O(n)
    批量获取hash key 的一批field对应的值
    hmset key field value1 field2 value2 ..fieldN valueN
    批量设置hash key的一批field value


    image.png

    实战

    1.记录网站每个用户个人主页的访问量
    hincrby user:1:info pageview count 这个只增加 主页访问量一个field
    2.缓存视频的基本信息(数据源在MySQL中)伪代码

        public VideoInfo get (long id){
            String redisKey = redisPrefix + id;
            Map<String,String> hashMap =  redis.hgetAll(redisKey);
            VideoInfo videoInfo = transferMapToVideo.(hashMap);
            if(videoInfo == null){
                videoInfo = mysq.get(id);
                if(videoInfo != null){
                    //序列化
                     redis.hmset(redisKey,transferVideoToMap(videoInfo));  
                }
            }
            return videoInfo;
        }
    

    hegetall hvals hkeys

    1.hgetall key O(n)
    返回 hash key对应所有的field和value
    2.hvals key O(n)
    返回hash key 对应所有field 的value
    3.hkeys key O(n)
    返回hash key 对应所有field


    image.png

    用户信息

    1.String实现1
    key value
    user:1 serializable:json, xml value封装为一个对象 更改要换整个json
    set user:1 serialize(userinfo)
    优点编程简单 可能节约内存 缺点 序列化开销 设置属性要操作整个数据
    2.String实现2
    key value
    user:1 name world
    user:1 age 40
    user:1 pageView 50000
    不是一个整理不便于管理
    优点 直观 可以部分更新 缺点 内存占用较大 key较为分散
    3.hash实现
    key field value
    name world
    user:1:info age 40
    pageview 5000000
    优点 直观 节省空间 可以部分更新 缺点 编程稍微复杂,ttl不好控制(过期时间只能针对可以 不能设置field过期时间)

    hsetnx hincrby hincrbyfloat

    1. hsetnx key field value
      设置hashkey对应的field 的value(如果field已经存在,则失败)
    2. hincrby key field intCounter
      hash key 对应的field的value 自增intCounter
    3. hincrbyfloat key field floadCounter
      hincrby浮点数版

    List 列表

    rpush lpush

    rpush key vlaue1 value2...valueN
    从列表右端插入值
    lpush key vlaue1 value2...valueN
    从列表左端插入值

    linsert

    linser key before|after value newValue

    lpop rpop

    lpop
    从列表左边弹出一个item
    rpop
    从列表右6边弹出一个item

    irem

    lrem key count value O(n)
    根据count值删除所有与value相等的项
    count>0从左到右,最多删除count个与value相等的项
    count<0从右到左,最多删除count个与value相等的项
    count=0从,删除所有value相等的项

    ltrim

    ltrim key start end O(n)
    按照所有范围修剪列表
    ltrim listkey 0 2

    lrange

    lrange key start end
    获取列表指定索引范围所有item

    lindex

    lindex key index O(n)
    lindex listkey 0 第一个元素
    lindex listkey -1 最后一个元素

    llen

    llen key O(1)
    获取列表长度

    lset

    lset key index newValue
    设置列表指定索引值为newValue
    lset listkey 2 java 第三个元素


    image.png

    应用 微博 TimeLine 时间轴

    新微博 ->微博1->微博2

    blpop brpop

    blpop key timeout
    lpop 阻塞版本 timeout=0为永远不阻塞

    TIPS

    1. LPUSH + LPOP = Stack
    2. LPUSH + RPOP = Queue
    3. LPUSH + LTRIM = Capped Collection 固定数量的列表
    4. LPUSH + BRPOP = Message Queue 左push + 右阻塞pop 实现 消息队列

    集合Set

    key values
    集合间的操作
    共同关注 交集
    sinnter 交集
    sdiff 不同
    sunion 并集

    特点

    1. 无序
    2. 无重复
    3. 集合间操作

    集合内API s开头

    sadd key element O(1)
    向集合key添加element(如果element已经存在,添加失败)
    srem key element
    将集合key中的element 移除掉

    scard

    scard user:1:follow 计算集合大小
    sismenber user:1:follow 判断it是否存在在集合中
    srandmember user:1:follow 4 从集合中随机挑count个元素 不会破坏集合
    spop user:1:follow 从集合中随机弹出一个元素

    image.png

    实战抽奖系统

    spop 随机弹出元素

    实战Like 赞 踩

    实战 标签tag

    1. 给用户添加标签
    2. 给标签添加用户

    集合间的API

    sdiff user:1:follow user:2:follow 差集
    sinter user:1:follow user:2:follow 交集
    sunion user:1:follow user:2:follow 并集
    sdiff|sinter|suion + store destkey 将差集交集并集结果保存到destkey中

    实战 共同关注

    有序集合 ZSet SortedSet

    key score value

    API

    zdd

    zdd key score element (可以是多对 score能重复 element不能重复) O(logN)
    添加score和element

    zrem

    zrem key element 可以是多个 O(1)
    删除元素

    zscore

    zscore key element
    返回元素的分数

    zincrby

    zincrby key increScore elemetmet O(1)
    增加或减少元素的分数

    zcard

    zcard key O(1)
    返回元素的个数


    image.png

    zrange

    zrange key start end [withscores] (是否打印分数 升序打印)
    O(logn +m)n为元素个数 m为范围内元素个数
    返回指定索引范围内的升序元素

    zrangebyscore

    zrangebyscore key minScore maxScore[withcores](是否打印分数 升序打印)
    O(logn +m)n为元素个数 m为范围内元素个数
    返回指定分数范围内的升序元素

    zcount

    zcount key minscore maxscore
    O(logn +m)n为元素个数 m为范围内元素个数
    返回有序集合内指定分数范围内的个数

    zremrangebyrank

    zremrangebyrank key start end
    删除指定排名内的元素

    zremrangebyscore

    zremrangebyrank key start end
    删除指定分数内的元素

    实战 排行榜

    1. 新书榜 热度榜
      zrevrank 从高到低 排名
      zrevrange 从高到低 排名范围
      zrevrangebyscore 从高到低 根据分数
      zinterstore 交集
      zunionstore 并集

    相关文章

      网友评论

          本文标题:Redis API的使用和理解之数据结构和内部编码

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