zoukankan      html  css  js  c++  java
  • Redis字符串详解

    Redis字符串详解

    redis虽然是使用c语言实现的,但是它并没有直接使用c语言提供的字符串,char[]和char*。而是自己实现的动态字符串类型(simple dynamic string),简称(sds)

    struct sdshdr{
        int len;	// 空间总长度
        int free;	// 剩余空间长度
        char[] buf;	// 字符数组
    }
    

    sds和c语言字符串的相同点:

    1. sds字符串末尾也会以''结束,len不会将''计算在长度之内,
    2. 都是使用了char[]存储字符串

    sds和c语言字符串区别:

    1. sds可以直接通过len获取到字符串长度,时间复杂度为O(1),c语言需要通过便利字符数组,时间复杂度为O(n)
    2. sds在添加字符串是会自动判断free是否足够,如果不够自动扩容,c语言添加字符串需要自己手动开辟内存空间,如果目标字符串空间不满足添加后的字符串长度,那么会导致缓冲区溢出

    使用sds的优势:

    1. sds会降低空间分配次数,提高内存使用率
    2. 空间预分配:sds自动扩容后,会进行空间预分配,如果len < 1M,则会分配与len相同的空间给free,如果len >= 1M,则会分配1M给free
    3. 惰性空间回收:sds删除自己某一部分字符串时,不会立即回收这一块的空间,而是在下一次空间不够时再进行回收

    Redis中的字符串有三种编码: rawembstr int

    embstr:短字符串和浮点数,int是整数字符串,raw是可变且任意长度字符串

    通过OBJECT ENCODING <key>即可查看字符串编码

    命令详解

    • SET:设置一个字符串,SET <key> <value> [EX 过期时间(s)] [PX 过期时间(ms)] [NX(不存在时设置)|XX(存在时设置)]EXPX不能同时设置

      SET a abc		// 不设置过期时间和条件
      SET a abc EX 5	        // 5秒钟过期
      SET a abc PX 5000	// 5000毫秒过期
      SET a abc NX		// 不存在时设置
      SET a abc XX		// 存在时设置
      
    • SETNX:当key不存在时设置,SET <key> <value>,相当于SET <key> <value> NX

    • SETEX:设置key过期时间并设置新值,SETEX <key> <过期时间(s)> <value>,相当于SET <key> <value> <EX 过期时间(s)>

    • PSETEX:命令和SETEX一样,只不过时间单位是毫秒

    • GET:获取字符串值,GET <key>

      SET a abc
      GET a	// abc
      
    • GETSET:获取并设置新值,GETSET <key> <value>

      SET a abc
      GETSET a def	// abc
      GET a		// def
      
    • STRLEN:获取字符串长度,STRLEN <key>

      SET a abc
      STRLEN a	// 3
      
    • APPEND:添加字符串到当前key指向的字符串末尾,APPEND <key> <value>

      SET a abc
      APPEND a " edf"
      GET a	// abc edf
      
    • SETRANGE:从指定位置开始修改原来字符串的值,字符串下标从0开始,SETRANGE <key> <offset> <replaceValue>

      SET a abc
      SETRANGE a 0 00
      GET a	// 00c
      
    • GETRANGE:返回指定范围的字符串,-1代表字符串最后位置,GETRANGE <key> <start> <end>

      SET a abc
      GETRANGE a 0 -1	// abc
      
    • INCR:让int编码字符串自增1,INCR <key>

      SET a 1
      INCR a
      GET a	// 2
      
    • INCRBY:让int编码字符串加上指定数值,INCRBY <key> <addValue>

      SET a 1
      INCRBY a 2
      GET a	// 3
      
    • INCRBYFLOAT:让浮点数加上指定数值,如果对int编码使用,会被转换成embstr编码,INCRBYFLOAT <key> <addValue>

      SET a 1
      OBJECT ENCODING a	// int 
      INCRBYFLOAT a 3.8
      OBJECT ENCODING a	// embstr
      GET a	// 4.8
      
    • DECR:int编码字符串自减,DECR <key>

      SET a 2
      DECR a
      GET a	// 1
      
    • DECRBY:int编码减去指定值,和INCRBY用法一样

    • MSET:一次性设置多个字符串,MSET <key> <value> [key value ..]

      MSET a a1 b b1 c c1
      
    • MGET:一次性获取多个字符串,MGET <key> [key ..]

      MGET a b c	// a1 b1 c1
      
    • MSETNX:设置多个字符串,如果有一个key已存在,则拒绝设置所有字符串,MSETNX <key> <value> [key value ..]

      SET a a1
      MSETNX b b1 c c1		// ok
      KEYS *					// a b c
      
      DEL b c
      MSETNX a a1 b b1 c c1	// fail
      KEYS *					// a
      

    embstr、int、raw的转换机制

    • APPEND命令会把int和embstr编码转成raw
    • embstr编码的字符串在长度大于44时会被转换成raw编码
    • INCRBYFLOAT命令会将整数类型转成浮点型(embstr编码)
  • 相关阅读:
    多线程008如何预防死锁
    多线程003volatile的可见性和禁止指令重排序怎么实现的
    多线程011线程池运行原理及复用原理
    多线程010为什么要使用线程池
    多线程009什么是守护线程
    多线程005创建线程有哪些方式
    多线程007描述一下线程安全活跃态问题,以及竞态条件
    多线程002ThreadLocal有哪些内存泄露问题,如何避免
    关于Tomcat的启动时机(精通Eclipse Web开发P40)
    乱侃~~~
  • 原文地址:https://www.cnblogs.com/dagger9527/p/12980205.html
Copyright © 2011-2022 走看看